diff --git a/CWasm.sublime-project b/CWasm.sublime-project index e06e498..e33dba2 100644 --- a/CWasm.sublime-project +++ b/CWasm.sublime-project @@ -95,6 +95,7 @@ "GlId jsGlCreateBuffer()", "GlId jsGlCreateProgram()", "GlId jsGlCreateShader(GlEnum shaderType)", + "GlId jsGlCreateTexture()", "GlId jsGlCreateVertexArray()", "GlId jsGlGetUniformLocation(GlId programId, int nameLength, const char* namePntr)", "bool jsGlGetProgramParameterBool(GlId programId, GlEnum parameter)", @@ -106,8 +107,10 @@ "void InitGlobalArenas(u32 scratchArenasSize)", "void ResetToArenaMark(ArenaMark arenaMark)", "void ResetToMark(Arena* arena, u32 mark)", + "void jsGlActiveTexture(GlEnum textureIndex)", "void jsGlAttachShader(GlId programId, GlId shaderId)", "void jsGlBindBuffer(GlEnum bufferType, GlId bufferId)", + "void jsGlBindTexture(GlEnum target, GlId textureId)", "void jsGlBindVertexArray(GlId vaoId)", "void jsGlBlendFunc(GlEnum srcFactor, GlEnum dstFactor)", "void jsGlBlendFuncSeparate(GlEnum srcRGB, GlEnum dstRGB, GlEnum srcAlpha, GlEnum dstAlpha)", @@ -118,14 +121,19 @@ "void jsGlDeleteBuffer(GlId bufferId)", "void jsGlDeleteProgram(GlId programId)", "void jsGlDeleteShader(GlId shaderId)", + "void jsGlDeleteTexture(GlId textureId)", + "void jsGlDeleteVertexArray(GlId vaoId)", "void jsGlDepthFunc(GlEnum depthFunc)", "void jsGlDisable(GlEnum capability)", "void jsGlDrawArrays(GlEnum geometryType, int startIndex, int count)", "void jsGlEnable(GlEnum capability)", "void jsGlEnableVertexAttribArray(GlEnum location)", "void jsGlFrontFace(GlEnum cullMode)", + "void jsGlGenerateMipmap(GlEnum target)", "void jsGlLinkProgram(GlId programId)", "void jsGlShaderSource(GlId shaderId, int sourceLength, const char* sourcePntr)", + "void jsGlTexImage2D(GlEnum target, GlEnum level, GlEnum internalFormat, int width, int height, int border, GlEnum format, GlEnum type, int dataLength, const void* dataPntr)", + "void jsGlTexParameteri(GlEnum target, GlEnum parameter, int value)", "void jsGlUniform1f(int location, r32 value)", "void jsGlUniform1fv(GlId locationId, int valuesCount, const r32* valuesPntr)", "void jsGlUniform1i(GlId locationId, int value)", diff --git a/cwasm_webgl_js_imports.h b/cwasm_webgl_js_imports.h index 12eebd5..05b7a6d 100644 --- a/cwasm_webgl_js_imports.h +++ b/cwasm_webgl_js_imports.h @@ -20,6 +20,14 @@ MAYBE_EXTERN_C void jsGlDeleteBuffer(GlId bufferId); MAYBE_EXTERN_C GlId jsGlCreateBuffer(); MAYBE_EXTERN_C void jsGlBindBuffer(GlEnum bufferType, GlId bufferId); MAYBE_EXTERN_C void jsGlBufferData(GlEnum bufferType, u32 dataLength, const void* dataPntr, GlEnum usageHint); +MAYBE_EXTERN_C void jsGlDeleteTexture(GlId textureId); +MAYBE_EXTERN_C GlId jsGlCreateTexture(); +MAYBE_EXTERN_C void jsGlActiveTexture(GlEnum textureIndex); +MAYBE_EXTERN_C void jsGlBindTexture(GlEnum target, GlId textureId); +MAYBE_EXTERN_C void jsGlTexImage2D(GlEnum target, GlEnum level, GlEnum internalFormat, int width, int height, int border, GlEnum format, GlEnum type, int dataLength, const void* dataPntr); +MAYBE_EXTERN_C void jsGlTexParameteri(GlEnum target, GlEnum parameter, int value); +MAYBE_EXTERN_C void jsGlGenerateMipmap(GlEnum target); +MAYBE_EXTERN_C void jsGlDeleteVertexArray(GlId vaoId); MAYBE_EXTERN_C GlId jsGlCreateVertexArray(); MAYBE_EXTERN_C void jsGlBindVertexArray(GlId vaoId); MAYBE_EXTERN_C void jsGlEnableVertexAttribArray(GlEnum location); diff --git a/data/gl_functions.js b/data/gl_functions.js index 5087d85..694d129 100644 --- a/data/gl_functions.js +++ b/data/gl_functions.js @@ -4,6 +4,7 @@ import { wasmPntrToJsString, wasmPntrAndLengthToJsString } from './wasm_function export var glObjects = { buffers: [ null ], + textures: [ null ], vaos: [ null ], shaders: [ null ], programs: [ null ], @@ -22,6 +23,15 @@ function verifyGlBufferId(bufferId, allowZero) if (glObjects.buffers[bufferId] == null) { return "BufferId is for a destroyed vertBuffer!"; } return null; } +function verifyGlTextureId(textureId, allowZero) +{ + if (typeof(textureId) != "number") { return "TextureId is not a number!"; } + if (textureId == 0) { return allowZero ? null : "TextureId is 0!"; } + if (glObjects == null || glObjects.textures == null) { return "Textures array has not been initialized yet!"; } + if (textureId >= glObjects.textures.length) { return "TextureId is too high!"; } + if (glObjects.textures[textureId] == null) { return "TextureId is for a destroyed texture!"; } + return null; +} function verifyGlVaoId(vaoId, allowZero) { if (typeof(vaoId) != "number") { return "VaoId is not a number!"; } @@ -97,6 +107,9 @@ export function jsGlFrontFace(cullMode) appGlobals.glContext.frontFace(cullMode); } +// +==============================+ +// | Buffer Functions | +// +==============================+ export function jsGlDeleteBuffer(bufferId) { if (!verifyParameter(verifyGlBufferId(bufferId, false), "gl.deleteBuffer", "bufferId", bufferId)) { return; } @@ -120,10 +133,65 @@ export function jsGlBindBuffer(bufferType, bufferId) export function jsGlBufferData(bufferType, dataLength, dataPntr, usageHint) { - let dataArray = appGlobals.memDataView.buffer.slice(dataPntr, dataPntr + dataLength) + let dataArray = appGlobals.memDataView.buffer.slice(dataPntr, dataPntr + dataLength); appGlobals.glContext.bufferData(bufferType, dataArray, usageHint); } +// +==============================+ +// | Texture Functions | +// +==============================+ +export function jsGlDeleteTexture(textureId) +{ + if (!verifyParameter(verifyGlTextureId(textureId, false), "gl.deleteTexture", "textureId", textureId)) { return; } + appGlobals.glContext.deleteTexture(glObjects.textures[textureId]); + glObjects.textures[textureId] = null; +} +export function jsGlCreateTexture() +{ + let newTexture = appGlobals.glContext.createTexture(); + let newTextureId = glObjects.textures.length; + glObjects.textures.push(newTexture); + return newTextureId; +} + +export function jsGlActiveTexture(textureIndex) +{ + appGlobals.glContext.activeTexture(textureIndex); +} + +export function jsGlBindTexture(target, textureId) +{ + if (!verifyParameter(verifyGlTextureId(textureId, true), "gl.bindTexture", "textureId", textureId)) { return; } + let texture = glObjects.textures[textureId]; + appGlobals.glContext.bindTexture(target, texture); +} + +export function jsGlTexImage2D(target, level, internalFormat, width, height, border, format, type, dataLength, dataPntr) +{ + // let dataBuffer = appGlobals.memDataView.buffer.slice(dataPntr, dataPntr + dataLength); + let dataBuffer = new Uint8Array(appGlobals.memDataView.buffer, dataPntr, dataLength); + appGlobals.glContext.texImage2D(target, level, internalFormat, width, height, border, format, type, dataBuffer); +} + +export function jsGlTexParameteri(target, parameter, value) +{ + appGlobals.glContext.texParameteri(target, parameter, value) +} + +export function jsGlGenerateMipmap(target) +{ + appGlobals.glContext.generateMipmap(target); +} + +// +==============================+ +// | Vertex Array Functions | +// +==============================+ +export function jsGlDeleteVertexArray(vaoId) +{ + if (!verifyParameter(verifyGlVaoId(vaoId, true), "gl.deleteVertexArray", "vaoId", vaoId)) { return; } + appGlobals.glContext.deleteVertexArray(glObjects.vaos[vaoId]); + glObjects.vaos[vaoId] = null; +} export function jsGlCreateVertexArray() { let newVao = appGlobals.glContext.createVertexArray(); @@ -132,7 +200,6 @@ export function jsGlCreateVertexArray() return newVaoId; } -//TODO: jsGlDeleteVertexArray? export function jsGlBindVertexArray(vaoId) { if (!verifyParameter(verifyGlVaoId(vaoId, true), "gl.bindVertexArray", "vaoId", vaoId)) { return; } @@ -150,6 +217,9 @@ export function jsGlVertexAttribPointer(attribLocation, componentCount, componen appGlobals.glContext.vertexAttribPointer(attribLocation, componentCount, componentType, normalized, stride, offset); } +// +==============================+ +// | Shader Functions | +// +==============================+ export function jsGlDeleteShader(shaderId) { if (!verifyParameter(verifyGlShaderId(shaderId, false), "gl.deleteShader", "shaderId", shaderId)) { return; } @@ -199,7 +269,7 @@ export function jsGlGetShaderParameterInt(shaderId, parameter) export function jsGlDeleteProgram(programId) { if (!verifyParameter(verifyGlProgramId(programId, false), "gl.deleteProgram", "programId", programId)) { return; } - appGlobals.glContext.deleteShader(glObjects.programs[programId]); + appGlobals.glContext.deleteProgram(glObjects.programs[programId]); glObjects.programs[programId] = null; } export function jsGlCreateProgram() @@ -250,6 +320,9 @@ export function jsGlGetProgramParameterInt(programId, parameter) return paramValue; } +// +==============================+ +// | Clearing Functions | +// +==============================+ export function jsGlClearColor(rValue, gValue, bValue, aValue) { appGlobals.glContext.clearColor(rValue, gValue, bValue, aValue); @@ -268,11 +341,17 @@ export function jsGlClear(bufferBits) appGlobals.glContext.clear(bufferBits); } +// +==============================+ +// | Drawing Functions | +// +==============================+ export function jsGlDrawArrays(geometryType, startIndex, count) { appGlobals.glContext.drawArrays(geometryType, startIndex, count); } +// +==============================+ +// | Uniform Functions | +// +==============================+ export function jsGlGetUniformLocation(programId, nameLength, namePntr) { if (!verifyParameter(verifyGlProgramId(programId, false), "gl.getUniformLocation", "programId", programId)) { return false; } @@ -414,6 +493,9 @@ export function jsGlUniformMatrix4fv(locationId, valuesPntr) appGlobals.glContext.uniformMatrix4fv(location, false, valuesArray); } +// +==============================+ +// | Functions List | +// +==============================+ export let jsGlFunctions = { jsGlEnable: jsGlEnable, jsGlDisable: jsGlDisable, @@ -425,6 +507,14 @@ export let jsGlFunctions = { jsGlCreateBuffer: jsGlCreateBuffer, jsGlBindBuffer: jsGlBindBuffer, jsGlBufferData: jsGlBufferData, + jsGlDeleteTexture: jsGlDeleteTexture, + jsGlCreateTexture: jsGlCreateTexture, + jsGlActiveTexture: jsGlActiveTexture, + jsGlBindTexture: jsGlBindTexture, + jsGlTexImage2D: jsGlTexImage2D, + jsGlTexParameteri: jsGlTexParameteri, + jsGlGenerateMipmap: jsGlGenerateMipmap, + jsGlDeleteVertexArray: jsGlDeleteVertexArray, jsGlCreateVertexArray: jsGlCreateVertexArray, jsGlBindVertexArray: jsGlBindVertexArray, jsGlEnableVertexAttribArray: jsGlEnableVertexAttribArray, @@ -469,9 +559,5 @@ export let jsGlFunctions = { jsGlUniformMatrix4fv: jsGlUniformMatrix4fv, }; -//TODO: deleteTexture(webglObjects.textures[textureId]) -//TODO: texImage2D(target, level, internalformat, width, height, border, format, type, dataBuffer) -//TODO: generateMipmap(target) - //TODO: string getShaderInfoLog(shaderId) //TODO: string getProgramInfoLog(programId) diff --git a/data/main.js b/data/main.js index e505096..4eb4c7b 100644 --- a/data/main.js +++ b/data/main.js @@ -23,14 +23,6 @@ function AcquireCanvas(canvasWidth, canvasHeight) appGlobals.canvas = canvas; } -function CreateGlContext() -{ - var canvasContextGl = appGlobals.canvas.getContext("webgl2"); - if (canvasContextGl === null) { console.error("Unable to initialize WebGL render context. Your browser or machine may not support it :("); return null; } - // console.dir(canvasContextGl); - appGlobals.glContext = canvasContextGl; -} - async function LoadWasmModule(wasmFilePath, initialWasmPageCount) { appGlobals.textDecoder = new TextDecoder("utf-8"); @@ -50,7 +42,11 @@ async function MainLoop() { console.log("Initializing WebGL Canvas..."); AcquireCanvas(600, 400); - CreateGlContext(); + + var canvasContextGl = appGlobals.canvas.getContext("webgl2"); + if (canvasContextGl === null) { console.error("Unable to initialize WebGL render context. Your browser or machine may not support it :("); return; } + // console.dir(canvasContextGl); + appGlobals.glContext = canvasContextGl; console.log("Loading WASM Module..."); await LoadWasmModule("app.wasm", 4); diff --git a/test_app.c b/test_app.c index fbb1b50..9b1fc91 100644 --- a/test_app.c +++ b/test_app.c @@ -12,11 +12,15 @@ struct { GlId positionBuffer; GlId colorBuffer; + GlId texCoordBuffer; GlId vao; + GlId dotTexture; + GlId testTexture; + GlId vertexShader; GlId fragmentShader; GlId testShader; - GlId testUniformLocation; + GlId texture1Location; GlId worldMatrixLocation; GlId viewMatrixLocation; GlId projMatrixLocation; @@ -53,9 +57,13 @@ WASM_EXPORT(App_Initialize) void App_Initialize() memset(&app, 0x00, sizeof(app)); r32 positions[] = { - -0.7, -0.7, // left bottom corner - 0.7, -0.7, // right bottom corner - 0.0, 0.7 // center top corner + 0.0, 0.0, + 1.0, 0.0, + 0.0, 1.0, + + 1.0, 1.0, + 0.0, 1.0, + 1.0, 0.0 }; app.positionBuffer = jsGlCreateBuffer(); jsGlBindBuffer(GL_ARRAY_BUFFER, app.positionBuffer); @@ -63,14 +71,32 @@ WASM_EXPORT(App_Initialize) void App_Initialize() u8 colors[] = { // R , G , B - 255, 0, 0, // red - 0, 255, 0, // green - 0, 0, 255 // blue + 255, 255, 255, + 255, 255, 255, + 255, 255, 255, + + 255, 255, 255, + 255, 255, 255, + 255, 255, 255, }; app.colorBuffer = jsGlCreateBuffer(); jsGlBindBuffer(GL_ARRAY_BUFFER, app.colorBuffer); jsGlBufferData(GL_ARRAY_BUFFER, sizeof(colors), &colors[0], GL_STATIC_DRAW); + r32 texCoords[] = { + // U, V + 0.0f, 0.0f, + 1.0f, 0.0f, + 0.0f, 1.0f, + + 1.0f, 1.0f, + 0.0f, 1.0f, + 1.0f, 0.0f, + }; + app.texCoordBuffer = jsGlCreateBuffer(); + jsGlBindBuffer(GL_ARRAY_BUFFER, app.texCoordBuffer); + jsGlBufferData(GL_ARRAY_BUFFER, sizeof(texCoords), &texCoords[0], GL_STATIC_DRAW); + app.vao = jsGlCreateVertexArray(); jsGlBindVertexArray(app.vao); // start "recording" // position attribute data @@ -79,7 +105,7 @@ WASM_EXPORT(App_Initialize) void App_Initialize() jsGlVertexAttribPointer( 0, // attrib location 2, // components per element: vec2 for our postition data - GL_FLOAT, // buffer data type: we have Float32Array + GL_FLOAT, false, // whether the data is normalized to 0.0 1.0 range in shaders 0, // stride, not important atm 0 // offset, not important atm @@ -92,11 +118,77 @@ WASM_EXPORT(App_Initialize) void App_Initialize() 3, // components per element: GL_UNSIGNED_BYTE, // we have Uint8Array true, // the 0..255 is normalized into 0.0...1.0 in shaders - 0, - 0 + 0, //stride + 0 //offset + ); + // texCoord attribute data + jsGlBindBuffer(GL_ARRAY_BUFFER, app.texCoordBuffer); + jsGlEnableVertexAttribArray(2); + jsGlVertexAttribPointer( + 2, // attrib location + 2, // components per element: + GL_FLOAT, + false, // not normalized + 0, //stride + 0 //offset ); jsGlBindVertexArray(0); // end "recording" + app.dotTexture = jsGlCreateTexture(); + jsGlActiveTexture(GL_TEXTURE0); + jsGlBindTexture(GL_TEXTURE_2D, app.dotTexture); + u32 dotPixel = 0xFFFFFFFF; + jsGlTexImage2D( + GL_TEXTURE_2D, //bound texture type + 0, //image level + GL_RGBA, //internal format + 1, //image width + 1, //image height + 0, //border + GL_RGBA, //format + GL_UNSIGNED_BYTE, //type + sizeof(dotPixel), //dataLength + &dotPixel //dataPntr + ); + jsGlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + jsGlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + jsGlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + jsGlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + jsGlGenerateMipmap(GL_TEXTURE_2D); + + app.testTexture = jsGlCreateTexture(); + jsGlActiveTexture(GL_TEXTURE0); + jsGlBindTexture(GL_TEXTURE_2D, app.testTexture); + u32 testPixels[] = { + 0xFFEEEEEE, 0xFFDDDDEE, 0xFFCCCCEE, 0xFFBBBBEE, 0xFFAAAAEE, 0xFF9999EE, 0xFF8888EE, 0xFF7777EE, 0xFF6666EE, 0xFF5555EE, + 0xFFEEEEDD, 0xFFDDDDDD, 0xFFCCCCDD, 0xFFBBBBDD, 0xFFAAAADD, 0xFF9999DD, 0xFF8888DD, 0xFF7777DD, 0xFF6666DD, 0xFF5555DD, + 0xFFEEEECC, 0xFFDDDDCC, 0xFFCCCCCC, 0xFFBBBBCC, 0xFFAAAACC, 0xFF9999CC, 0xFF8888CC, 0xFF7777CC, 0xFF6666CC, 0xFF5555CC, + 0xFFEEEEBB, 0xFFDDDDBB, 0xFFCCCCBB, 0xFFBBBBBB, 0xFFAAAABB, 0xFF9999BB, 0xFF8888BB, 0xFF7777BB, 0xFF6666BB, 0xFF5555BB, + 0xFFEEEEAA, 0xFFDDDDAA, 0xFFCCCCAA, 0xFFBBBBAA, 0xFFAAAAAA, 0xFF9999AA, 0xFF8888AA, 0xFF7777AA, 0xFF6666AA, 0xFF5555AA, + 0xFFEEEE99, 0xFFDDDD99, 0xFFCCCC99, 0xFFBBBB99, 0xFFAAAA99, 0xFF999999, 0xFF888899, 0xFF777799, 0xFF666699, 0xFF555599, + 0xFFEEEE88, 0xFFDDDD88, 0xFFCCCC88, 0xFFBBBB88, 0xFFAAAA88, 0xFF999988, 0xFF888888, 0xFF777788, 0xFF666688, 0xFF555588, + 0xFFEEEE77, 0xFFDDDD77, 0xFFCCCC77, 0xFFBBBB77, 0xFFAAAA77, 0xFF999977, 0xFF888877, 0xFF777777, 0xFF666677, 0xFF555577, + 0xFFEEEE66, 0xFFDDDD66, 0xFFCCCC66, 0xFFBBBB66, 0xFFAAAA66, 0xFF999966, 0xFF888866, 0xFF777766, 0xFF666666, 0xFF555566, + 0xFFEEEE55, 0xFFDDDD55, 0xFFCCCC55, 0xFFBBBB55, 0xFFAAAA55, 0xFF999955, 0xFF888855, 0xFF777755, 0xFF666655, 0xFF555555, + }; + jsGlTexImage2D( + GL_TEXTURE_2D, //bound texture type + 0, //image level + GL_RGBA, //internal format + 10, //image width + 10, //image height + 0, //border + GL_RGBA, //format + GL_UNSIGNED_BYTE, //type + sizeof(testPixels), //dataLength + &testPixels //dataPntr + ); + jsGlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + jsGlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + jsGlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + jsGlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + jsGlGenerateMipmap(GL_TEXTURE_2D); + app.vertexShader = jsGlCreateShader(GL_VERTEX_SHADER); jsGlShaderSource(app.vertexShader, (int)strlen(VertexShaderCodeStr), VertexShaderCodeStr); jsGlCompileShader(app.vertexShader); @@ -112,8 +204,10 @@ WASM_EXPORT(App_Initialize) void App_Initialize() // also debug the program status if (!jsGlGetProgramParameterBool(app.testShader, GL_LINK_STATUS)) { WriteLine_E("Failed to link shader program!"); } //TODO: jsGlGetProgramInfoLog - const char* uniformName = "TestUniform"; - app.testUniformLocation = jsGlGetUniformLocation(app.testShader, (int)strlen(uniformName), uniformName); + // const char* uniformName = "TestUniform"; + // app.testUniformLocation = jsGlGetUniformLocation(app.testShader, (int)strlen(uniformName), uniformName); + const char* texture1Name = "Texture1"; + app.texture1Location = jsGlGetUniformLocation(app.testShader, (int)strlen(texture1Name), texture1Name); const char* worldMatrixName = "WorldMatrix"; app.worldMatrixLocation = jsGlGetUniformLocation(app.testShader, (int)strlen(worldMatrixName), worldMatrixName); const char* viewMatrixName = "ViewMatrix"; @@ -127,10 +221,10 @@ WASM_EXPORT(App_Initialize) void App_Initialize() // +--------------------------------------------------------------+ WASM_EXPORT(App_Close) void App_Close() { - //TODO: Delete vao jsGlDeleteProgram(app.testShader); jsGlDeleteShader(app.vertexShader); jsGlDeleteShader(app.fragmentShader); + jsGlDeleteVertexArray(app.vao); jsGlDeleteBuffer(app.positionBuffer); jsGlDeleteBuffer(app.colorBuffer); } @@ -155,6 +249,8 @@ WASM_EXPORT(App_UpdateAndRender) bool App_UpdateAndRender(r64 programTimeR64) jsGlClear(GL_COLOR_BUFFER_BIT); jsGlBindVertexArray(app.vao); // our vertex array object jsGlUseProgram(app.testShader); // our shader program + jsGlActiveTexture(GL_TEXTURE0); + jsGlBindTexture(GL_TEXTURE_2D, app.testTexture); r32 identityMatrix[] = { 1.0f, 0.0f, 0.0f, 0.0f, @@ -165,15 +261,16 @@ WASM_EXPORT(App_UpdateAndRender) bool App_UpdateAndRender(r64 programTimeR64) jsGlUniformMatrix4fv(app.viewMatrixLocation, &identityMatrix[0]); jsGlUniformMatrix4fv(app.projMatrixLocation, &identityMatrix[0]); + #if 0 const u64 numTris = 75; for (u64 tIndex = 0; tIndex < numTris; tIndex++) { - r32 uniformValues[] = { - OscillateBy(programTime, 0.0f, 1.0f, 2000, 0 + tIndex*(2000/numTris)), - OscillateBy(programTime, 0.0f, 1.0f, 2000, 1200 + tIndex*(2000/numTris)), - OscillateBy(programTime, 0.0f, 1.0f, 2000, 700 + tIndex*(2000/numTris)), - }; - jsGlUniform1fv(app.testUniformLocation, ArrayCount(uniformValues), &uniformValues[0]); + // r32 uniformValues[] = { + // OscillateBy(programTime, 0.0f, 1.0f, 2000, 0 + tIndex*(2000/numTris)), + // OscillateBy(programTime, 0.0f, 1.0f, 2000, 1200 + tIndex*(2000/numTris)), + // OscillateBy(programTime, 0.0f, 1.0f, 2000, 700 + tIndex*(2000/numTris)), + // }; + // jsGlUniform1fv(app.testUniformLocation, ArrayCount(uniformValues), &uniformValues[0]); r32 offsetX = OscillateBy(programTime, -0.1f, 0.1f, 3000, 0 + tIndex*(3000/numTris)); r32 offsetY = OscillateBy(programTime, -0.1f, 0.1f, 3000, 750 + tIndex*(3000/numTris)); @@ -186,8 +283,26 @@ WASM_EXPORT(App_UpdateAndRender) bool App_UpdateAndRender(r64 programTimeR64) 0.0f, 0.0f, 0.0f, 1.0f, }; jsGlUniformMatrix4fv(app.worldMatrixLocation, &worldMatrix[0]); - jsGlDrawArrays(GL_TRIANGLES, 0, 3); + jsGlDrawArrays(GL_TRIANGLES, 0, 6); } + #endif + + { + r32 offsetX = 0.0f; + r32 offsetY = 0.0f; + r32 scaleX = 1.0f; + r32 scaleY = 1.0f; + r32 worldMatrix[] = { + scaleX, 0.0f, 0.0f, offsetX, + 0.0f, scaleY, 0.0f, offsetY, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, + }; + jsGlUniformMatrix4fv(app.worldMatrixLocation, &worldMatrix[0]); + jsGlDrawArrays(GL_TRIANGLES, 0, 6); + } + + // if (programTime > 5000) { shouldContinue = false; } app.frameIndex++; app.prevProgramTimeR64 = programTimeR64; @@ -219,12 +334,18 @@ static const char* VertexShaderCodeStr = "#version 300 es\n" "// this is the color attrib at index: 1\n" "layout(location=1) in vec3 aCol;\n" "\n" +"// this is the texCoord attrib at index: 2\n" +"layout(location=2) in vec2 aTexCoord;\n" +"\n" "// this is the interpolate color which is\n" "// passed to the fragment shader\n" "out vec3 vCol;\n" "\n" +"out vec2 vTexCoord;\n" +"\n" "void main(){\n" " vCol = aCol; // just pass through the value \n" +" vTexCoord = aTexCoord; // just pass through the value \n" " \n" " // vertex position for the shader program\n" " // always a vec4 value\n" @@ -234,14 +355,16 @@ static const char* VertexShaderCodeStr = "#version 300 es\n" static const char* FragmentShaderCodeStr = "#version 300 es\n" "precision highp float;\n" "\n" -"uniform float TestUniform[3];\n" +"uniform sampler2D Texture1;\n" "\n" "in vec3 vCol; // the data from vertex shader\n" +"in vec2 vTexCoord; // the data from vertex shader\n" "\n" "// fragment output value\n" "// essentially the color of the output pixel\n" "out vec4 outCol;\n" "\n" "void main(){\n" -" outCol = vec4(vec3(vCol.r * TestUniform[0], vCol.g * TestUniform[1], vCol.b * TestUniform[2]), 1.0);\n" +" vec4 sampleColor = texture(Texture1, vTexCoord);\n" +" outCol = vec4(vCol, 1.0) * sampleColor;\n" "}\n";