Added some more WebGL functions to gl_functions.js. Made the test_app render something more interesting. Added a bool return from App_UpdateAndRender which allows it to request that the application loop ends.
This commit is contained in:
@@ -109,12 +109,21 @@
|
||||
"void jsGlAttachShader(GlId programId, GlId shaderId)",
|
||||
"void jsGlBindBuffer(GlEnum bufferType, GlId bufferId)",
|
||||
"void jsGlBindVertexArray(GlId vaoId)",
|
||||
"void jsGlBlendFunc(GlEnum srcFactor, GlEnum dstFactor)",
|
||||
"void jsGlBlendFuncSeparate(GlEnum srcRGB, GlEnum dstRGB, GlEnum srcAlpha, GlEnum dstAlpha)",
|
||||
"void jsGlBufferData(GlEnum bufferType, u32 dataLength, const void* dataPntr, GlEnum usageHint)",
|
||||
"void jsGlClear(int bufferBits)",
|
||||
"void jsGlClearColor(r32 rValue, r32 gValue, r32 bValue, r32 aValue)",
|
||||
"void jsGlCompileShader(GlId shaderId)",
|
||||
"void jsGlDeleteBuffer(GlId bufferId)",
|
||||
"void jsGlDeleteProgram(GlId programId)",
|
||||
"void jsGlDeleteShader(GlId shaderId)",
|
||||
"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 jsGlLinkProgram(GlId programId)",
|
||||
"void jsGlShaderSource(GlId shaderId, int sourceLength, const char* sourcePntr)",
|
||||
"void jsGlUniform1f(int location, r32 value)",
|
||||
|
||||
@@ -10,6 +10,13 @@ Date: 09\01\2025
|
||||
typedef int GlId; // Really this is just an index into a javascript array that holds the real reference to the WebGL object
|
||||
typedef int GlEnum;
|
||||
|
||||
MAYBE_EXTERN_C void jsGlEnable(GlEnum capability);
|
||||
MAYBE_EXTERN_C void jsGlDisable(GlEnum capability);
|
||||
MAYBE_EXTERN_C void jsGlBlendFunc(GlEnum srcFactor, GlEnum dstFactor);
|
||||
MAYBE_EXTERN_C void jsGlBlendFuncSeparate(GlEnum srcRGB, GlEnum dstRGB, GlEnum srcAlpha, GlEnum dstAlpha);
|
||||
MAYBE_EXTERN_C void jsGlDepthFunc(GlEnum depthFunc);
|
||||
MAYBE_EXTERN_C void jsGlFrontFace(GlEnum cullMode);
|
||||
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);
|
||||
@@ -17,11 +24,13 @@ MAYBE_EXTERN_C GlId jsGlCreateVertexArray();
|
||||
MAYBE_EXTERN_C void jsGlBindVertexArray(GlId vaoId);
|
||||
MAYBE_EXTERN_C void jsGlEnableVertexAttribArray(GlEnum location);
|
||||
MAYBE_EXTERN_C void jsGlVertexAttribPointer(GlEnum attribLocation, int componentCount, GlEnum componentType, bool normalized, int stride, int offset);
|
||||
MAYBE_EXTERN_C void jsGlDeleteShader(GlId shaderId);
|
||||
MAYBE_EXTERN_C GlId jsGlCreateShader(GlEnum shaderType);
|
||||
MAYBE_EXTERN_C void jsGlShaderSource(GlId shaderId, int sourceLength, const char* sourcePntr);
|
||||
MAYBE_EXTERN_C void jsGlCompileShader(GlId shaderId);
|
||||
MAYBE_EXTERN_C bool jsGlGetShaderParameterBool(GlId shaderId, GlEnum parameter);
|
||||
MAYBE_EXTERN_C int jsGlGetShaderParameterInt(GlId shaderId, GlEnum parameter);
|
||||
MAYBE_EXTERN_C void jsGlDeleteProgram(GlId programId);
|
||||
MAYBE_EXTERN_C GlId jsGlCreateProgram();
|
||||
MAYBE_EXTERN_C void jsGlAttachShader(GlId programId, GlId shaderId);
|
||||
MAYBE_EXTERN_C void jsGlLinkProgram(GlId programId);
|
||||
@@ -29,6 +38,8 @@ MAYBE_EXTERN_C void jsGlUseProgram(GlId programId);
|
||||
MAYBE_EXTERN_C bool jsGlGetProgramParameterBool(GlId programId, GlEnum parameter);
|
||||
MAYBE_EXTERN_C int jsGlGetProgramParameterInt(GlId programId, GlEnum parameter);
|
||||
MAYBE_EXTERN_C void jsGlClearColor(r32 rValue, r32 gValue, r32 bValue, r32 aValue);
|
||||
MAYBE_EXTERN_C void jsGlClearDepth(r32 depth);
|
||||
MAYBE_EXTERN_C void jsGlClearStencil(r32 stencilValue);
|
||||
MAYBE_EXTERN_C void jsGlClear(int bufferBits);
|
||||
MAYBE_EXTERN_C void jsGlDrawArrays(GlEnum geometryType, int startIndex, int count);
|
||||
MAYBE_EXTERN_C GlId jsGlGetUniformLocation(GlId programId, int nameLength, const char* namePntr);
|
||||
|
||||
@@ -69,6 +69,40 @@ function verifyParameter(verifyResult, functionName, parameterName, parameterVal
|
||||
// +--------------------------------------------------------------+
|
||||
// | WebGL API |
|
||||
// +--------------------------------------------------------------+
|
||||
export function jsGlEnable(capability)
|
||||
{
|
||||
appGlobals.glContext.enable(capability);
|
||||
}
|
||||
export function jsGlDisable(capability)
|
||||
{
|
||||
appGlobals.glContext.disable(capability);
|
||||
}
|
||||
|
||||
export function jsGlBlendFunc(srcFactor, dstFactor)
|
||||
{
|
||||
appGlobals.glContext.blendFunc(srcFactor, dstFactor);
|
||||
}
|
||||
export function jsGlBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha)
|
||||
{
|
||||
appGlobals.glContext.blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
|
||||
}
|
||||
|
||||
export function jsGlDepthFunc(depthFunc)
|
||||
{
|
||||
appGlobals.glContext.depthFunc(depthFunc);
|
||||
}
|
||||
|
||||
export function jsGlFrontFace(cullMode)
|
||||
{
|
||||
appGlobals.glContext.frontFace(cullMode);
|
||||
}
|
||||
|
||||
export function jsGlDeleteBuffer(bufferId)
|
||||
{
|
||||
if (!verifyParameter(verifyGlBufferId(bufferId, false), "gl.deleteBuffer", "bufferId", bufferId)) { return; }
|
||||
appGlobals.glContext.deleteBuffer(glObjects.buffers[bufferId]);
|
||||
glObjects.buffers[bufferId] = null;
|
||||
}
|
||||
export function jsGlCreateBuffer()
|
||||
{
|
||||
let newBuffer = appGlobals.glContext.createBuffer();
|
||||
@@ -98,6 +132,7 @@ export function jsGlCreateVertexArray()
|
||||
return newVaoId;
|
||||
}
|
||||
|
||||
//TODO: jsGlDeleteVertexArray?
|
||||
export function jsGlBindVertexArray(vaoId)
|
||||
{
|
||||
if (!verifyParameter(verifyGlVaoId(vaoId, true), "gl.bindVertexArray", "vaoId", vaoId)) { return; }
|
||||
@@ -115,6 +150,12 @@ export function jsGlVertexAttribPointer(attribLocation, componentCount, componen
|
||||
appGlobals.glContext.vertexAttribPointer(attribLocation, componentCount, componentType, normalized, stride, offset);
|
||||
}
|
||||
|
||||
export function jsGlDeleteShader(shaderId)
|
||||
{
|
||||
if (!verifyParameter(verifyGlShaderId(shaderId, false), "gl.deleteShader", "shaderId", shaderId)) { return; }
|
||||
appGlobals.glContext.deleteShader(glObjects.shaders[shaderId]);
|
||||
glObjects.shaders[shaderId] = null;
|
||||
}
|
||||
export function jsGlCreateShader(shaderType)
|
||||
{
|
||||
let newShader = appGlobals.glContext.createShader(shaderType);
|
||||
@@ -155,6 +196,12 @@ export function jsGlGetShaderParameterInt(shaderId, parameter)
|
||||
return paramValue;
|
||||
}
|
||||
|
||||
export function jsGlDeleteProgram(programId)
|
||||
{
|
||||
if (!verifyParameter(verifyGlProgramId(programId, false), "gl.deleteProgram", "programId", programId)) { return; }
|
||||
appGlobals.glContext.deleteShader(glObjects.programs[programId]);
|
||||
glObjects.programs[programId] = null;
|
||||
}
|
||||
export function jsGlCreateProgram()
|
||||
{
|
||||
let newProgram = appGlobals.glContext.createProgram();
|
||||
@@ -207,6 +254,14 @@ export function jsGlClearColor(rValue, gValue, bValue, aValue)
|
||||
{
|
||||
appGlobals.glContext.clearColor(rValue, gValue, bValue, aValue);
|
||||
}
|
||||
export function jsGlClearDepth(depth)
|
||||
{
|
||||
appGlobals.glContext.clearDepth(depth);
|
||||
}
|
||||
export function jsGlClearStencil(stencilValue)
|
||||
{
|
||||
appGlobals.glContext.clearStencil(stencilValue);
|
||||
}
|
||||
|
||||
export function jsGlClear(bufferBits)
|
||||
{
|
||||
@@ -360,6 +415,13 @@ export function jsGlUniformMatrix4fv(locationId, valuesPntr)
|
||||
}
|
||||
|
||||
export let jsGlFunctions = {
|
||||
jsGlEnable: jsGlEnable,
|
||||
jsGlDisable: jsGlDisable,
|
||||
jsGlBlendFunc: jsGlBlendFunc,
|
||||
jsGlBlendFuncSeparate: jsGlBlendFuncSeparate,
|
||||
jsGlDepthFunc: jsGlDepthFunc,
|
||||
jsGlFrontFace: jsGlFrontFace,
|
||||
jsGlDeleteBuffer: jsGlDeleteBuffer,
|
||||
jsGlCreateBuffer: jsGlCreateBuffer,
|
||||
jsGlBindBuffer: jsGlBindBuffer,
|
||||
jsGlBufferData: jsGlBufferData,
|
||||
@@ -367,11 +429,13 @@ export let jsGlFunctions = {
|
||||
jsGlBindVertexArray: jsGlBindVertexArray,
|
||||
jsGlEnableVertexAttribArray: jsGlEnableVertexAttribArray,
|
||||
jsGlVertexAttribPointer: jsGlVertexAttribPointer,
|
||||
jsGlDeleteShader: jsGlDeleteShader,
|
||||
jsGlCreateShader: jsGlCreateShader,
|
||||
jsGlShaderSource: jsGlShaderSource,
|
||||
jsGlCompileShader: jsGlCompileShader,
|
||||
jsGlGetShaderParameterBool: jsGlGetShaderParameterBool,
|
||||
jsGlGetShaderParameterInt: jsGlGetShaderParameterInt,
|
||||
jsGlDeleteProgram: jsGlDeleteProgram,
|
||||
jsGlCreateProgram: jsGlCreateProgram,
|
||||
jsGlAttachShader: jsGlAttachShader,
|
||||
jsGlLinkProgram: jsGlLinkProgram,
|
||||
@@ -379,6 +443,8 @@ export let jsGlFunctions = {
|
||||
jsGlGetProgramParameterBool: jsGlGetProgramParameterBool,
|
||||
jsGlGetProgramParameterInt: jsGlGetProgramParameterInt,
|
||||
jsGlClearColor: jsGlClearColor,
|
||||
jsGlClearDepth: jsGlClearDepth,
|
||||
jsGlClearStencil: jsGlClearStencil,
|
||||
jsGlClear: jsGlClear,
|
||||
jsGlDrawArrays: jsGlDrawArrays,
|
||||
jsGlGetUniformLocation: jsGlGetUniformLocation,
|
||||
@@ -403,5 +469,9 @@ 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)
|
||||
|
||||
@@ -59,8 +59,9 @@ async function MainLoop()
|
||||
console.log("Running!");
|
||||
function renderFrame(currentTime)
|
||||
{
|
||||
appGlobals.wasmModule.exports.App_UpdateAndRender(currentTime);
|
||||
window.requestAnimationFrame(renderFrame);
|
||||
let shouldContinue = appGlobals.wasmModule.exports.App_UpdateAndRender(currentTime);
|
||||
if (shouldContinue) { window.requestAnimationFrame(renderFrame); }
|
||||
else { appGlobals.wasmModule.exports.App_Close(); }
|
||||
}
|
||||
window.requestAnimationFrame(renderFrame);
|
||||
}
|
||||
|
||||
84
test_app.c
84
test_app.c
@@ -28,6 +28,15 @@ struct
|
||||
static const char* VertexShaderCodeStr;
|
||||
static const char* FragmentShaderCodeStr;
|
||||
|
||||
r32 OscillateBy(u64 timeSource, r32 min, r32 max, u64 periodMs, u64 offset)
|
||||
{
|
||||
r32 lerpValue = (sinf((((timeSource + offset) % periodMs) / (r32)periodMs) * 2*Pi32) + 1.0f) / 2.0f;
|
||||
return min + (max - min) * lerpValue;
|
||||
}
|
||||
|
||||
// +--------------------------------------------------------------+
|
||||
// | Initialize |
|
||||
// +--------------------------------------------------------------+
|
||||
WASM_EXPORT(App_Initialize) void App_Initialize()
|
||||
{
|
||||
InitializeCWasm(Kilobytes(128));
|
||||
@@ -113,14 +122,25 @@ WASM_EXPORT(App_Initialize) void App_Initialize()
|
||||
app.projMatrixLocation = jsGlGetUniformLocation(app.testShader, (int)strlen(projMatrixName), projMatrixName);
|
||||
}
|
||||
|
||||
r32 OscillateBy(u64 timeSource, r32 min, r32 max, u64 periodMs, u64 offset)
|
||||
// +--------------------------------------------------------------+
|
||||
// | Close |
|
||||
// +--------------------------------------------------------------+
|
||||
WASM_EXPORT(App_Close) void App_Close()
|
||||
{
|
||||
r32 lerpValue = (sinf((((timeSource + offset) % periodMs) / (r32)periodMs) * 2*Pi32) + 1.0f) / 2.0f;
|
||||
return min + (max - min) * lerpValue;
|
||||
//TODO: Delete vao
|
||||
jsGlDeleteProgram(app.testShader);
|
||||
jsGlDeleteShader(app.vertexShader);
|
||||
jsGlDeleteShader(app.fragmentShader);
|
||||
jsGlDeleteBuffer(app.positionBuffer);
|
||||
jsGlDeleteBuffer(app.colorBuffer);
|
||||
}
|
||||
|
||||
WASM_EXPORT(App_UpdateAndRender) void App_UpdateAndRender(r64 programTimeR64)
|
||||
// +--------------------------------------------------------------+
|
||||
// | Update and Render |
|
||||
// +--------------------------------------------------------------+
|
||||
WASM_EXPORT(App_UpdateAndRender) bool App_UpdateAndRender(r64 programTimeR64)
|
||||
{
|
||||
bool shouldContinue = true;
|
||||
r64 timeScaleR64 = (programTimeR64 - app.prevProgramTimeR64) / (1000.0 / 60.0);
|
||||
if (fabs(timeScaleR64 - 1.0) < 0.001) { timeScaleR64 = 1.0; }
|
||||
if (timeScaleR64 > 4.0) { timeScaleR64 = 4.0; }
|
||||
@@ -130,43 +150,53 @@ WASM_EXPORT(App_UpdateAndRender) void App_UpdateAndRender(r64 programTimeR64)
|
||||
u64 programTime = (u64)programTimeR64;
|
||||
u64 elapsedMs = programTime - (u64)app.prevProgramTimeR64;
|
||||
|
||||
// jsGlClearColor(OscillateBy(programTime, 0.0f, 1.0f, 3700, 1500), OscillateBy(programTime, 0.0f, 1.0f, 5300, 2000), OscillateBy(programTime, 0.0f, 1.0f, 2300, 500), 1.0f);
|
||||
jsGlClearColor(32/255.0f, 32/255.0f, 32/255.0f, 1.0f);
|
||||
jsGlClear(GL_COLOR_BUFFER_BIT);
|
||||
jsGlBindVertexArray(app.vao); // our vertex array object
|
||||
jsGlUseProgram(app.testShader); // our shader program
|
||||
|
||||
r32 identityMatrix[] = {
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f,
|
||||
};
|
||||
r32 worldMatrix[] = {
|
||||
OscillateBy(programTime, 0.9f, 1.1f, 3000, 0), 0.0f, 0.0f, OscillateBy(programTime, -0.1f, 0.1f, 3000, 0),
|
||||
0.0f, OscillateBy(programTime, 0.9f, 1.1f, 3000, 1500), 0.0f, OscillateBy(programTime, -0.1f, 0.1f, 3000, 750),
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f,
|
||||
};
|
||||
|
||||
jsGlClearColor(OscillateBy(programTime, 0.0f, 1.0f, 3700, 1500), OscillateBy(programTime, 0.0f, 1.0f, 5300, 2000), OscillateBy(programTime, 0.0f, 1.0f, 2300, 500), 1.0f);
|
||||
jsGlClear(GL_COLOR_BUFFER_BIT);
|
||||
jsGlBindVertexArray(app.vao); // our vertex array object
|
||||
jsGlUseProgram(app.testShader); // our shader program
|
||||
r32 uniformValues[] = {
|
||||
OscillateBy(programTime, 0.0f, 1.0f, 2000, 0),
|
||||
OscillateBy(programTime, 0.0f, 1.0f, 2000, 1200),
|
||||
OscillateBy(programTime, 0.0f, 1.0f, 2000, 700),
|
||||
};
|
||||
jsGlUniform1fv(app.testUniformLocation, ArrayCount(uniformValues), &uniformValues[0]);
|
||||
jsGlUniformMatrix4fv(app.worldMatrixLocation, &worldMatrix[0]);
|
||||
jsGlUniformMatrix4fv(app.viewMatrixLocation, &identityMatrix[0]);
|
||||
jsGlUniformMatrix4fv(app.projMatrixLocation, &identityMatrix[0]);
|
||||
|
||||
jsGlDrawArrays(
|
||||
GL_TRIANGLES, // drawing mode
|
||||
0, // index of the first vertex to draw
|
||||
3 // number of vertices to draw
|
||||
);
|
||||
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 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));
|
||||
r32 scaleX = OscillateBy(programTime, 0.9f - tIndex*(0.9f/numTris), 1.1f - tIndex*(0.9f/numTris), 3000, 0 + tIndex*(3000/numTris));
|
||||
r32 scaleY = OscillateBy(programTime, 0.9f - tIndex*(0.9f/numTris), 1.1f - tIndex*(0.9f/numTris), 3000, 1500 + tIndex*(3000/numTris));
|
||||
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, 3);
|
||||
}
|
||||
|
||||
app.frameIndex++;
|
||||
app.prevProgramTimeR64 = programTimeR64;
|
||||
return shouldContinue;
|
||||
}
|
||||
|
||||
// +--------------------------------------------------------------+
|
||||
// | Shaders |
|
||||
// +--------------------------------------------------------------+
|
||||
static const char* VertexShaderCodeStr = "#version 300 es\n"
|
||||
"// ^^^\n"
|
||||
"// the version definition has to be the first line in\n"
|
||||
|
||||
Reference in New Issue
Block a user