diff --git a/demo/webgl/GLUtils.pas b/demo/webgl/GLUtils.pas index 855093e..8b72415 100644 --- a/demo/webgl/GLUtils.pas +++ b/demo/webgl/GLUtils.pas @@ -1,463 +1,463 @@ unit GLUtils; interface uses - MemoryBuffer, Mat4, GLTypes, - BrowserConsole, WebGL, JS, - Types, SysUtils; + MemoryBuffer, Mat4, GLTypes, + BrowserConsole, WebGL, JS, + Types, SysUtils; type - TShader = class - public - constructor Create (context: TJSWebGLRenderingContext; vertexShaderSource, fragmentShaderSource: string); - procedure Compile; - procedure Link; - procedure Use; + TShader = class + public + constructor Create (context: TJSWebGLRenderingContext; vertexShaderSource, fragmentShaderSource: string); + procedure Compile; + procedure Link; + procedure Use; - function GetAttribLocation (name: string): GLint; - procedure BindAttribLocation (index: GLuint; name: string); + function GetAttribLocation (name: string): GLint; + procedure BindAttribLocation (index: GLuint; name: string); - procedure SetUniformMat4 (name: string; value: TMat4); - procedure SetUniformVec3 (name: string; value: TVec3); - procedure SetUniformFloat (name: string; value: GLfloat); + procedure SetUniformMat4 (name: string; value: TMat4); + procedure SetUniformVec3 (name: string; value: TVec3); + procedure SetUniformFloat (name: string; value: GLfloat); - private - gl: TJSWebGLRenderingContext; - vertexShader: TJSWebGLShader; - fragmentShader: TJSWebGLShader; - programID: TJSWebGLProgram; + private + gl: TJSWebGLRenderingContext; + vertexShader: TJSWebGLShader; + fragmentShader: TJSWebGLShader; + programID: TJSWebGLProgram; - function GetUniformLocation (name: string): TJSWebGLUniformLocation; - function CreateShader (theType: GLenum; source: string): TJSWebGLShader; - end; + function GetUniformLocation (name: string): TJSWebGLUniformLocation; + function CreateShader (theType: GLenum; source: string): TJSWebGLShader; + end; type - TModelData = record - verticies: TJSFloat32Array; // GLfloat + TModelData = record + verticies: TJSFloat32Array; // GLfloat - // NOTE: it's not clear if WebGL supports GLuint - // https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements + // NOTE: it's not clear if WebGL supports GLuint + // https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements - indicies: TJSUint16Array; // GLushort - floatsPerVertex: integer; - end; + indicies: TJSUint16Array; // GLushort + floatsPerVertex: integer; + end; const - kModelVertexFloats = 3 + 2 + 3; + kModelVertexFloats = 3 + 2 + 3; type - TModelVertex = record - pos: TVec3; - texCoord: TVec2; - normal: TVec3; - end; + TModelVertex = record + pos: TVec3; + texCoord: TVec2; + normal: TVec3; + end; procedure ModelVertexAddToBuffer(vertex: TModelVertex; buffer: TMemoryBuffer); -procedure ModelVertexAddToArray (vertex: TModelVertex; list: TJSArray); +procedure ModelVertexAddToArray (vertex: TModelVertex; list: TJSArray); type - TModel = class - public - constructor Create(context: TJSWebGLRenderingContext; modelData: TModelData); overload; - procedure Draw; - private - gl: TJSWebGLRenderingContext; - data: TModelData; - vertexBuffer: TJSWebGLBuffer; - indexBuffer: TJSWebGLBuffer; - //elementCount: integer; + TModel = class + public + constructor Create(context: TJSWebGLRenderingContext; modelData: TModelData); overload; + procedure Draw; + private + gl: TJSWebGLRenderingContext; + data: TModelData; + vertexBuffer: TJSWebGLBuffer; + indexBuffer: TJSWebGLBuffer; + //elementCount: integer; - procedure EnableAttributes; - procedure Load; - end; + procedure EnableAttributes; + procedure Load; + end; function LoadOBJFile (text: TJSString): TModelData; -function GLSizeof(glType: NativeInt): integer; -procedure GLFatal (gl: TJSWebGLRenderingContext; messageString: string = 'Fatal OpenGL error'); +function GLSizeof(glType: NativeInt): integer; +procedure GLFatal (gl: TJSWebGLRenderingContext; messageString: string = 'Fatal OpenGL error'); implementation {=============================================} -{@! ___Utilities___ } +{@! ___Utilities___ } {=============================================} procedure Fatal (messageString: string); overload; begin - writeln('*** FATAL: ', messageString); - raise Exception.Create('FATAL'); + writeln('*** FATAL: ', messageString); + raise Exception.Create('FATAL'); end; // TODO: toll free bridge to FPC strings {procedure Fatal (messageString: TJSString); overload; begin - writeln('*** FATAL: ', messageString); - raise Exception.Create('FATAL'); + writeln('*** FATAL: ', messageString); + raise Exception.Create('FATAL'); end;} -procedure GLFatal (gl: TJSWebGLRenderingContext; messageString: string = 'Fatal OpenGL error'); +procedure GLFatal (gl: TJSWebGLRenderingContext; messageString: string = 'Fatal OpenGL error'); var - error: integer; + error: integer; begin - error := gl.getError(); - if error <> TJSWebGLRenderingContext.NO_ERROR then - begin - // TODO: case doesn't work? - case error of - TJSWebGLRenderingContext.INVALID_VALUE: - messageString := messageString+' (GL_INVALID_VALUE)'; - TJSWebGLRenderingContext.INVALID_OPERATION: - messageString := messageString+' (GL_INVALID_OPERATION)'; - TJSWebGLRenderingContext.INVALID_ENUM: - messageString := messageString+' (GL_INVALID_ENUM)'; - otherwise - messageString := messageString+' '+IntToStr(error); - end; - Fatal(messageString); - end; + error := gl.getError(); + if error <> TJSWebGLRenderingContext.NO_ERROR then + begin + // TODO: case doesn't work? + case error of + TJSWebGLRenderingContext.INVALID_VALUE: + messageString := messageString+' (GL_INVALID_VALUE)'; + TJSWebGLRenderingContext.INVALID_OPERATION: + messageString := messageString+' (GL_INVALID_OPERATION)'; + TJSWebGLRenderingContext.INVALID_ENUM: + messageString := messageString+' (GL_INVALID_ENUM)'; + otherwise + messageString := messageString+' '+IntToStr(error); + end; + Fatal(messageString); + end; end; -function GLSizeof(glType: NativeInt): integer; +function GLSizeof(glType: NativeInt): integer; begin - case glType of - TJSWebGLRenderingContext.UNSIGNED_BYTE, TJSWebGLRenderingContext.BYTE: - result := 1; - TJSWebGLRenderingContext.SHORT, TJSWebGLRenderingContext.UNSIGNED_SHORT: - result := 2; - TJSWebGLRenderingContext.INT, TJSWebGLRenderingContext.UNSIGNED_INT: - result := 4; - TJSWebGLRenderingContext.FLOAT: - result := 4; - otherwise - Fatal('GLSizeof type is invalid.'); - end; + case glType of + TJSWebGLRenderingContext.UNSIGNED_BYTE, TJSWebGLRenderingContext.BYTE: + result := 1; + TJSWebGLRenderingContext.SHORT, TJSWebGLRenderingContext.UNSIGNED_SHORT: + result := 2; + TJSWebGLRenderingContext.INT, TJSWebGLRenderingContext.UNSIGNED_INT: + result := 4; + TJSWebGLRenderingContext.FLOAT: + result := 4; + otherwise + Fatal('GLSizeof type is invalid.'); + end; end; {=============================================} -{@! ___Model___ } +{@! ___Model___ } {=============================================} procedure ModelVertexAddToBuffer(vertex: TModelVertex; buffer: TMemoryBuffer); begin - buffer.AddFloats(kModelVertexFloats, [ - vertex.pos.x, vertex.pos.y, vertex.pos.z, - vertex.texCoord.x, vertex.texCoord.y, - vertex.normal.x, vertex.normal.y, vertex.normal.z - ]); + buffer.AddFloats(kModelVertexFloats, [ + vertex.pos.x, vertex.pos.y, vertex.pos.z, + vertex.texCoord.x, vertex.texCoord.y, + vertex.normal.x, vertex.normal.y, vertex.normal.z + ]); end; -procedure ModelVertexAddToArray (vertex: TModelVertex; list: TJSArray); +procedure ModelVertexAddToArray (vertex: TModelVertex; list: TJSArray); begin - list.push(vertex.pos.x); - list.push(vertex.pos.y); - list.push(vertex.pos.z); - list.push(vertex.texCoord.x); - list.push(vertex.texCoord.y); - list.push(vertex.normal.x); - list.push(vertex.normal.y); - list.push(vertex.normal.z); + list.push(vertex.pos.x); + list.push(vertex.pos.y); + list.push(vertex.pos.z); + list.push(vertex.texCoord.x); + list.push(vertex.texCoord.y); + list.push(vertex.normal.x); + list.push(vertex.normal.y); + list.push(vertex.normal.z); end; constructor TModel.Create(context: TJSWebGLRenderingContext; modelData: TModelData); begin - gl := context; - data := modelData; - Load; + gl := context; + data := modelData; + Load; end; procedure TModel.Draw; begin - gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); + gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); - EnableAttributes; - gl.drawElements(gl.TRIANGLES, data.indicies.length, gl.UNSIGNED_SHORT, 0); + EnableAttributes; + gl.drawElements(gl.TRIANGLES, data.indicies.length, gl.UNSIGNED_SHORT, 0); - gl.bindBuffer(gl.ARRAY_BUFFER, nil); - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, nil); + gl.bindBuffer(gl.ARRAY_BUFFER, nil); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, nil); end; procedure TModel.EnableAttributes; var - offset: integer; - stride: integer; + offset: integer; + stride: integer; begin - // NOTE: we don't have VAO's yet so we need to enable vertex attributes for shader - // before every draw call (unless the array buffer hasn't changed between calls) - offset := 0; - stride := data.floatsPerVertex * GLSizeof(TJSWebGLRenderingContext.FLOAT); + // NOTE: we don't have VAO's yet so we need to enable vertex attributes for shader + // before every draw call (unless the array buffer hasn't changed between calls) + offset := 0; + stride := data.floatsPerVertex * GLSizeof(TJSWebGLRenderingContext.FLOAT); - // position - gl.enableVertexAttribArray(0); - gl.vertexAttribPointer(0, 3, gl.FLOAT, false, stride, offset); - offset += GLSizeof(TJSWebGLRenderingContext.FLOAT) * 3; + // position + gl.enableVertexAttribArray(0); + gl.vertexAttribPointer(0, 3, gl.FLOAT, false, stride, offset); + offset += GLSizeof(TJSWebGLRenderingContext.FLOAT) * 3; - // texture - gl.enableVertexAttribArray(1); - gl.vertexAttribPointer(1, 2, gl.FLOAT, false, stride, offset); - offset += GLSizeof(TJSWebGLRenderingContext.FLOAT) * 2; + // texture + gl.enableVertexAttribArray(1); + gl.vertexAttribPointer(1, 2, gl.FLOAT, false, stride, offset); + offset += GLSizeof(TJSWebGLRenderingContext.FLOAT) * 2; - // normal - gl.enableVertexAttribArray(2); - gl.vertexAttribPointer(2, 3, gl.FLOAT, false, stride, offset); - offset += GLSizeof(TJSWebGLRenderingContext.FLOAT) * 3; + // normal + gl.enableVertexAttribArray(2); + gl.vertexAttribPointer(2, 3, gl.FLOAT, false, stride, offset); + offset += GLSizeof(TJSWebGLRenderingContext.FLOAT) * 3; end; procedure TModel.Load; begin - indexBuffer := gl.createBuffer; - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, data.indicies, gl.STATIC_DRAW); - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, nil); + indexBuffer := gl.createBuffer; + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, data.indicies, gl.STATIC_DRAW); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, nil); - vertexBuffer := gl.createBuffer; - gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); + vertexBuffer := gl.createBuffer; + gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); gl.bufferData(gl.ARRAY_BUFFER, data.verticies, gl.STATIC_DRAW); - gl.bindBuffer(gl.ARRAY_BUFFER, nil); + gl.bindBuffer(gl.ARRAY_BUFFER, nil); end; type - TOBJVertex = record - position: TVec3; - textureIndex: integer; - normalIndex: integer; - end; + TOBJVertex = record + position: TVec3; + textureIndex: integer; + normalIndex: integer; + end; function ProcessFace (verticies: TJSArray; indices: TJSArray; face: TStringDynArray): TOBJVertex; var - index: integer; - vertex: TOBJVertex; + index: integer; + vertex: TOBJVertex; begin - index := StrToInt(face[0]) - 1; + index := StrToInt(face[0]) - 1; - vertex := TOBJVertex(verticies[index]); + vertex := TOBJVertex(verticies[index]); - // NOTE: see TOBJData - // index can't exceed GLushort - if index > 65536 then - Fatal('overflowed indices array'); + // NOTE: see TOBJData + // index can't exceed GLushort + if index > 65536 then + Fatal('overflowed indices array'); - if face[1] <> '' then - vertex.textureIndex := StrToInt(face[1]) - 1 - else - vertex.textureIndex := -1; + if face[1] <> '' then + vertex.textureIndex := StrToInt(face[1]) - 1 + else + vertex.textureIndex := -1; - if face[2] <> '' then - vertex.normalIndex := StrToInt(face[2]) - 1 - else - vertex.normalIndex := -1; + if face[2] <> '' then + vertex.normalIndex := StrToInt(face[2]) - 1 + else + vertex.normalIndex := -1; - indices.push(index); - - verticies[index] := vertex; + indices.push(index); - result := vertex; + verticies[index] := vertex; + + result := vertex; end; function LoadOBJFile (text: TJSString): TModelData; const - kLineEnding = #10; - kSpace = ' '; // what code is space? + kLineEnding = #10; + kSpace = ' '; // what code is space? var - lines: TStringDynArray; - parts: TStringDynArray; - indices: TJSArray; - positions: TJSArray; - normals: TJSArray; - textures: TJSArray; - verticies: TJSArray; - mesh: TJSFloat32Array; + lines: TStringDynArray; + parts: TStringDynArray; + indices: TJSArray; + positions: TJSArray; + normals: TJSArray; + textures: TJSArray; + verticies: TJSArray; + mesh: TJSFloat32Array; - i: integer; - line: TJSString; - vertex: TOBJVertex; - vertexIndex: integer; - data: TModelData; + i: integer; + line: TJSString; + vertex: TOBJVertex; + vertexIndex: integer; + data: TModelData; - pos: TVec3; - texCoord: TVec2; - normal: TVec3; + pos: TVec3; + texCoord: TVec2; + normal: TVec3; begin - positions := TJSArray.new; - normals := TJSArray.new; - textures := TJSArray.new; - indices := TJSArray.new; - verticies := TJSArray.new; + positions := TJSArray.new; + normals := TJSArray.new; + textures := TJSArray.new; + indices := TJSArray.new; + verticies := TJSArray.new; - lines := text.split(kLineEnding); + lines := text.split(kLineEnding); - for i := 0 to high(lines) do - begin - line := TJSString(lines[i]); - parts := line.split(kSpace); + for i := 0 to high(lines) do + begin + line := TJSString(lines[i]); + parts := line.split(kSpace); - if line.startsWith('v ') then - begin - pos := V3(StrToFloat(parts[1]), StrToFloat(parts[2]), StrToFloat(parts[3])); - positions.push(pos); - - // add new vertex - vertex.position := pos; - vertex.textureIndex := -1; - vertex.normalIndex := -1; - verticies.push(pos); - end - else if line.startsWith('vn ') then - begin - normals.push(V3(StrToFloat(parts[1]), StrToFloat(parts[2]), StrToFloat(parts[3]))); - end - else if line.startsWith('vt ') then - begin - textures.push(V2(StrToFloat(parts[1]), 1 - StrToFloat(parts[2]))); - end - else if line.startsWith('f ') then - begin - ProcessFace(verticies, indices, TJSString(parts[1]).split('/')); - ProcessFace(verticies, indices, TJSString(parts[2]).split('/')); - ProcessFace(verticies, indices, TJSString(parts[3]).split('/')); - end; - end; - - // vec3 (position) + vec2 (texCoord) + vec3 (normal) - data.floatsPerVertex := kModelVertexFloats; + if line.startsWith('v ') then + begin + pos := V3(StrToFloat(parts[1]), StrToFloat(parts[2]), StrToFloat(parts[3])); + positions.push(pos); - mesh := TJSFloat32Array.New(data.floatsPerVertex * verticies.length); + // add new vertex + vertex.position := pos; + vertex.textureIndex := -1; + vertex.normalIndex := -1; + verticies.push(vertex); + end + else if line.startsWith('vn ') then + begin + normals.push(V3(StrToFloat(parts[1]), StrToFloat(parts[2]), StrToFloat(parts[3]))); + end + else if line.startsWith('vt ') then + begin + textures.push(V2(StrToFloat(parts[1]), 1 - StrToFloat(parts[2]))); + end + else if line.startsWith('f ') then + begin + ProcessFace(verticies, indices, TJSString(parts[1]).split('/')); + ProcessFace(verticies, indices, TJSString(parts[2]).split('/')); + ProcessFace(verticies, indices, TJSString(parts[3]).split('/')); + end; + end; - for i := 0 to verticies.length - 1 do - begin - vertex := TOBJVertex(verticies[i]); + // vec3 (position) + vec2 (texCoord) + vec3 (normal) + data.floatsPerVertex := kModelVertexFloats; - vertexIndex := i * data.floatsPerVertex; + mesh := TJSFloat32Array.New(data.floatsPerVertex * verticies.length); - // position - pos := TVec3(positions[i]); - mesh[vertexIndex + 0] := pos.x; - mesh[vertexIndex + 1] := pos.y; - mesh[vertexIndex + 2] := pos.z; + for i := 0 to verticies.length - 1 do + begin + vertex := TOBJVertex(verticies[i]); - // texture - if vertex.textureIndex <> -1 then - begin - texCoord := TVec2(textures[vertex.textureIndex]); - mesh[vertexIndex + 3] := texCoord.x; - mesh[vertexIndex + 4] := texCoord.y; - end - else - begin - mesh[vertexIndex + 3] := 0; - mesh[vertexIndex + 4] := 0; - end; - - // normal - if vertex.normalIndex <> -1 then - begin - normal := TVec3(normals[vertex.normalIndex]); - mesh[vertexIndex + 5] := normal.x; - mesh[vertexIndex + 6] := normal.y; - mesh[vertexIndex + 7] := normal.z; - end; - end; + vertexIndex := i * data.floatsPerVertex; - //writeln('floats: ', mesh.length); - //writeln('positions:', positions.length); - //writeln('indices:', indices.length); + // position + pos := TVec3(positions[i]); + mesh[vertexIndex + 0] := pos.x; + mesh[vertexIndex + 1] := pos.y; + mesh[vertexIndex + 2] := pos.z; - data.verticies := mesh; - data.indicies := TJSUint16Array.New(TJSObject(indices)); + // texture + if vertex.textureIndex <> -1 then + begin + texCoord := TVec2(textures[vertex.textureIndex]); + mesh[vertexIndex + 3] := texCoord.x; + mesh[vertexIndex + 4] := texCoord.y; + end + else + begin + mesh[vertexIndex + 3] := 0; + mesh[vertexIndex + 4] := 0; + end; - result := data; + // normal + if vertex.normalIndex <> -1 then + begin + normal := TVec3(normals[vertex.normalIndex]); + mesh[vertexIndex + 5] := normal.x; + mesh[vertexIndex + 6] := normal.y; + mesh[vertexIndex + 7] := normal.z; + end; + end; + + //writeln('floats: ', mesh.length); + //writeln('positions:', positions.length); + //writeln('indices:', indices.length); + + data.verticies := mesh; + data.indicies := TJSUint16Array.New(TJSObject(indices)); + + result := data; end; {=============================================} -{@! ___Shader___ } +{@! ___Shader___ } {=============================================} function TShader.GetUniformLocation (name: string): TJSWebGLUniformLocation; begin - // TODO: cache these. how do we use dictionarys from JS in Pascal? - result := gl.getUniformLocation(programID, name); - GLFatal(gl, 'gl.getUniformLocation'); + // TODO: cache these. how do we use dictionarys from JS in Pascal? + result := gl.getUniformLocation(programID, name); + GLFatal(gl, 'gl.getUniformLocation'); end; procedure TShader.SetUniformFloat (name: string; value: GLfloat); begin - gl.uniform1f(GetUniformLocation(name), value); - GLFatal(gl, 'gl.uniform1f'); + gl.uniform1f(GetUniformLocation(name), value); + GLFatal(gl, 'gl.uniform1f'); end; procedure TShader.SetUniformVec3 (name: string; value: TVec3); begin - //gl.uniform3fv(GetUniformLocation(name), ToFloats(value)); - gl.uniform3f(GetUniformLocation(name), value.x, value.y, value.z); - GLFatal(gl, 'gl.uniform3fv'); + //gl.uniform3fv(GetUniformLocation(name), ToFloats(value)); + gl.uniform3f(GetUniformLocation(name), value.x, value.y, value.z); + GLFatal(gl, 'gl.uniform3fv'); end; procedure TShader.SetUniformMat4 (name: string; value: TMat4); var - list: TJSFloat32List; + list: TJSFloat32List; begin - // TODO: fix mat4 to use flat arrays - list := TJSFloat32List(value.CopyList); - gl.uniformMatrix4fv(GetUniformLocation(name), false, list); - GLFatal(gl, 'gl.uniformMatrix4fv'); + // TODO: fix mat4 to use flat arrays + list := TJSFloat32List(value.CopyList); + gl.uniformMatrix4fv(GetUniformLocation(name), false, list); + GLFatal(gl, 'gl.uniformMatrix4fv'); end; function TShader.GetAttribLocation (name: string): GLint; begin - result := gl.getAttribLocation(programID, name); + result := gl.getAttribLocation(programID, name); end; procedure TShader.BindAttribLocation (index: GLuint; name: string); begin - gl.bindAttribLocation(programID, index, name); - //GLFatal('glBindAttribLocation '+IntToStr(index)+':'+name); + gl.bindAttribLocation(programID, index, name); + //GLFatal('glBindAttribLocation '+IntToStr(index)+':'+name); end; constructor TShader.Create (context: TJSWebGLRenderingContext; vertexShaderSource, fragmentShaderSource: string); begin - gl := context; - vertexShader := CreateShader(gl.VERTEX_SHADER, vertexShaderSource); - fragmentShader := CreateShader(gl.FRAGMENT_SHADER, fragmentShaderSource); + gl := context; + vertexShader := CreateShader(gl.VERTEX_SHADER, vertexShaderSource); + fragmentShader := CreateShader(gl.FRAGMENT_SHADER, fragmentShaderSource); end; -function TShader.CreateShader(theType: GLenum; source: string): TJSWebGLShader; +function TShader.CreateShader(theType: GLenum; source: string): TJSWebGLShader; begin - Result := gl.createShader(theType); - if Result = nil then - Fatal('create shader failed'); - gl.shaderSource(Result, source); - gl.compileShader(Result); - if gl.getShaderParameter(Result, gl.COMPILE_STATUS) then - begin - //writeln('loaded shader ', theType); - exit; - end - else - begin - Fatal(gl.getShaderInfoLog(Result)); - //gl.deleteShader(shader); - end; + Result := gl.createShader(theType); + if Result = nil then + Fatal('create shader failed'); + gl.shaderSource(Result, source); + gl.compileShader(Result); + if gl.getShaderParameter(Result, gl.COMPILE_STATUS) then + begin + //writeln('loaded shader ', theType); + exit; + end + else + begin + Fatal(gl.getShaderInfoLog(Result)); + //gl.deleteShader(shader); + end; end; -procedure TShader.Compile; +procedure TShader.Compile; begin - programID := gl.createProgram; - gl.attachShader(programID, vertexShader); - gl.attachShader(programID, fragmentShader); + programID := gl.createProgram; + gl.attachShader(programID, vertexShader); + gl.attachShader(programID, fragmentShader); end; -procedure TShader.Link; +procedure TShader.Link; begin gl.linkProgram(programID); if not gl.getProgramParameter(programID, gl.LINK_STATUS) then - begin - Fatal(gl.getProgramInfoLog(programID)); - //gl.deleteProgram(programID); - end; + begin + Fatal(gl.getProgramInfoLog(programID)); + //gl.deleteProgram(programID); + end; end; -procedure TShader.Use; +procedure TShader.Use; begin - gl.useProgram(programID); + gl.useProgram(programID); end; end. diff --git a/demo/webgl/Noise.pas b/demo/webgl/Noise.pas index f660ca2..b5b9b97 100644 --- a/demo/webgl/Noise.pas +++ b/demo/webgl/Noise.pas @@ -1,7 +1,7 @@ unit Noise; interface uses - SysUtils, Math; + Math; const kNoisekPerumationMax = 256; @@ -241,4 +241,4 @@ begin p[i] := seed[i mod kNoisekPerumationMax]; end; -end. \ No newline at end of file +end. diff --git a/demo/webgl/Pas2JS_WebGL.lpi b/demo/webgl/Pas2JS_WebGL.lpi index 678f895..d182743 100644 --- a/demo/webgl/Pas2JS_WebGL.lpi +++ b/demo/webgl/Pas2JS_WebGL.lpi @@ -1,16 +1,16 @@ - - + + + - <UseAppBundle Value="False"/> <ResourceType Value="res"/> @@ -18,7 +18,7 @@ <CustomData Count="1"> <Item0 Name="PasJSWebBrowserProject" Value="1"/> </CustomData> - <BuildModes Count="1"> + <BuildModes> <Item1 Name="Default" Default="True"/> </BuildModes> <PublishOptions> @@ -28,11 +28,6 @@ <FormatVersion Value="2"/> <Modes Count="0"/> </RunParams> - <RequiredPackages Count="1"> - <Item1> - <PackageName Value="pas2js_rtl"/> - </Item1> - </RequiredPackages> <Units Count="1"> <Unit0> <Filename Value="Pas2JS_WebGL.pas"/> @@ -66,7 +61,7 @@ </Linking> <Other> <CustomOptions Value="-Jeutf-8 -Jirtl.js -Jc -Jminclude"/> - <CompilerPath Value="$MakeExe(IDE,pas2js)"/> + <CompilerPath Value="$(pas2js)"/> </Other> </CompilerOptions> <Debugging> diff --git a/demo/webgl/Pas2JS_WebGL_Minimal.lpi b/demo/webgl/Pas2JS_WebGL_Minimal.lpi index bb9c476..fe85644 100644 --- a/demo/webgl/Pas2JS_WebGL_Minimal.lpi +++ b/demo/webgl/Pas2JS_WebGL_Minimal.lpi @@ -1,16 +1,16 @@ <?xml version="1.0" encoding="UTF-8"?> <CONFIG> - <ProjectOptions> - <Version Value="11"/> + <ProjectOptions BuildModesCount="1"> + <Version Value="12"/> <General> <Flags> <MainUnitHasCreateFormStatements Value="False"/> <MainUnitHasTitleStatement Value="False"/> <MainUnitHasScaledStatement Value="False"/> <Runnable Value="False"/> + <CompatibilityMode Value="True"/> </Flags> <SessionStorage Value="InProjectDir"/> - <MainUnit Value="0"/> <Title Value="project1"/> <UseAppBundle Value="False"/> <ResourceType Value="res"/> @@ -18,7 +18,7 @@ <CustomData Count="1"> <Item0 Name="PasJSWebBrowserProject" Value="1"/> </CustomData> - <BuildModes Count="1"> + <BuildModes> <Item1 Name="Default" Default="True"/> </BuildModes> <PublishOptions> @@ -28,11 +28,6 @@ <FormatVersion Value="2"/> <Modes Count="0"/> </RunParams> - <RequiredPackages Count="1"> - <Item1> - <PackageName Value="pas2js_rtl"/> - </Item1> - </RequiredPackages> <Units Count="1"> <Unit0> <Filename Value="Pas2JS_WebGL_Minimal.pas"/> @@ -66,7 +61,7 @@ </Linking> <Other> <CustomOptions Value="-Jeutf-8 -Jirtl.js -Jc -Jminclude"/> - <CompilerPath Value="$MakeExe(IDE,pas2js)"/> + <CompilerPath Value="$(pas2js)"/> </Other> </CompilerOptions> <Debugging> diff --git a/demo/webgl/Pas2JS_WebGL_OBJ.lpi b/demo/webgl/Pas2JS_WebGL_OBJ.lpi index d311f3f..ee1c2e8 100644 --- a/demo/webgl/Pas2JS_WebGL_OBJ.lpi +++ b/demo/webgl/Pas2JS_WebGL_OBJ.lpi @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <CONFIG> <ProjectOptions> - <Version Value="11"/> + <Version Value="12"/> <General> <Flags> <MainUnitHasCreateFormStatements Value="False"/> @@ -10,7 +10,6 @@ <Runnable Value="False"/> </Flags> <SessionStorage Value="InProjectDir"/> - <MainUnit Value="0"/> <Title Value="project1"/> <UseAppBundle Value="False"/> <ResourceType Value="res"/> @@ -18,8 +17,8 @@ <CustomData Count="1"> <Item0 Name="PasJSWebBrowserProject" Value="1"/> </CustomData> - <BuildModes Count="1"> - <Item1 Name="Default" Default="True"/> + <BuildModes> + <Item Name="Default" Default="True"/> </BuildModes> <PublishOptions> <Version Value="2"/> @@ -28,16 +27,11 @@ <FormatVersion Value="2"/> <Modes Count="0"/> </RunParams> - <RequiredPackages Count="1"> - <Item1> - <PackageName Value="pas2js_rtl"/> - </Item1> - </RequiredPackages> - <Units Count="1"> - <Unit0> + <Units> + <Unit> <Filename Value="Pas2JS_WebGL_OBJ.pas"/> <IsPartOfProject Value="True"/> - </Unit0> + </Unit> </Units> </ProjectOptions> <CompilerOptions> diff --git a/demo/webgl/Pas2JS_WebGL_OBJ.pas b/demo/webgl/Pas2JS_WebGL_OBJ.pas index 1884348..b22be36 100644 --- a/demo/webgl/Pas2JS_WebGL_OBJ.pas +++ b/demo/webgl/Pas2JS_WebGL_OBJ.pas @@ -4,8 +4,8 @@ uses BrowserConsole, Web, WebGL, JS, Math; var - gl: TJSWebGLRenderingContext; - shader: TShader; + gl: TJSWebGLRenderingContext; + shader: TShader; projTransform: TMat4; viewTransform: TMat4; modelTransform: TMat4; diff --git a/demo/webgl/Pas2JS_WebGL_Terrain.lpi b/demo/webgl/Pas2JS_WebGL_Terrain.lpi index a60b8a0..443660d 100644 --- a/demo/webgl/Pas2JS_WebGL_Terrain.lpi +++ b/demo/webgl/Pas2JS_WebGL_Terrain.lpi @@ -1,16 +1,16 @@ <?xml version="1.0" encoding="UTF-8"?> <CONFIG> - <ProjectOptions> - <Version Value="11"/> + <ProjectOptions BuildModesCount="1"> + <Version Value="12"/> <General> <Flags> <MainUnitHasCreateFormStatements Value="False"/> <MainUnitHasTitleStatement Value="False"/> <MainUnitHasScaledStatement Value="False"/> <Runnable Value="False"/> + <CompatibilityMode Value="True"/> </Flags> <SessionStorage Value="InProjectDir"/> - <MainUnit Value="0"/> <Title Value="project1"/> <UseAppBundle Value="False"/> <ResourceType Value="res"/> @@ -18,7 +18,7 @@ <CustomData Count="1"> <Item0 Name="PasJSWebBrowserProject" Value="1"/> </CustomData> - <BuildModes Count="1"> + <BuildModes> <Item1 Name="Default" Default="True"/> </BuildModes> <PublishOptions> @@ -28,11 +28,6 @@ <FormatVersion Value="2"/> <Modes Count="0"/> </RunParams> - <RequiredPackages Count="1"> - <Item1> - <PackageName Value="pas2js_rtl"/> - </Item1> - </RequiredPackages> <Units Count="1"> <Unit0> <Filename Value="Pas2JS_WebGL_Terrain.pas"/> @@ -66,7 +61,7 @@ </Linking> <Other> <CustomOptions Value="-Jeutf-8 -Jirtl.js -Jc -Jminclude"/> - <CompilerPath Value="$MakeExe(IDE,pas2js)"/> + <CompilerPath Value="$(pas2js)"/> </Other> </CompilerOptions> <Debugging> diff --git a/demo/webgl/Pas2JS_WebGL_Terrain.pas b/demo/webgl/Pas2JS_WebGL_Terrain.pas index e322ebd..be98a01 100644 --- a/demo/webgl/Pas2JS_WebGL_Terrain.pas +++ b/demo/webgl/Pas2JS_WebGL_Terrain.pas @@ -11,7 +11,7 @@ var viewTransform: TMat4; modelTransform: TMat4; - var +var debugConsole: TJSElement; canvasAnimationHandler: integer = 0;