123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- program Pas2JS_WebGL;
- uses
- Mat4, MemoryBuffer, GLUtils, GLTypes, SysUtils,
- BrowserConsole, Web, WebGL, JS, Math;
- type
- GLVertex2 = record
- pos: TVec2;
- color: TRGBAb;
- end;
- const
- kSIZEOF_VERTEX = 12; // vec2 + RGBAb
- function GetVertexData: TJSUInt8Array;
- var
- buffer: TMemoryBuffer;
- verts: TJSArray;
- v: GLVertex2;
- i: integer;
- begin
- // there's really no reason to build the array
- // as vectors first then pack into bytes but
- // we're doing it anyways because this how most
- // will be familar with vertex data from standard
- // OpenGL
- verts := TJSArray.new;
- v.pos := V2(0, 0);
- v.color := RGBAb(255, 0, 0, 255);
- verts.push(v);
- v.pos := V2(0, 100);
- v.color := RGBAb(0, 255, 0, 255);
- verts.push(v);
- v.pos := V2(100, 100);
- v.color := RGBAb(0, 0, 255, 255);
- verts.push(v);
- // pack the array of verticies into a byte buffer
- buffer := TMemoryBuffer.Create(kSIZEOF_VERTEX * verts.length);
- for i := 0 to verts.length - 1 do
- begin
- v := GLVertex2(verts[i]);
- buffer.AddFloats(2, {v.pos}ToFloats(v.pos));
- buffer.AddBytes(4, v.color);
- end;
- result := buffer.GetBytes;
- end;
- var
- nextTime: TJSFloat32 = 0;
- deltaTime: TJSFloat32 = 0;
- var
- gl: TJSWebGLRenderingContext;
- shader: TShader;
- projTransform: TMat4;
- viewTransform: TMat4;
- modelTransform: TMat4;
- var
- rotateAngle: double = 0;
- procedure UpdateCanvas(time: TJSDOMHighResTimeStamp);
- var
- now: TJSFloat32;
- begin
- now := time * 0.001;
- deltaTime := now - nextTime;
- nextTime := now;
- modelTransform := TMat4.Identity;
- modelTransform := modelTransform.Multiply(TMat4.Translate(100, 100, 0));
- modelTransform := modelTransform.Multiply(TMat4.RotateZ(DegToRad(rotateAngle)));
- rotateAngle := rotateAngle + (20 * deltaTime);
- shader.SetUniformMat4('modelTransform', modelTransform);
- //writeln(deltaTime);
- gl.clear(gl.COLOR_BUFFER_BIT);
- gl.drawArrays(gl.TRIANGLES, 0, 3);
- window.requestAnimationFrame(@UpdateCanvas);
- end;
- var
- canvas: TJSHTMLCanvasElement;
- stride: integer;
- offset: integer;
- vertexShaderSource: string;
- fragmentShaderSource: string;
- buffer: TJSWebGLBuffer;
- begin
- // make webgl context
- canvas := TJSHTMLCanvasElement(document.createElement('canvas'));
- canvas.width := 300;
- canvas.height := 300;
- document.body.appendChild(canvas);
- gl := TJSWebGLRenderingContext(canvas.getContext('webgl'));
- if gl = nil then
- begin
- writeln('failed to load webgl!');
- exit;
- end;
- // create shaders from source in html
- vertexShaderSource := document.getElementById('vertex.glsl').textContent;
- fragmentShaderSource := document.getElementById('fragment.glsl').textContent;
- shader := TShader.Create(gl, vertexShaderSource, fragmentShaderSource);
- shader.Compile;
- shader.BindAttribLocation(0, 'in_position');
- shader.BindAttribLocation(1, 'in_color');
- shader.Link;
- shader.Use;
- // prepare context
- gl.clearColor(0.9, 0.9, 0.9, 1);
- gl.viewport(0, 0, canvas.width, canvas.height);
- gl.clear(gl.COLOR_BUFFER_BIT);
- // setup transform matricies
- projTransform := TMat4.Ortho(0, gl.canvas.width, gl.canvas.height, 0, -1, 1);
- viewTransform := TMat4.Identity;
- modelTransform := TMat4.Identity;
- shader.SetUniformMat4('projTransform', projTransform);
- shader.SetUniformMat4('viewTransform', viewTransform);
- shader.SetUniformMat4('modelTransform', modelTransform);
- // create buffer
- buffer := gl.createBuffer;
- gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
- gl.bufferData(gl.ARRAY_BUFFER, GetVertexData, gl.STATIC_DRAW);
- offset := 0;
- stride := kSIZEOF_VERTEX;
- // position
- gl.enableVertexAttribArray(0);
- gl.vertexAttribPointer(0, 2, gl.FLOAT, false, stride, offset);
- offset += GLSizeof(gl.FLOAT) * 2;
- // color (normalized = true since we're using unsigned byte)
- gl.enableVertexAttribArray(1);
- gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, true, stride, offset);
- offset += GLSizeof(gl.UNSIGNED_BYTE) * 4;
- // fire off the timer to draw
- window.requestAnimationFrame(@UpdateCanvas);
- end.
|