From 78ca52766b2a23713dce1bab02a531b556566640 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Thu, 11 Jun 2026 23:59:17 +0200 Subject: [PATCH 01/21] actually use the Camera's matricies and fix mistake with the matrix lookat thingy --- src/gl/gl_renderer.c | 2 ++ src/runner.h | 2 ++ src/vm_builtins.c | 48 +++++++++++++++++++++++++++++++++----------- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index accb6efe9..143ae8f93 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -558,6 +558,7 @@ static void glEndView(Renderer* renderer) { // camera_apply: swap the active world->clip projection on the current target without touching its viewport. static void glApplyProjection(Renderer* renderer, const Matrix4f* worldToClip) { GLRenderer* gl = (GLRenderer*) renderer; + // Flush first so pending quads draw under the projection they were issued with. flushBatch(gl); Matrix4f projection = *worldToClip; @@ -565,6 +566,7 @@ static void glApplyProjection(Renderer* renderer, const Matrix4f* worldToClip) { renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; glShaderSettingsRefresh(renderer); renderer->previousViewMatrix = projection; + } static void glBeginGUI(Renderer* renderer, int32_t guiW, int32_t guiH, int32_t portX, int32_t portY, int32_t portW, int32_t portH, int32_t targetSurfaceId) { diff --git a/src/runner.h b/src/runner.h index 1f5ce8b0d..b1fa5df1a 100644 --- a/src/runner.h +++ b/src/runner.h @@ -158,6 +158,8 @@ typedef struct { // Center derived from camera_set_view_mat; kept so set_view_mat / set_proj_mat (which arrive in either order) can both recompute the top-left viewX/viewY once the size from the proj matrix is known. int32_t viewMatCenterX; int32_t viewMatCenterY; + Matrix4f ViewMatrix; + Matrix4f ProjectionMatrix; } GMLCamera; typedef struct { diff --git a/src/vm_builtins.c b/src/vm_builtins.c index c26ab7e34..5c9f58b4d 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -2953,20 +2953,20 @@ static RValue builtin_matrix_build_lookat(MAYBE_UNUSED VMContext *ctx, RValue *a Matrix4f_identity(&matrix); matrix.m[Matrix_getIndex(0, 0)] = xRight; - matrix.m[Matrix_getIndex(0, 1)] = xUp; - matrix.m[Matrix_getIndex(0, 2)] = xLook; + matrix.m[Matrix_getIndex(1, 0)] = xUp; + matrix.m[Matrix_getIndex(2, 0)] = xLook; - matrix.m[Matrix_getIndex(1, 0)] = yRight; + matrix.m[Matrix_getIndex(0, 1)] = yRight; matrix.m[Matrix_getIndex(1, 1)] = yUp; - matrix.m[Matrix_getIndex(1, 2)] = yLook; + matrix.m[Matrix_getIndex(2, 1)] = yLook; - matrix.m[Matrix_getIndex(2, 0)] = zRight; - matrix.m[Matrix_getIndex(2, 1)] = zUp; + matrix.m[Matrix_getIndex(0, 2)] = zRight; + matrix.m[Matrix_getIndex(1, 2)] = zUp; matrix.m[Matrix_getIndex(2, 2)] = zLook; - matrix.m[Matrix_getIndex(3, 0)] = -x; - matrix.m[Matrix_getIndex(3, 1)] = -y; - matrix.m[Matrix_getIndex(3, 2)] = -z; + matrix.m[Matrix_getIndex(0, 3)] = -x; + matrix.m[Matrix_getIndex(1, 3)] = -y; + matrix.m[Matrix_getIndex(2, 3)] = -z; bool toPrevMatrix = argCount == 10; GMLArray *destArray = toPrevMatrix ? args[9].array : nullptr; @@ -3488,9 +3488,24 @@ static RValue builtin_camera_set_view_mat(VMContext* ctx, RValue* args, int32_t camera->viewMatCenterY = (int32_t) lround(-m.m[Matrix_getIndex(3, 1)]); camera->viewX = camera->viewMatCenterX - camera->viewWidth / 2; camera->viewY = camera->viewMatCenterY - camera->viewHeight / 2; + camera->ViewMatrix = m; return RValue_makeUndefined(); } +static RValue builtin_camera_get_view_mat(VMContext* ctx, RValue* args, int32_t argCount) { + Runner* runner = ctx->runner; + GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); + if (camera == nullptr) return RValue_makeUndefined(); + return RValue_makeArray(matrixToGml(&camera->ViewMatrix)); +} + +static RValue builtin_camera_get_proj_mat(VMContext* ctx, RValue* args, int32_t argCount) { + Runner* runner = ctx->runner; + GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); + if (camera == nullptr) return RValue_makeUndefined(); + return RValue_makeArray(matrixToGml(&camera->ProjectionMatrix)); +} + static RValue builtin_camera_set_proj_mat(VMContext* ctx, RValue* args, int32_t argCount) { if (2 > argCount) return RValue_makeUndefined(); Runner* runner = ctx->runner; @@ -3505,6 +3520,8 @@ static RValue builtin_camera_set_proj_mat(VMContext* ctx, RValue* args, int32_t if (m11 != 0.0) camera->viewHeight = (int32_t) lround(GMLReal_fabs(2.0 / m11)); camera->viewX = camera->viewMatCenterX - camera->viewWidth / 2; camera->viewY = camera->viewMatCenterY - camera->viewHeight / 2; + camera->ProjectionMatrix = m; + camera->ProjectionMatrix.m[Matrix_getIndex(1, 1)] = -m.m[Matrix_getIndex(1, 1)]; return RValue_makeUndefined(); } @@ -3692,9 +3709,14 @@ static RValue builtin_camera_apply(VMContext* ctx, RValue* args, int32_t argCoun Runner* runner = ctx->runner; GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); if (camera != nullptr) { - Matrix4f worldToClip; - Matrix4f_viewProjection(&worldToClip, (float) camera->viewX, (float) camera->viewY, (float) camera->viewWidth, (float) camera->viewHeight, camera->viewAngle); - runner->renderer->vtable->applyProjection(runner->renderer, &worldToClip); + + Matrix4f ViewMatrix = camera->ViewMatrix; + Matrix4f ProjectionMatrix = camera->ProjectionMatrix; + Matrix4f FinalProjection; + Matrix4f_multiply(&FinalProjection, &ProjectionMatrix, &ViewMatrix); + + runner->renderer->vtable->applyProjection(runner->renderer, &FinalProjection); + } return RValue_makeUndefined(); } @@ -15517,7 +15539,9 @@ void VMBuiltins_registerAll(VMContext* ctx) { VM_registerBuiltin(ctx, "camera_get_view_height", builtin_camera_get_view_height); VM_registerBuiltin(ctx, "camera_set_view_pos", builtin_camera_set_view_pos); VM_registerBuiltin(ctx, "camera_set_view_mat", builtin_camera_set_view_mat); + VM_registerBuiltin(ctx, "camera_get_view_mat", builtin_camera_get_view_mat); VM_registerBuiltin(ctx, "camera_set_proj_mat", builtin_camera_set_proj_mat); + VM_registerBuiltin(ctx, "camera_get_proj_mat", builtin_camera_get_proj_mat); VM_registerBuiltin(ctx, "camera_get_view_target", builtin_camera_get_view_target); VM_registerBuiltin(ctx, "camera_set_view_target", builtin_camera_set_view_target); VM_registerBuiltin(ctx, "camera_get_view_border_x", builtin_camera_get_view_border_x); From caa4bbee116affb1ff8dc9f18c66a2b3e8d4cacb Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Fri, 12 Jun 2026 13:15:02 +0200 Subject: [PATCH 02/21] remove ViewMatCenter --- src/runner.h | 4 +--- src/vm_builtins.c | 5 ----- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/runner.h b/src/runner.h index b1fa5df1a..873b7efd8 100644 --- a/src/runner.h +++ b/src/runner.h @@ -155,9 +155,7 @@ typedef struct { int32_t speedY; int32_t objectId; // follow target (object index), -1 = none float viewAngle; - // Center derived from camera_set_view_mat; kept so set_view_mat / set_proj_mat (which arrive in either order) can both recompute the top-left viewX/viewY once the size from the proj matrix is known. - int32_t viewMatCenterX; - int32_t viewMatCenterY; + Matrix4f ViewMatrix; Matrix4f ProjectionMatrix; } GMLCamera; diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 5c9f58b4d..ac2a268c9 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -3483,11 +3483,6 @@ static RValue builtin_camera_set_view_mat(VMContext* ctx, RValue* args, int32_t if (camera == nullptr || !rvalueIsMatrix(args[1])) return RValue_makeUndefined(); Matrix4f m; matrixFromGml(&m, args[1].array); - // For an axis-aligned 2D camera the view-matrix translation encodes -(camera center). - camera->viewMatCenterX = (int32_t) lround(-m.m[Matrix_getIndex(3, 0)]); - camera->viewMatCenterY = (int32_t) lround(-m.m[Matrix_getIndex(3, 1)]); - camera->viewX = camera->viewMatCenterX - camera->viewWidth / 2; - camera->viewY = camera->viewMatCenterY - camera->viewHeight / 2; camera->ViewMatrix = m; return RValue_makeUndefined(); } From 3c7d68d86c4d13d3eb33ad73fd2e34cddf31e255 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Fri, 12 Jun 2026 13:17:21 +0200 Subject: [PATCH 03/21] fix tiny mistake --- src/vm_builtins.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vm_builtins.c b/src/vm_builtins.c index ac2a268c9..db62ddf88 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -3513,8 +3513,6 @@ static RValue builtin_camera_set_proj_mat(VMContext* ctx, RValue* args, int32_t GMLReal m11 = m.m[Matrix_getIndex(1, 1)]; if (m00 != 0.0) camera->viewWidth = (int32_t) lround(GMLReal_fabs(2.0 / m00)); if (m11 != 0.0) camera->viewHeight = (int32_t) lround(GMLReal_fabs(2.0 / m11)); - camera->viewX = camera->viewMatCenterX - camera->viewWidth / 2; - camera->viewY = camera->viewMatCenterY - camera->viewHeight / 2; camera->ProjectionMatrix = m; camera->ProjectionMatrix.m[Matrix_getIndex(1, 1)] = -m.m[Matrix_getIndex(1, 1)]; return RValue_makeUndefined(); From 3f2637e5f5c0218dba7ed9536367b0b9af973616 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Sat, 13 Jun 2026 00:45:19 +0200 Subject: [PATCH 04/21] change more things to use matricies! I kinda forgor what else I did --- src/gl/gl_renderer.c | 44 +++++++++--- src/gl/gl_renderer.h | 2 + src/gl_legacy/gl_legacy_renderer.c | 4 +- src/renderer.h | 3 +- src/runner.c | 8 ++- src/vm_builtins.c | 110 +++++++++++++++++++++++++++-- 6 files changed, 149 insertions(+), 22 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index 143ae8f93..8b12e6d04 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -42,11 +42,11 @@ static const char* defaultVertexShaderSource = "layout(location = 0) in vec2 aPos;\n" "layout(location = 1) in vec4 aColor;\n" "layout(location = 2) in vec2 aTexCoord;\n" - "uniform mat4 uProjection;\n" + "uniform mat4 uWorldViewProjection;\n" "out vec2 vTexCoord;\n" "out vec4 vColor;\n" "void main() {\n" - " gl_Position = uProjection * vec4(aPos, 0.0, 1.0);\n" + " gl_Position = uWorldViewProjection * vec4(aPos, 0.0, 1.0);\n" " vTexCoord = aTexCoord;\n" " vColor = aColor;\n" "}\n"; @@ -59,7 +59,7 @@ static const char* defaultFragmentShaderSource = "uniform sampler2D uTexture;\n" "uniform float uAlphaTestRef;\n" "uniform bool uAlphaTestEnabled;\n" - "uniform vec4 uFogColor;\n" // rgb = fog color, a = enable flag (0 or 1) +"uniform vec4 uFogColor;\n" // rgb = fog color, a = enable flag (0 or 1) "out vec4 fragColor;\n" "void main() {\n" " vec4 c = texture(uTexture, vTexCoord) * vColor;\n" @@ -538,7 +538,7 @@ static void glBeginView(Renderer* renderer, int32_t viewX, int32_t viewY, int32_ // World -> clip transform for this view. Matrix4f projection; Matrix4f_viewProjection(&projection, (float) viewX, (float) viewY, (float) viewW, (float) viewH, viewAngle); - Matrix4f_flipClipY(&projection); + renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; glShaderSettingsRefresh(renderer); @@ -556,16 +556,30 @@ static void glEndView(Renderer* renderer) { } // camera_apply: swap the active world->clip projection on the current target without touching its viewport. -static void glApplyProjection(Renderer* renderer, const Matrix4f* worldToClip) { +static void glApplyProjection(Renderer* renderer, const Matrix4f* ViewMatrix,const Matrix4f* ProjectionMatrix) { GLRenderer* gl = (GLRenderer*) renderer; // Flush first so pending quads draw under the projection they were issued with. flushBatch(gl); - Matrix4f projection = *worldToClip; - Matrix4f_flipClipY(&projection); - renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; + + Matrix4f World = renderer->gmlMatrices[MATRIX_WORLD]; + Matrix4f View = *ViewMatrix; + Matrix4f Projection = *ProjectionMatrix; + + Matrix4f WorldView; + Matrix4f_multiply(&WorldView, &View, &World); + + Matrix4f WorldViewProjection; + Matrix4f_multiply(&WorldViewProjection, &View, &World); + Matrix4f_multiply(&WorldViewProjection, &Projection, &WorldViewProjection); + + renderer->gmlMatrices[MATRIX_VIEW] = View; + renderer->gmlMatrices[MATRIX_PROJECTION] = Projection; + renderer->gmlMatrices[MATRIX_WORLD_VIEW] = WorldView; + renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = WorldViewProjection; + //oh my I hope it's good enough. glShaderSettingsRefresh(renderer); - renderer->previousViewMatrix = projection; + renderer->previousViewMatrix = WorldViewProjection; } @@ -592,7 +606,7 @@ static void glBeginGUI(Renderer* renderer, int32_t guiW, int32_t guiH, int32_t p Matrix4f projection; Matrix4f_guiProjection(&projection, (float) guiW, (float) guiH, (float) portW, (float) portH); - + Matrix4f_flipClipY(&projection); renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; glShaderSettingsRefresh(renderer); glActiveTexture(GL_TEXTURE1); @@ -1990,7 +2004,7 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic // Normal surface bind: surface-local ortho covering the whole surface, no scissor. Matrix4f projection; Matrix4f_identity(&projection); - Matrix4f_ortho(&projection, 0.0f, (float) gl->surfaceWidth[surfaceId], 0.0f, (float) gl->surfaceHeight[surfaceId], -1.0f, 1.0f); + Matrix4f_ortho(&projection, 0.0f, (float) gl->surfaceWidth[surfaceId], (float) gl->surfaceHeight[surfaceId], 0.0f, -1.0f, 1.0f); glViewport(0, 0, gl->surfaceWidth[surfaceId], gl->surfaceHeight[surfaceId]); glDisable(GL_SCISSOR_TEST); renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; @@ -2482,6 +2496,13 @@ static bool glShadersSupported(void) { return true; } +static void glSetMatrix(Renderer* renderer, int32_t MatrixType, Matrix4f Matrix) { + GLRenderer* gl = (GLRenderer*) renderer; + flushBatch(gl); + renderer->gmlMatrices[MatrixType] = Matrix; + glShaderSettingsRefresh(renderer); +} + // ===[ Vtable ]=== static RendererVtable glVtable; @@ -2554,6 +2575,7 @@ Renderer* GLRenderer_create(void) { glVtable.textureSetStage = glTextureSetStage, glVtable.shaderIsCompiled = glShaderIsCompiled, glVtable.shadersSupported = glShadersSupported, + glVtable.setMatrix = glSetMatrix, gl->base.drawColor = 0xFFFFFF; // white (BGR) gl->base.drawAlpha = 1.0f; diff --git a/src/gl/gl_renderer.h b/src/gl/gl_renderer.h index 7e3b13dbd..71909234e 100644 --- a/src/gl/gl_renderer.h +++ b/src/gl/gl_renderer.h @@ -42,6 +42,8 @@ typedef struct { bool colorWriteR, colorWriteG, colorWriteB, colorWriteA; bool fogEnable; uint32_t fogColor; // BGR + float fogStart; + float fogEnd; GLuint vao, vbo, ebo; float* vertexData; // MAX_QUADS * VERTICES_PER_QUAD * FLOATS_PER_VERTEX floats diff --git a/src/gl_legacy/gl_legacy_renderer.c b/src/gl_legacy/gl_legacy_renderer.c index cbba9f0a4..9be5f2288 100644 --- a/src/gl_legacy/gl_legacy_renderer.c +++ b/src/gl_legacy/gl_legacy_renderer.c @@ -186,8 +186,8 @@ static void glEndView(MAYBE_UNUSED Renderer* renderer) { } // camera_apply: swap the active world->clip projection on the current target without touching its viewport. -static void glApplyProjection(Renderer* renderer, const Matrix4f* worldToClip) { - Matrix4f projection = *worldToClip; +static void glApplyProjection(Renderer* renderer, const Matrix4f* ViewMatrix,const Matrix4f* ProjectionMatrix) { + Matrix4f projection = *ProjectionMatrix; //fix it later Matrix4f_flipClipY(&projection); glMatrixMode(GL_PROJECTION); glLoadMatrixf(projection.m); diff --git a/src/renderer.h b/src/renderer.h index a7f390237..f9cb3a308 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -72,7 +72,7 @@ typedef struct { void (*endFrameEnd)(Renderer* renderer); void (*beginView)(Renderer* renderer, int32_t viewX, int32_t viewY, int32_t viewW, int32_t viewH, int32_t portX, int32_t portY, int32_t portW, int32_t portH, float viewAngle); void (*endView)(Renderer* renderer); - void (*applyProjection)(Renderer* renderer, const Matrix4f* worldToClip); + void (*applyProjection)(Renderer* renderer, const Matrix4f* ViewMatrix,const Matrix4f* ProjectionMatrix); // GUI pass: coordinates are (0,0)..(guiW,guiH) mapped to the current view's port rect. Called after endView. // targetSurfaceId is the surface the pass renders into, or RENDER_TARGET_HOST_FRAMEBUFFER. void (*beginGUI)(Renderer* renderer, int32_t guiW, int32_t guiH, int32_t portX, int32_t portY, int32_t portW, int32_t portH, int32_t targetSurfaceId); @@ -149,6 +149,7 @@ typedef struct { void (*textureSetStage)(Renderer* renderer, int32_t slot, uint32_t texID); bool (*shaderIsCompiled)(Renderer* renderer, int32_t shader); bool (*shadersSupported)(void); + void (*setMatrix)(Renderer* renderer, int32_t MatrixType, Matrix4f Matrix); } RendererVtable; // ===[ Renderer Base Struct ]=== diff --git a/src/runner.c b/src/runner.c index 411ccf5b5..d5b50ffa7 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1137,9 +1137,11 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh if (runner->drawBackgroundColor) renderer->vtable->clearScreen(renderer, runner->currentRoom->backgroundColor, 1.0f); - Matrix4f proj; - Matrix4f_viewProjection(&proj, (float) camera->viewX, (float) camera->viewY, (float) camera->viewWidth, (float) camera->viewHeight, camera->viewAngle); - renderer->vtable->applyProjection(renderer, &proj); + Matrix4f ViewMatrix = camera->ViewMatrix; + Matrix4f ProjectionMatrix = camera->ProjectionMatrix; + + runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); + runner->viewCurrent = (int32_t) vi; Runner_draw(runner); diff --git a/src/vm_builtins.c b/src/vm_builtins.c index db62ddf88..3ad434b8f 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -2898,6 +2898,23 @@ static RValue builtin_matrix_build_projection_perspective_fov(MAYBE_UNUSED VMCon return RValue_makeArrayWeak(destArray); } } +static RValue builtin_matrix_get(MAYBE_UNUSED VMContext *ctx, RValue *args, int32_t argCount) { + int32_t Matrix = RValue_toInt32(args[0]); + return RValue_makeArray(matrixToGml(&ctx->runner->renderer->gmlMatrices[Matrix])); +} + +static RValue builtin_matrix_set(MAYBE_UNUSED VMContext *ctx, RValue *args, int32_t argCount) { + int32_t Matrix = RValue_toInt32(args[0]); + Matrix4f m; + matrixFromGml(&m, args[1].array); + //return RValue_makeArray(matrixToGml(&ctx->runner->renderer->gmlMatrices[Matrix])); + if (ctx->runner->renderer != nullptr) { + ctx->runner->renderer->vtable->setMatrix(ctx->runner->renderer, Matrix, m); + } + + return RValue_makeUndefined(); +} + static RValue builtin_matrix_build_lookat(MAYBE_UNUSED VMContext *ctx, RValue *args, int32_t argCount) { if (argCount < 9 || argCount > 10) return RValue_makeUndefined(); @@ -3650,6 +3667,90 @@ static RValue builtin_camera_create_view(VMContext* ctx, RValue* args, int32_t a if (argCount > 7) camera->speedY = RValue_toInt32(args[7]); if (argCount > 8) camera->borderX = (uint32_t) RValue_toInt32(args[8]); if (argCount > 9) camera->borderY = (uint32_t) RValue_toInt32(args[9]); + + //what have I done. + Matrix4f Projection; + + memset(Projection.m, 0, sizeof(Projection.m)); + Projection.m[Matrix_getIndex(0,0)] = 2.0f / RValue_toReal(args[2]); + Projection.m[Matrix_getIndex(1,1)] = 2.0f / RValue_toReal(args[3]); + Projection.m[Matrix_getIndex(2,2)] = 1.0f / (32000.0 - 0.0); + Projection.m[Matrix_getIndex(3,3)] = 1.0f; + Projection.m[Matrix_getIndex(2,3)] = 0.0 / (0.0 - 32000.0); + camera->ProjectionMatrix = Projection; + + + GMLReal xFrom = RValue_toReal(args[0]) + RValue_toReal(args[2])/2.0f; + GMLReal yFrom = RValue_toReal(args[1]) + RValue_toReal(args[3])/2.0f; + GMLReal zFrom = -16000.0; + + GMLReal xTo = RValue_toReal(args[0]) + RValue_toReal(args[2])/2.0f; + GMLReal yTo = RValue_toReal(args[1]) + RValue_toReal(args[3])/2.0f; + GMLReal zTo = 16000.0; + + GMLReal xUp = 0.0; + GMLReal yUp = 1.0; + GMLReal zUp = 0.0; + GMLReal magUp = GMLReal_sqrt(xUp * xUp + yUp * yUp + zUp * zUp); + xUp /= magUp; + yUp /= magUp; + zUp /= magUp; + + GMLReal xLook = xTo - xFrom; + GMLReal yLook = yTo - yFrom; + GMLReal zLook = zTo - zFrom; + GMLReal magLook = GMLReal_sqrt(xLook * xLook + yLook * yLook + zLook * zLook); + xLook /= magLook; + yLook /= magLook; + zLook /= magLook; + + // normalised cross product between Up and Look + GMLReal xRight = yUp * zLook - zUp * yLook; + GMLReal yRight = zUp * xLook - xUp * zLook; + GMLReal zRight = xUp * yLook - yUp * xLook; + GMLReal magRight = GMLReal_sqrt(xRight * xRight + yRight * yRight + zRight * zRight); + xRight /= magRight; + yRight /= magRight; + zRight /= magRight; + + // normalised cross product between Look and Right + xUp = yLook * zRight - zLook * yRight; + yUp = zLook * xRight - xLook * zRight; + zUp = xLook * yRight - yLook * xRight; + magUp = GMLReal_sqrt(xUp * xUp + yUp * yUp + zUp * zUp); + xUp /= magUp; + yUp /= magUp; + zUp /= magUp; + + GMLReal x, y, z; + x = xFrom * xRight + yFrom * yRight + zFrom * zRight; + y = xFrom * xUp + yFrom * yUp + zFrom * zUp; + z = xFrom * xLook + yFrom * yLook + zFrom * zLook; + + Matrix4f ViewMatrix; + Matrix4f_identity(&ViewMatrix); + + ViewMatrix.m[Matrix_getIndex(0, 0)] = xRight; + ViewMatrix.m[Matrix_getIndex(1, 0)] = xUp; + ViewMatrix.m[Matrix_getIndex(2, 0)] = xLook; + + ViewMatrix.m[Matrix_getIndex(0, 1)] = yRight; + ViewMatrix.m[Matrix_getIndex(1, 1)] = yUp; + ViewMatrix.m[Matrix_getIndex(2, 1)] = yLook; + + ViewMatrix.m[Matrix_getIndex(0, 2)] = zRight; + ViewMatrix.m[Matrix_getIndex(1, 2)] = zUp; + ViewMatrix.m[Matrix_getIndex(2, 2)] = zLook; + + ViewMatrix.m[Matrix_getIndex(0, 3)] = -x; + ViewMatrix.m[Matrix_getIndex(1, 3)] = -y; + ViewMatrix.m[Matrix_getIndex(2, 3)] = -z; + camera->ViewMatrix = ViewMatrix; + + //builtin_matrix_build_lookat(ctx,args[0],args[1],RValue_makeReal(-16000.0),args[0],args[1],RValue_makeReal(16000.0), RValue_makeReal(0.0),RValue_makeReal(1.0),RValue_makeReal(0.0)) + //builtin_matrix_build_projection_ortho(ctx,args[2], args[3], RValue_makeReal(0.0), RValue_makeReal(32000.0)); + + return RValue_makeReal(id); } @@ -3705,10 +3806,8 @@ static RValue builtin_camera_apply(VMContext* ctx, RValue* args, int32_t argCoun Matrix4f ViewMatrix = camera->ViewMatrix; Matrix4f ProjectionMatrix = camera->ProjectionMatrix; - Matrix4f FinalProjection; - Matrix4f_multiply(&FinalProjection, &ProjectionMatrix, &ViewMatrix); - - runner->renderer->vtable->applyProjection(runner->renderer, &FinalProjection); + + runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); } return RValue_makeUndefined(); @@ -15489,7 +15588,8 @@ void VMBuiltins_registerAll(VMContext* ctx) { VM_registerBuiltin(ctx, "matrix_build_lookat", builtin_matrix_build_lookat); VM_registerBuiltin(ctx, "matrix_build_projection_ortho", builtin_matrix_build_projection_ortho); VM_registerBuiltin(ctx, "matrix_build_projection_perspective_fov", builtin_matrix_build_projection_perspective_fov); - + VM_registerBuiltin(ctx, "matrix_get", builtin_matrix_get); + VM_registerBuiltin(ctx, "matrix_set", builtin_matrix_set); // Random VM_registerBuiltin(ctx, "random", builtin_random); VM_registerBuiltin(ctx, "random_range", builtin_random_range); From ca9d33b0712a2012016e881215acd1b57b9c6e7b Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Sat, 13 Jun 2026 18:57:17 +0200 Subject: [PATCH 05/21] I somehow already forgor what else I did --- src/gl/gl_renderer.c | 33 ++++--- src/matrix_math.h | 81 +++++++++++++++++ src/runner.c | 47 ++++++++++ src/runner.h | 4 +- src/vm_builtins.c | 210 +++++++++++++++---------------------------- 5 files changed, 221 insertions(+), 154 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index 8b12e6d04..affdfed76 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -524,29 +524,21 @@ static void glBeginView(Renderer* renderer, int32_t viewX, int32_t viewY, int32_ // Set viewport and scissor to the port rectangle within the FBO // FBO uses game resolution, port coordinates are in game space // OpenGL viewport Y is bottom-up, game Y is top-down - int32_t glPortY = gl->gameH - portY - portH; - glViewport(portX, glPortY, portW, portH); + + glViewport(portX, portY, portW, portH); gl->base.CPortX = portX; - gl->base.CPortY = glPortY; + gl->base.CPortY = portY; gl->base.CPortW = portW; gl->base.CPortH = portH; glEnable(GL_SCISSOR_TEST); - glScissor(portX, glPortY, portW, portH); - - // World -> clip transform for this view. - Matrix4f projection; - Matrix4f_viewProjection(&projection, (float) viewX, (float) viewY, (float) viewW, (float) viewH, viewAngle); + glScissor(portX, portY, portW, portH); - - renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; glShaderSettingsRefresh(renderer); glActiveTexture(GL_TEXTURE1); glBindVertexArray(gl->vao); - renderer->previousViewMatrix = projection; - } static void glEndView(Renderer* renderer) { @@ -2500,6 +2492,23 @@ static void glSetMatrix(Renderer* renderer, int32_t MatrixType, Matrix4f Matrix) GLRenderer* gl = (GLRenderer*) renderer; flushBatch(gl); renderer->gmlMatrices[MatrixType] = Matrix; + //yeah just recalculate everything when we change a matrix + //TODO LATR: only allow these 3 to be changed directly, other ones should only be allowed to be calculated by the rest of the function + Matrix4f World = renderer->gmlMatrices[MATRIX_WORLD]; + Matrix4f View = renderer->gmlMatrices[MATRIX_VIEW]; + Matrix4f Projection = renderer->gmlMatrices[MATRIX_PROJECTION]; + + Matrix4f WorldView; + Matrix4f_multiply(&WorldView, &View, &World); + + Matrix4f WorldViewProjection; + Matrix4f_multiply(&WorldViewProjection, &View, &World); + Matrix4f_multiply(&WorldViewProjection, &Projection, &WorldViewProjection); + + renderer->gmlMatrices[MATRIX_WORLD_VIEW] = WorldView; + renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = WorldViewProjection; + + glShaderSettingsRefresh(renderer); } diff --git a/src/matrix_math.h b/src/matrix_math.h index ad8acd772..7c15807a6 100644 --- a/src/matrix_math.h +++ b/src/matrix_math.h @@ -51,6 +51,87 @@ static inline Matrix4f* Matrix4f_multiply(Matrix4f* dest, const Matrix4f* a, con return dest; } +static inline Matrix4f* Matrix4f_LookAt(Matrix4f* dest, float x_from, float y_from, float z_from, float x_to, float y_to, float z_to, float x_up, float y_up, float z_up) { + + double xFrom = x_from; + double yFrom = y_from; + double zFrom = z_from; + + double xTo = x_to; + double yTo = y_to; + double zTo = z_to; + + double xUp = x_up; + double yUp = y_up; + double zUp = z_up; + double magUp = sqrt(xUp * xUp + yUp * yUp + zUp * zUp); + xUp /= magUp; + yUp /= magUp; + zUp /= magUp; + + double xLook = xTo - xFrom; + double yLook = yTo - yFrom; + double zLook = zTo - zFrom; + double magLook = sqrt(xLook * xLook + yLook * yLook + zLook * zLook); + xLook /= magLook; + yLook /= magLook; + zLook /= magLook; + + // normalised cross product between Up and Look + double xRight = yUp * zLook - zUp * yLook; + double yRight = zUp * xLook - xUp * zLook; + double zRight = xUp * yLook - yUp * xLook; + double magRight = sqrt(xRight * xRight + yRight * yRight + zRight * zRight); + xRight /= magRight; + yRight /= magRight; + zRight /= magRight; + + // normalised cross product between Look and Right + xUp = yLook * zRight - zLook * yRight; + yUp = zLook * xRight - xLook * zRight; + zUp = xLook * yRight - yLook * xRight; + magUp = sqrt(xUp * xUp + yUp * yUp + zUp * zUp); + xUp /= magUp; + yUp /= magUp; + zUp /= magUp; + + double x, y, z; + x = xFrom * xRight + yFrom * yRight + zFrom * zRight; + y = xFrom * xUp + yFrom * yUp + zFrom * zUp; + z = xFrom * xLook + yFrom * yLook + zFrom * zLook; + + dest->m[Matrix_getIndex(0, 0)] = xRight; + dest->m[Matrix_getIndex(1, 0)] = xUp; + dest->m[Matrix_getIndex(2, 0)] = xLook; + + dest->m[Matrix_getIndex(0, 1)] = yRight; + dest->m[Matrix_getIndex(1, 1)] = yUp; + dest->m[Matrix_getIndex(2, 1)] = yLook; + + dest->m[Matrix_getIndex(0, 2)] = zRight; + dest->m[Matrix_getIndex(1, 2)] = zUp; + dest->m[Matrix_getIndex(2, 2)] = zLook; + + dest->m[Matrix_getIndex(0, 3)] = -x; + dest->m[Matrix_getIndex(1, 3)] = -y; + dest->m[Matrix_getIndex(2, 3)] = -z; + + return dest; +} + +static inline Matrix4f* Matrix4f_Orthographic(Matrix4f* dest, float width, float height, float zfar, float znear) { + + memset(dest->m, 0, sizeof(dest->m)); + dest->m[Matrix_getIndex(0,0)] = 2.0f / width; + dest->m[Matrix_getIndex(1,1)] = 2.0f / height; + dest->m[Matrix_getIndex(2,2)] = 1.0f / (zfar - znear); + dest->m[Matrix_getIndex(3,3)] = 1.0f; + + dest->m[Matrix_getIndex(2,3)] = znear / (znear - zfar); + + return dest; +} + // ===[ Orthographic Projection ]=== // Post-multiply orthographic projection onto dest: dest = dest * ortho(l, r, b, t, n, f) diff --git a/src/runner.c b/src/runner.c index d5b50ffa7..f5de60062 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1023,6 +1023,19 @@ void Runner_drawGUI(Runner* runner, int32_t windowW, int32_t windowH, int32_t ta int32_t guiW = runner->guiWidth > 0 ? runner->guiWidth : targetW; int32_t guiH = runner->guiHeight > 0 ? runner->guiHeight : targetH; beginGuiPass(runner, guiW, guiH, windowW, windowH, RENDER_TARGET_HOST_FRAMEBUFFER); + + //make default projection + Matrix4f Projection; + Matrix4f_Orthographic(&Projection, (float) guiW, (float) guiH, 32000.0, 0.0); + + Matrix4f View; + float x = (float) guiW / 2; + float y = (float) guiH / 2; + Matrix4f_identity(&View); + Matrix4f_LookAt(&View, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + + runner->renderer->vtable->applyProjection(runner->renderer, &View, &Projection); + fireDrawSubtype(runner, drawables, drawableCount, DRAW_GUI_BEGIN); fireDrawSubtype(runner, drawables, drawableCount, DRAW_GUI); fireDrawSubtype(runner, drawables, drawableCount, DRAW_GUI_END); @@ -1166,6 +1179,11 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh runner->viewCurrent = (int32_t) vi; renderer->vtable->beginView(renderer, viewX, viewY, viewW, viewH, portX, portY, portW, portH, viewAngle); + Matrix4f ViewMatrix = camera->ViewMatrix; + Matrix4f ProjectionMatrix = camera->ProjectionMatrix; + //what am I even doing. + runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); + Runner_draw(runner); if (debugShowCollisionMasks) DebugOverlay_drawCollisionMasks(runner); @@ -1184,6 +1202,18 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh expandViewAxis(0, (int32_t) runner->currentRoom->height, gameH, widescreenBaseH, &viewY, &viewH); applyFreeCamera(runner, &viewX, &viewY, &viewW, &viewH); renderer->vtable->beginView(renderer, viewX, viewY, viewW, viewH, 0, 0, gameW, gameH, 0); + + //make default projection + Matrix4f Projection; + Matrix4f_Orthographic(&Projection, (float) gameW, (float) -gameH, 32000.0, 0.0); + + Matrix4f View; + float x = (float) gameW /2; + float y = (float) gameH /2; + Matrix4f_identity(&View); + Matrix4f_LookAt(&View, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + + runner->renderer->vtable->applyProjection(runner->renderer, &View, &Projection); Runner_draw(runner); if (debugShowCollisionMasks) DebugOverlay_drawCollisionMasks(runner); @@ -1318,6 +1348,23 @@ static void initDefaultCameraFromRoomView(GMLCamera* camera, RoomView* roomView) camera->speedY = roomView->speedY; camera->objectId = roomView->objectId; camera->viewAngle = 0; + //make default projection + Matrix4f Projection; + Matrix4f_Orthographic(&Projection, (float) camera->viewWidth, (float) -camera->viewHeight, 32000.0, 0.0); + + Matrix4f View; + float x = camera->viewX + camera->viewWidth/2; + float y = camera->viewY + camera->viewHeight/2; + Matrix4f_identity(&View); + Matrix4f_LookAt(&View, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + Matrix4f_translate(&View, x, y, 0.0f); + Matrix4f_rotateZ(&View, -camera->viewAngle * (float) M_PI / 180.0f); + Matrix4f_translate(&View, -x, -y, 0.0f); + + + + camera->ProjectionMatrix = Projection; + camera->ViewMatrix = View; } // Copies the viewport (port) properties and enabled flag from parsed room data. diff --git a/src/runner.h b/src/runner.h index 873b7efd8..7cb2b7a1d 100644 --- a/src/runner.h +++ b/src/runner.h @@ -145,8 +145,8 @@ typedef struct { typedef struct { bool allocated; // slot in use (default cameras: set when the room enables the view; user cameras: camera_create/destroy) - int32_t viewX; - int32_t viewY; + float viewX; + float viewY; int32_t viewWidth; int32_t viewHeight; uint32_t borderX; diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 3ad434b8f..be2e7549d 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -216,6 +216,21 @@ static DsStack* dsStackGet(Runner* runner, int32_t id) { return &runner->dsStackPool[id]; } +static void UpdateCamera(GMLCamera* camera) { + + float x = camera->viewX + camera->viewWidth/2; + float y = camera->viewY + camera->viewHeight/2; + Matrix4f ViewMatrix; + Matrix4f_identity(&ViewMatrix); + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + Matrix4f_translate(&ViewMatrix, x, y, 0.0f); + Matrix4f_rotateZ(&ViewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); + Matrix4f_translate(&ViewMatrix, -x, -y, 0.0f); + camera->ViewMatrix = ViewMatrix; + +} + + // ===[ BUILT-IN VARIABLE GET/SET ]=== static bool isValidAlarmIndex(int alarmIndex) { @@ -1551,22 +1566,34 @@ void VMBuiltins_setVariable(VMContext* ctx, Instance* inst, int16_t builtinVarId // View properties case BUILTIN_VAR_VIEW_XVIEW: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); - if (camera != nullptr) camera->viewX = RValue_toInt32(val); + if (camera != nullptr) { + camera->viewX = RValue_toReal(val); + UpdateCamera(camera); + } return; } case BUILTIN_VAR_VIEW_YVIEW: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); - if (camera != nullptr) camera->viewY = RValue_toInt32(val); + if (camera != nullptr) { + camera->viewY = RValue_toInt32(val); + UpdateCamera(camera); + } return; } case BUILTIN_VAR_VIEW_WVIEW: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); - if (camera != nullptr) camera->viewWidth = RValue_toInt32(val); + if (camera != nullptr) { + camera->viewWidth = RValue_toInt32(val); + UpdateCamera(camera); + } return; } case BUILTIN_VAR_VIEW_HVIEW: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); - if (camera != nullptr) camera->viewHeight = RValue_toInt32(val); + if (camera != nullptr) { + camera->viewHeight = RValue_toInt32(val); + UpdateCamera(camera); + } return; } case BUILTIN_VAR_VIEW_XPORT: @@ -1592,7 +1619,10 @@ void VMBuiltins_setVariable(VMContext* ctx, Instance* inst, int16_t builtinVarId return; case BUILTIN_VAR_VIEW_ANGLE: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); - if (camera != nullptr) camera->viewAngle = (float) RValue_toReal(val); + if (camera != nullptr) { + camera->viewAngle = (float) RValue_toReal(val); + UpdateCamera(camera); + } return; } case BUILTIN_VAR_VIEW_HBORDER: { @@ -2847,14 +2877,7 @@ static RValue builtin_matrix_build_projection_ortho(MAYBE_UNUSED VMContext *ctx, if (toPrevMatrix && !rvalueIsMatrix(args[4])) return RValue_makeUndefined(); Matrix4f mat; - - memset(mat.m, 0, sizeof(mat.m)); - mat.m[Matrix_getIndex(0,0)] = 2.0f / width; - mat.m[Matrix_getIndex(1,1)] = 2.0f / height; - mat.m[Matrix_getIndex(2,2)] = 1.0f / (zfar - znear); - mat.m[Matrix_getIndex(3,3)] = 1.0f; - - mat.m[Matrix_getIndex(2,3)] = znear / (znear - zfar); + Matrix4f_Orthographic(&mat, width, height, zfar, znear); if (!toPrevMatrix) { return RValue_makeArray(matrixToGml(ctx->dataWin->gen8.wadVersion, &mat)); @@ -2907,7 +2930,7 @@ static RValue builtin_matrix_set(MAYBE_UNUSED VMContext *ctx, RValue *args, int3 int32_t Matrix = RValue_toInt32(args[0]); Matrix4f m; matrixFromGml(&m, args[1].array); - //return RValue_makeArray(matrixToGml(&ctx->runner->renderer->gmlMatrices[Matrix])); + //add safe guards or whatever itis if (ctx->runner->renderer != nullptr) { ctx->runner->renderer->vtable->setMatrix(ctx->runner->renderer, Matrix, m); } @@ -2915,7 +2938,6 @@ static RValue builtin_matrix_set(MAYBE_UNUSED VMContext *ctx, RValue *args, int3 return RValue_makeUndefined(); } - static RValue builtin_matrix_build_lookat(MAYBE_UNUSED VMContext *ctx, RValue *args, int32_t argCount) { if (argCount < 9 || argCount > 10) return RValue_makeUndefined(); @@ -2930,60 +2952,11 @@ static RValue builtin_matrix_build_lookat(MAYBE_UNUSED VMContext *ctx, RValue *a GMLReal xUp = RValue_toReal(args[6]); GMLReal yUp = RValue_toReal(args[7]); GMLReal zUp = RValue_toReal(args[8]); - GMLReal magUp = GMLReal_sqrt(xUp * xUp + yUp * yUp + zUp * zUp); - xUp /= magUp; - yUp /= magUp; - zUp /= magUp; - - GMLReal xLook = xTo - xFrom; - GMLReal yLook = yTo - yFrom; - GMLReal zLook = zTo - zFrom; - GMLReal magLook = GMLReal_sqrt(xLook * xLook + yLook * yLook + zLook * zLook); - xLook /= magLook; - yLook /= magLook; - zLook /= magLook; - - // normalised cross product between Up and Look - GMLReal xRight = yUp * zLook - zUp * yLook; - GMLReal yRight = zUp * xLook - xUp * zLook; - GMLReal zRight = xUp * yLook - yUp * xLook; - GMLReal magRight = GMLReal_sqrt(xRight * xRight + yRight * yRight + zRight * zRight); - xRight /= magRight; - yRight /= magRight; - zRight /= magRight; - - // normalised cross product between Look and Right - xUp = yLook * zRight - zLook * yRight; - yUp = zLook * xRight - xLook * zRight; - zUp = xLook * yRight - yLook * xRight; - magUp = GMLReal_sqrt(xUp * xUp + yUp * yUp + zUp * zUp); - xUp /= magUp; - yUp /= magUp; - zUp /= magUp; - - GMLReal x, y, z; - x = xFrom * xRight + yFrom * yRight + zFrom * zRight; - y = xFrom * xUp + yFrom * yUp + zFrom * zUp; - z = xFrom * xLook + yFrom * yLook + zFrom * zLook; Matrix4f matrix; Matrix4f_identity(&matrix); - matrix.m[Matrix_getIndex(0, 0)] = xRight; - matrix.m[Matrix_getIndex(1, 0)] = xUp; - matrix.m[Matrix_getIndex(2, 0)] = xLook; - - matrix.m[Matrix_getIndex(0, 1)] = yRight; - matrix.m[Matrix_getIndex(1, 1)] = yUp; - matrix.m[Matrix_getIndex(2, 1)] = yLook; - - matrix.m[Matrix_getIndex(0, 2)] = zRight; - matrix.m[Matrix_getIndex(1, 2)] = zUp; - matrix.m[Matrix_getIndex(2, 2)] = zLook; - - matrix.m[Matrix_getIndex(0, 3)] = -x; - matrix.m[Matrix_getIndex(1, 3)] = -y; - matrix.m[Matrix_getIndex(2, 3)] = -z; + Matrix4f_LookAt(&matrix, xFrom, yFrom, zFrom, xTo, yTo, zTo, xUp, yUp, zUp); bool toPrevMatrix = argCount == 10; GMLArray *destArray = toPrevMatrix ? args[9].array : nullptr; @@ -3486,8 +3459,17 @@ static RValue builtin_camera_set_view_pos(VMContext* ctx, RValue* args, int32_t Runner* runner = ctx->runner; GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); if (camera != nullptr) { - camera->viewX = RValue_toInt32(args[1]); - camera->viewY = RValue_toInt32(args[2]); + camera->viewX = RValue_toReal(args[1]); + camera->viewY = RValue_toReal(args[2]); + float x = camera->viewX + camera->viewWidth/2; + float y = camera->viewY + camera->viewHeight/2; + Matrix4f ViewMatrix; + Matrix4f_identity(&ViewMatrix); + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + Matrix4f_translate(&ViewMatrix, x, y, 0.0f); + Matrix4f_rotateZ(&ViewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); + Matrix4f_translate(&ViewMatrix, -x, -y, 0.0f); + camera->ViewMatrix = ViewMatrix; } return RValue_makeUndefined(); } @@ -3604,7 +3586,19 @@ static RValue builtin_camera_set_view_angle(VMContext* ctx, RValue* args, int32_ if (2 > argCount) return RValue_makeUndefined(); Runner* runner = ctx->runner; GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); - if (camera != nullptr) camera->viewAngle = (float) RValue_toReal(args[1]); + if (camera != nullptr) + { + camera->viewAngle = (float) RValue_toReal(args[1]); + float x = camera->viewX + camera->viewWidth/2; + float y = camera->viewY + camera->viewHeight/2; + Matrix4f ViewMatrix; + Matrix4f_identity(&ViewMatrix); + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + Matrix4f_translate(&ViewMatrix, x, y, 0.0f); + Matrix4f_rotateZ(&ViewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); + Matrix4f_translate(&ViewMatrix, -x, -y, 0.0f); + camera->ViewMatrix = ViewMatrix; + } return RValue_makeUndefined(); } @@ -3657,8 +3651,8 @@ static RValue builtin_camera_create_view(VMContext* ctx, RValue* args, int32_t a if (0 > id) return RValue_makeReal(-1); GMLCamera* camera = Runner_getCameraById(runner, id); // camera_create_view(room_x, room_y, room_w, room_h, [angle, object, x_speed, y_speed, x_border, y_border]) - if (argCount > 0) camera->viewX = RValue_toInt32(args[0]); - if (argCount > 1) camera->viewY = RValue_toInt32(args[1]); + if (argCount > 0) camera->viewX = RValue_toReal(args[0]); + if (argCount > 1) camera->viewY = RValue_toReal(args[1]); if (argCount > 2) camera->viewWidth = RValue_toInt32(args[2]); if (argCount > 3) camera->viewHeight = RValue_toInt32(args[3]); if (argCount > 4) camera->viewAngle = (float) RValue_toReal(args[4]); @@ -3668,83 +3662,19 @@ static RValue builtin_camera_create_view(VMContext* ctx, RValue* args, int32_t a if (argCount > 8) camera->borderX = (uint32_t) RValue_toInt32(args[8]); if (argCount > 9) camera->borderY = (uint32_t) RValue_toInt32(args[9]); - //what have I done. - Matrix4f Projection; - memset(Projection.m, 0, sizeof(Projection.m)); - Projection.m[Matrix_getIndex(0,0)] = 2.0f / RValue_toReal(args[2]); - Projection.m[Matrix_getIndex(1,1)] = 2.0f / RValue_toReal(args[3]); - Projection.m[Matrix_getIndex(2,2)] = 1.0f / (32000.0 - 0.0); - Projection.m[Matrix_getIndex(3,3)] = 1.0f; - Projection.m[Matrix_getIndex(2,3)] = 0.0 / (0.0 - 32000.0); + Matrix4f Projection; + Matrix4f_Orthographic(&Projection, camera->viewWidth, -camera->viewHeight, 32000.0, 0.0); camera->ProjectionMatrix = Projection; + //we will look at the center, okay? + float x = RValue_toReal(args[0]) + RValue_toReal(args[2])/2; + float y = RValue_toReal(args[1]) + RValue_toReal(args[3])/2; - GMLReal xFrom = RValue_toReal(args[0]) + RValue_toReal(args[2])/2.0f; - GMLReal yFrom = RValue_toReal(args[1]) + RValue_toReal(args[3])/2.0f; - GMLReal zFrom = -16000.0; - - GMLReal xTo = RValue_toReal(args[0]) + RValue_toReal(args[2])/2.0f; - GMLReal yTo = RValue_toReal(args[1]) + RValue_toReal(args[3])/2.0f; - GMLReal zTo = 16000.0; - - GMLReal xUp = 0.0; - GMLReal yUp = 1.0; - GMLReal zUp = 0.0; - GMLReal magUp = GMLReal_sqrt(xUp * xUp + yUp * yUp + zUp * zUp); - xUp /= magUp; - yUp /= magUp; - zUp /= magUp; - - GMLReal xLook = xTo - xFrom; - GMLReal yLook = yTo - yFrom; - GMLReal zLook = zTo - zFrom; - GMLReal magLook = GMLReal_sqrt(xLook * xLook + yLook * yLook + zLook * zLook); - xLook /= magLook; - yLook /= magLook; - zLook /= magLook; - - // normalised cross product between Up and Look - GMLReal xRight = yUp * zLook - zUp * yLook; - GMLReal yRight = zUp * xLook - xUp * zLook; - GMLReal zRight = xUp * yLook - yUp * xLook; - GMLReal magRight = GMLReal_sqrt(xRight * xRight + yRight * yRight + zRight * zRight); - xRight /= magRight; - yRight /= magRight; - zRight /= magRight; - - // normalised cross product between Look and Right - xUp = yLook * zRight - zLook * yRight; - yUp = zLook * xRight - xLook * zRight; - zUp = xLook * yRight - yLook * xRight; - magUp = GMLReal_sqrt(xUp * xUp + yUp * yUp + zUp * zUp); - xUp /= magUp; - yUp /= magUp; - zUp /= magUp; - - GMLReal x, y, z; - x = xFrom * xRight + yFrom * yRight + zFrom * zRight; - y = xFrom * xUp + yFrom * yUp + zFrom * zUp; - z = xFrom * xLook + yFrom * yLook + zFrom * zLook; - Matrix4f ViewMatrix; Matrix4f_identity(&ViewMatrix); - ViewMatrix.m[Matrix_getIndex(0, 0)] = xRight; - ViewMatrix.m[Matrix_getIndex(1, 0)] = xUp; - ViewMatrix.m[Matrix_getIndex(2, 0)] = xLook; - - ViewMatrix.m[Matrix_getIndex(0, 1)] = yRight; - ViewMatrix.m[Matrix_getIndex(1, 1)] = yUp; - ViewMatrix.m[Matrix_getIndex(2, 1)] = yLook; - - ViewMatrix.m[Matrix_getIndex(0, 2)] = zRight; - ViewMatrix.m[Matrix_getIndex(1, 2)] = zUp; - ViewMatrix.m[Matrix_getIndex(2, 2)] = zLook; - - ViewMatrix.m[Matrix_getIndex(0, 3)] = -x; - ViewMatrix.m[Matrix_getIndex(1, 3)] = -y; - ViewMatrix.m[Matrix_getIndex(2, 3)] = -z; + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); camera->ViewMatrix = ViewMatrix; //builtin_matrix_build_lookat(ctx,args[0],args[1],RValue_makeReal(-16000.0),args[0],args[1],RValue_makeReal(16000.0), RValue_makeReal(0.0),RValue_makeReal(1.0),RValue_makeReal(0.0)) From 99a7444db4e44f60831c698c7b30138c6f14eff6 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Sat, 13 Jun 2026 20:09:53 +0200 Subject: [PATCH 06/21] clean up a little bit --- src/gl/gl_renderer.c | 2 +- src/runner.h | 1 - src/vm_builtins.c | 23 ++--------------------- 3 files changed, 3 insertions(+), 23 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index affdfed76..d8b9454dc 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -59,7 +59,7 @@ static const char* defaultFragmentShaderSource = "uniform sampler2D uTexture;\n" "uniform float uAlphaTestRef;\n" "uniform bool uAlphaTestEnabled;\n" -"uniform vec4 uFogColor;\n" // rgb = fog color, a = enable flag (0 or 1) + "uniform vec4 uFogColor;\n" // rgb = fog color, a = enable flag (0 or 1) "out vec4 fragColor;\n" "void main() {\n" " vec4 c = texture(uTexture, vTexCoord) * vColor;\n" diff --git a/src/runner.h b/src/runner.h index 7cb2b7a1d..3790c4f5b 100644 --- a/src/runner.h +++ b/src/runner.h @@ -155,7 +155,6 @@ typedef struct { int32_t speedY; int32_t objectId; // follow target (object index), -1 = none float viewAngle; - Matrix4f ViewMatrix; Matrix4f ProjectionMatrix; } GMLCamera; diff --git a/src/vm_builtins.c b/src/vm_builtins.c index be2e7549d..ffdebaafa 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -3461,15 +3461,7 @@ static RValue builtin_camera_set_view_pos(VMContext* ctx, RValue* args, int32_t if (camera != nullptr) { camera->viewX = RValue_toReal(args[1]); camera->viewY = RValue_toReal(args[2]); - float x = camera->viewX + camera->viewWidth/2; - float y = camera->viewY + camera->viewHeight/2; - Matrix4f ViewMatrix; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - Matrix4f_translate(&ViewMatrix, x, y, 0.0f); - Matrix4f_rotateZ(&ViewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); - Matrix4f_translate(&ViewMatrix, -x, -y, 0.0f); - camera->ViewMatrix = ViewMatrix; + UpdateCamera(camera); } return RValue_makeUndefined(); } @@ -3591,13 +3583,7 @@ static RValue builtin_camera_set_view_angle(VMContext* ctx, RValue* args, int32_ camera->viewAngle = (float) RValue_toReal(args[1]); float x = camera->viewX + camera->viewWidth/2; float y = camera->viewY + camera->viewHeight/2; - Matrix4f ViewMatrix; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - Matrix4f_translate(&ViewMatrix, x, y, 0.0f); - Matrix4f_rotateZ(&ViewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); - Matrix4f_translate(&ViewMatrix, -x, -y, 0.0f); - camera->ViewMatrix = ViewMatrix; + UpdateCamera(camera); } return RValue_makeUndefined(); } @@ -3673,14 +3659,9 @@ static RValue builtin_camera_create_view(VMContext* ctx, RValue* args, int32_t a Matrix4f ViewMatrix; Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); camera->ViewMatrix = ViewMatrix; - //builtin_matrix_build_lookat(ctx,args[0],args[1],RValue_makeReal(-16000.0),args[0],args[1],RValue_makeReal(16000.0), RValue_makeReal(0.0),RValue_makeReal(1.0),RValue_makeReal(0.0)) - //builtin_matrix_build_projection_ortho(ctx,args[2], args[3], RValue_makeReal(0.0), RValue_makeReal(32000.0)); - - return RValue_makeReal(id); } From aeac57702ca97eefc292e306a67836d1a7edba04 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Sun, 14 Jun 2026 11:43:40 +0200 Subject: [PATCH 07/21] make rendering to surfaces work in a hacky way --- src/gl/gl_renderer.c | 46 +++++++++++++++++++++++++++------------- src/renderer.h | 4 ++++ src/runner.c | 50 +++++++++++++++++++++++++++++++------------- src/vm_builtins.c | 13 +----------- 4 files changed, 71 insertions(+), 42 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index d8b9454dc..8dff402ba 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -570,9 +570,7 @@ static void glApplyProjection(Renderer* renderer, const Matrix4f* ViewMatrix,con renderer->gmlMatrices[MATRIX_WORLD_VIEW] = WorldView; renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = WorldViewProjection; //oh my I hope it's good enough. - glShaderSettingsRefresh(renderer); - renderer->previousViewMatrix = WorldViewProjection; - + glShaderSettingsRefresh(renderer); } static void glBeginGUI(Renderer* renderer, int32_t guiW, int32_t guiH, int32_t portX, int32_t portY, int32_t portW, int32_t portH, int32_t targetSurfaceId) { @@ -596,10 +594,10 @@ static void glBeginGUI(Renderer* renderer, int32_t guiW, int32_t guiH, int32_t p glEnable(GL_SCISSOR_TEST); - Matrix4f projection; - Matrix4f_guiProjection(&projection, (float) guiW, (float) guiH, (float) portW, (float) portH); - Matrix4f_flipClipY(&projection); - renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; + //Matrix4f projection; + //Matrix4f_guiProjection(&projection, (float) guiW, (float) guiH, (float) portW, (float) portH); + //Matrix4f_flipClipY(&projection); + //renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; glShaderSettingsRefresh(renderer); glActiveTexture(GL_TEXTURE1); @@ -660,11 +658,11 @@ static void glClearScreen(Renderer* renderer, uint32_t color, float alpha) { float b = (float) BGR_B(color) / 255.0f; // GML draw_clear ignores the active scissor and clears the whole target. Disable scissor for the clear and restore it after. - GLboolean scissorWasEnabled = glIsEnabled(GL_SCISSOR_TEST); - if (scissorWasEnabled) glDisable(GL_SCISSOR_TEST); + //GLboolean scissorWasEnabled = glIsEnabled(GL_SCISSOR_TEST); + //if (scissorWasEnabled) glDisable(GL_SCISSOR_TEST); glClearColor(r, g, b, alpha); glClear(GL_COLOR_BUFFER_BIT); - if (scissorWasEnabled) glEnable(GL_SCISSOR_TEST); + //if (scissorWasEnabled) glEnable(GL_SCISSOR_TEST); } // Lazily decodes and uploads a TXTR page on first access. @@ -1988,18 +1986,36 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic if (surfaceId == renderer->runner->applicationSurfaceId && implicitApplicationSurface) { glViewport(gl->base.CPortX, gl->base.CPortY, gl->base.CPortW, gl->base.CPortH); glEnable(GL_SCISSOR_TEST); - renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = renderer->previousViewMatrix; + glApplyProjection(renderer, &renderer->V_ViewMatrix,&renderer->V_ProjectionMatrix); glShaderSettingsRefresh(renderer); return true; } // Normal surface bind: surface-local ortho covering the whole surface, no scissor. - Matrix4f projection; - Matrix4f_identity(&projection); - Matrix4f_ortho(&projection, 0.0f, (float) gl->surfaceWidth[surfaceId], (float) gl->surfaceHeight[surfaceId], 0.0f, -1.0f, 1.0f); + //Matrix4f projection; + //Matrix4f_identity(&projection); + //Matrix4f_ortho(&projection, 0.0f, (float) gl->surfaceWidth[surfaceId], (float) gl->surfaceHeight[surfaceId], 0.0f, -1.0f, 1.0f); + //glViewport(0, 0, gl->surfaceWidth[surfaceId], gl->surfaceHeight[surfaceId]); + //glDisable(GL_SCISSOR_TEST); + //renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; + if (surfaceId == renderer->V_SurfaceID) { + glApplyProjection(renderer, &renderer->V_ViewMatrix,&renderer->V_ProjectionMatrix); + + } else { + Matrix4f ProjectionMatrix; + Matrix4f_Orthographic(&ProjectionMatrix, (float) gl->surfaceWidth[surfaceId], (float) -gl->surfaceHeight[surfaceId], 32000.0, 0.0); + + Matrix4f ViewMatrix; + float x = (float) gl->surfaceWidth[surfaceId] /2; + float y = (float) gl->surfaceHeight[surfaceId] /2; + Matrix4f_identity(&ViewMatrix); + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + glApplyProjection(renderer, &ViewMatrix,&ProjectionMatrix); + } + + glViewport(0, 0, gl->surfaceWidth[surfaceId], gl->surfaceHeight[surfaceId]); glDisable(GL_SCISSOR_TEST); - renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; glShaderSettingsRefresh(renderer); return true; diff --git a/src/renderer.h b/src/renderer.h index f9cb3a308..4e321c1c8 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -8,6 +8,7 @@ #include "data_win.h" #include "instance.h" + // GameMaker Blend Modes #define bm_complex -1 @@ -172,6 +173,9 @@ struct Renderer { Runner* runner; Matrix4f gmlMatrices[MATRICES_MAX]; int32_t currentShader; + Matrix4f V_ViewMatrix; + Matrix4f V_ProjectionMatrix; + int32_t V_SurfaceID; }; // ===[ Shared Helpers (platform-agnostic) ]=== diff --git a/src/runner.c b/src/runner.c index f5de60062..197b1ee66 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1025,16 +1025,19 @@ void Runner_drawGUI(Runner* runner, int32_t windowW, int32_t windowH, int32_t ta beginGuiPass(runner, guiW, guiH, windowW, windowH, RENDER_TARGET_HOST_FRAMEBUFFER); //make default projection - Matrix4f Projection; - Matrix4f_Orthographic(&Projection, (float) guiW, (float) guiH, 32000.0, 0.0); + Matrix4f ProjectionMatrix; + Matrix4f_Orthographic(&ProjectionMatrix, (float) guiW, (float) guiH, 32000.0, 0.0); - Matrix4f View; + Matrix4f ViewMatrix; float x = (float) guiW / 2; float y = (float) guiH / 2; - Matrix4f_identity(&View); - Matrix4f_LookAt(&View, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + Matrix4f_identity(&ViewMatrix); + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - runner->renderer->vtable->applyProjection(runner->renderer, &View, &Projection); + runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); + runner->renderer->V_ViewMatrix = ViewMatrix; + runner->renderer->V_ProjectionMatrix = ProjectionMatrix; + runner->renderer->V_SurfaceID = -1; fireDrawSubtype(runner, drawables, drawableCount, DRAW_GUI_BEGIN); fireDrawSubtype(runner, drawables, drawableCount, DRAW_GUI); @@ -1152,7 +1155,9 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh Matrix4f ViewMatrix = camera->ViewMatrix; Matrix4f ProjectionMatrix = camera->ProjectionMatrix; - + renderer->V_ViewMatrix = ViewMatrix; + renderer->V_ProjectionMatrix = ProjectionMatrix; + renderer->V_SurfaceID = view->surfaceId; runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); @@ -1181,7 +1186,9 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh Matrix4f ViewMatrix = camera->ViewMatrix; Matrix4f ProjectionMatrix = camera->ProjectionMatrix; - //what am I even doing. + renderer->V_ViewMatrix = ViewMatrix; + renderer->V_ProjectionMatrix = ProjectionMatrix; + renderer->V_SurfaceID = -1; runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); Runner_draw(runner); @@ -1204,16 +1211,23 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh renderer->vtable->beginView(renderer, viewX, viewY, viewW, viewH, 0, 0, gameW, gameH, 0); //make default projection - Matrix4f Projection; - Matrix4f_Orthographic(&Projection, (float) gameW, (float) -gameH, 32000.0, 0.0); + Matrix4f ProjectionMatrix; + Matrix4f_Orthographic(&ProjectionMatrix, (float) gameW, (float) -gameH, 32000.0, 0.0); - Matrix4f View; + Matrix4f ViewMatrix; float x = (float) gameW /2; float y = (float) gameH /2; - Matrix4f_identity(&View); - Matrix4f_LookAt(&View, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - - runner->renderer->vtable->applyProjection(runner->renderer, &View, &Projection); + Matrix4f_identity(&ViewMatrix); + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + renderer->V_ViewMatrix = ViewMatrix; + renderer->V_ProjectionMatrix = ProjectionMatrix; + if (camera != nullptr) { + camera->ViewMatrix = ViewMatrix; + camera->ProjectionMatrix = ProjectionMatrix; + } + + renderer->V_SurfaceID = -1; + runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); Runner_draw(runner); if (debugShowCollisionMasks) DebugOverlay_drawCollisionMasks(runner); @@ -3929,6 +3943,9 @@ bool Runner_surfaceSetTarget(Runner* runner, int32_t surfaceID) { runner->surfaceStack[slot] = surfaceID; runner->renderer->vtable->flush(runner->renderer); + GMLCamera* camera = Runner_getCameraForView(runner, (int32_t) runner->viewCurrent); + runner->renderer->V_ProjectionMatrix = camera->ProjectionMatrix; + runner->renderer->V_ViewMatrix = camera->ViewMatrix; return runner->renderer->vtable->setRenderTarget(runner->renderer, surfaceID, false); } @@ -3943,6 +3960,9 @@ bool Runner_surfaceResetTarget(Runner* runner) { int32_t newTop = findStackTop(runner); int32_t newTarget = newTop == -1 ? runner->applicationSurfaceId : runner->surfaceStack[newTop]; + GMLCamera* camera = Runner_getCameraForView(runner, (int32_t) runner->viewCurrent); + runner->renderer->V_ProjectionMatrix = camera->ProjectionMatrix; + runner->renderer->V_ViewMatrix = camera->ViewMatrix; runner->renderer->vtable->setRenderTarget(runner->renderer, newTarget, newTop == -1); if (newTop == -1 && runner->inGuiPass) { // Inside Pre Draw / Post Draw / Draw GUI the base target is the GUI pass target with the GUI projection, not the room view. diff --git a/src/vm_builtins.c b/src/vm_builtins.c index ffdebaafa..96f61433f 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -3649,18 +3649,7 @@ static RValue builtin_camera_create_view(VMContext* ctx, RValue* args, int32_t a if (argCount > 9) camera->borderY = (uint32_t) RValue_toInt32(args[9]); - Matrix4f Projection; - Matrix4f_Orthographic(&Projection, camera->viewWidth, -camera->viewHeight, 32000.0, 0.0); - camera->ProjectionMatrix = Projection; - //we will look at the center, okay? - float x = RValue_toReal(args[0]) + RValue_toReal(args[2])/2; - float y = RValue_toReal(args[1]) + RValue_toReal(args[3])/2; - - - Matrix4f ViewMatrix; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - camera->ViewMatrix = ViewMatrix; + UpdateCamera(camera); return RValue_makeReal(id); } From 478fadf82a117068af093f2fa8175dc8f402eab7 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Sun, 14 Jun 2026 15:04:47 +0200 Subject: [PATCH 08/21] add and remove some comments --- src/gl/gl_renderer.c | 10 ++-------- src/renderer.h | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index 8dff402ba..fab730451 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -1991,16 +1991,10 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic return true; } - // Normal surface bind: surface-local ortho covering the whole surface, no scissor. - //Matrix4f projection; - //Matrix4f_identity(&projection); - //Matrix4f_ortho(&projection, 0.0f, (float) gl->surfaceWidth[surfaceId], (float) gl->surfaceHeight[surfaceId], 0.0f, -1.0f, 1.0f); - //glViewport(0, 0, gl->surfaceWidth[surfaceId], gl->surfaceHeight[surfaceId]); - //glDisable(GL_SCISSOR_TEST); - //renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; + if (surfaceId == renderer->V_SurfaceID) { + //we go back to the camera's settings for this glApplyProjection(renderer, &renderer->V_ViewMatrix,&renderer->V_ProjectionMatrix); - } else { Matrix4f ProjectionMatrix; Matrix4f_Orthographic(&ProjectionMatrix, (float) gl->surfaceWidth[surfaceId], (float) -gl->surfaceHeight[surfaceId], 32000.0, 0.0); diff --git a/src/renderer.h b/src/renderer.h index 4e321c1c8..4325322ef 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -165,7 +165,7 @@ struct Renderer { int32_t drawValign; // 0=top, 1=middle, 2=bottom int32_t circlePrecision; // segments used by draw_circle/draw_ellipse, clamped to [4, 64] and rounded down to multiple of 4. Default 24. //It's The Simplest Way I Found To Restore Previous Thingies For Rendering SORRY - Matrix4f previousViewMatrix; + Matrix4f previousViewMatrix; //when you go fix the Legacy OpenGL renderer, please remove this, as we don't need this anymore I hope int32_t CPortX; int32_t CPortY; int32_t CPortW; From 7e1fc9b8e479ba9a7844e4f177acedf51139370a Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Sun, 14 Jun 2026 20:47:16 +0200 Subject: [PATCH 09/21] I think I've made spaghetti --- src/gl/gl_renderer.c | 22 ++++++++++++++++++++++ src/renderer.h | 3 +++ src/runner.c | 4 ++++ src/runner.h | 1 + src/vm_builtins.c | 9 ++++++++- 5 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index fab730451..08641b106 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -1987,6 +1987,7 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic glViewport(gl->base.CPortX, gl->base.CPortY, gl->base.CPortW, gl->base.CPortH); glEnable(GL_SCISSOR_TEST); glApplyProjection(renderer, &renderer->V_ViewMatrix,&renderer->V_ProjectionMatrix); + gl->base.CameraCurrent = renderer->runner->viewCurrent; glShaderSettingsRefresh(renderer); return true; } @@ -1995,6 +1996,7 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic if (surfaceId == renderer->V_SurfaceID) { //we go back to the camera's settings for this glApplyProjection(renderer, &renderer->V_ViewMatrix,&renderer->V_ProjectionMatrix); + gl->base.CameraCurrent = renderer->runner->viewCurrent; } else { Matrix4f ProjectionMatrix; Matrix4f_Orthographic(&ProjectionMatrix, (float) gl->surfaceWidth[surfaceId], (float) -gl->surfaceHeight[surfaceId], 32000.0, 0.0); @@ -2005,6 +2007,24 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic Matrix4f_identity(&ViewMatrix); Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); glApplyProjection(renderer, &ViewMatrix,&ProjectionMatrix); + gl->base.CameraCurrent = SURFACE_CAMERA; + + GMLCamera* camera = &renderer->runner->surfaceCamera; + + camera->allocated = true; + camera->viewX = 0.0; + camera->viewY = 0.0; + camera->viewWidth = gl->surfaceWidth[surfaceId]; + camera->viewHeight = gl->surfaceHeight[surfaceId]; + camera->borderX = 0; + camera->borderY = 0; + camera->speedX = 0; + camera->speedY = 0; + camera->objectId = -1; + camera->viewAngle = 0; + + camera->ProjectionMatrix = ProjectionMatrix; + camera->ViewMatrix = ViewMatrix; } @@ -2603,5 +2623,7 @@ Renderer* GLRenderer_create(void) { gl->base.drawValign = 0; gl->base.circlePrecision = 24; gl->base.currentShader = -1; + gl->base.V_SurfaceID = -1; + gl->base.CameraCurrent = 0; return (Renderer*) gl; } diff --git a/src/renderer.h b/src/renderer.h index 4325322ef..1c6b07e7e 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -42,6 +42,8 @@ #define MAX_TEXTURE_STAGES 8 +#define SURFACE_CAMERA 8192 + // Sentinel returned by ensureApplicationSurface on platforms that don't back the application_surface with a real entry in the renderer's surface table. // // Also used as the initial value of Runner.applicationSurfaceId before the first ensure call. @@ -176,6 +178,7 @@ struct Renderer { Matrix4f V_ViewMatrix; Matrix4f V_ProjectionMatrix; int32_t V_SurfaceID; + int32_t CameraCurrent; }; // ===[ Shared Helpers (platform-agnostic) ]=== diff --git a/src/runner.c b/src/runner.c index 197b1ee66..b4ce4db63 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1162,6 +1162,7 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh runner->viewCurrent = (int32_t) vi; + runner->renderer->CameraCurrent = runner->viewCurrent; Runner_draw(runner); renderer->vtable->flush(renderer); @@ -1182,6 +1183,7 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh float viewAngle = camera->viewAngle; runner->viewCurrent = (int32_t) vi; + runner->renderer->CameraCurrent = runner->viewCurrent; renderer->vtable->beginView(renderer, viewX, viewY, viewW, viewH, portX, portY, portW, portH, viewAngle); Matrix4f ViewMatrix = camera->ViewMatrix; @@ -1238,6 +1240,7 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh // Reset view_current to 0 so non-Draw events (Step, Alarm, Create) see view_current = 0 runner->viewCurrent = 0; + runner->renderer->CameraCurrent = runner->viewCurrent; } // ===[ Instance Creation Helper ]=== @@ -1339,6 +1342,7 @@ GMLCamera* Runner_getCameraById(Runner* runner, int32_t id) { if (0 > id) return nullptr; else if (MAX_DEFAULT_ROOM_CAMERAS > id) camera = &runner->defaultCameras[id]; else if (MAX_CAMERAS > id) camera = &runner->userCameras[id - MAX_DEFAULT_ROOM_CAMERAS]; + else if (id == 8192) camera = &runner->surfaceCamera; else return nullptr; if (!camera->allocated) return nullptr; return camera; diff --git a/src/runner.h b/src/runner.h index 3790c4f5b..d76cdc099 100644 --- a/src/runner.h +++ b/src/runner.h @@ -472,6 +472,7 @@ struct Runner { RuntimeView views[MAX_VIEWS]; GMLCamera defaultCameras[MAX_DEFAULT_ROOM_CAMERAS]; GMLCamera userCameras[MAX_USER_CAMERAS]; + GMLCamera surfaceCamera; RunnerGamepadState* gamepads; RuntimeBackground backgrounds[8]; uint32_t backgroundColor; // runtime-mutable (BGR format) diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 96f61433f..a06de181e 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -226,7 +226,13 @@ static void UpdateCamera(GMLCamera* camera) { Matrix4f_translate(&ViewMatrix, x, y, 0.0f); Matrix4f_rotateZ(&ViewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); Matrix4f_translate(&ViewMatrix, -x, -y, 0.0f); + + Matrix4f ProjectionMatrix; + Matrix4f_Orthographic(&ProjectionMatrix, (float) camera->viewWidth, (float) -camera->viewHeight, 32000.0, 0.0); + + camera->ViewMatrix = ViewMatrix; + camera->ProjectionMatrix = ProjectionMatrix; } @@ -3685,7 +3691,8 @@ static RValue builtin_view_set_camera(VMContext* ctx, RValue* args, int32_t argC static RValue builtin_camera_get_active(VMContext* ctx, MAYBE_UNUSED RValue* args, MAYBE_UNUSED int32_t argCount) { Runner* runner = ctx->runner; if (runner->viewCurrent >= 0 && MAX_VIEWS > runner->viewCurrent) { - return RValue_makeReal(runner->views[runner->viewCurrent].cameraId); + //return RValue_makeReal(runner->views[runner->viewCurrent].cameraId); + return RValue_makeReal(runner->renderer->CameraCurrent); } return RValue_makeReal(-1); } From 43939199f5d54f1a463e974064191c6dbfa7bdd7 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Sun, 14 Jun 2026 22:34:50 +0200 Subject: [PATCH 10/21] clean up a little bit --- src/gl/gl_renderer.c | 5 ++--- src/gl/gl_renderer.h | 2 -- src/renderer.h | 1 - src/runner.c | 6 +++--- src/vm_builtins.c | 16 ++-------------- 5 files changed, 7 insertions(+), 23 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index 08641b106..16e896031 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -658,11 +658,10 @@ static void glClearScreen(Renderer* renderer, uint32_t color, float alpha) { float b = (float) BGR_B(color) / 255.0f; // GML draw_clear ignores the active scissor and clears the whole target. Disable scissor for the clear and restore it after. - //GLboolean scissorWasEnabled = glIsEnabled(GL_SCISSOR_TEST); - //if (scissorWasEnabled) glDisable(GL_SCISSOR_TEST); + //No it doesn't? glClearColor(r, g, b, alpha); glClear(GL_COLOR_BUFFER_BIT); - //if (scissorWasEnabled) glEnable(GL_SCISSOR_TEST); + } // Lazily decodes and uploads a TXTR page on first access. diff --git a/src/gl/gl_renderer.h b/src/gl/gl_renderer.h index 71909234e..7e3b13dbd 100644 --- a/src/gl/gl_renderer.h +++ b/src/gl/gl_renderer.h @@ -42,8 +42,6 @@ typedef struct { bool colorWriteR, colorWriteG, colorWriteB, colorWriteA; bool fogEnable; uint32_t fogColor; // BGR - float fogStart; - float fogEnd; GLuint vao, vbo, ebo; float* vertexData; // MAX_QUADS * VERTICES_PER_QUAD * FLOATS_PER_VERTEX floats diff --git a/src/renderer.h b/src/renderer.h index 1c6b07e7e..aba166257 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -8,7 +8,6 @@ #include "data_win.h" #include "instance.h" - // GameMaker Blend Modes #define bm_complex -1 diff --git a/src/runner.c b/src/runner.c index b4ce4db63..04a505ffa 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1162,7 +1162,7 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh runner->viewCurrent = (int32_t) vi; - runner->renderer->CameraCurrent = runner->viewCurrent; + runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; Runner_draw(runner); renderer->vtable->flush(renderer); @@ -1183,7 +1183,7 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh float viewAngle = camera->viewAngle; runner->viewCurrent = (int32_t) vi; - runner->renderer->CameraCurrent = runner->viewCurrent; + runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; renderer->vtable->beginView(renderer, viewX, viewY, viewW, viewH, portX, portY, portW, portH, viewAngle); Matrix4f ViewMatrix = camera->ViewMatrix; @@ -1240,7 +1240,7 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh // Reset view_current to 0 so non-Draw events (Step, Alarm, Create) see view_current = 0 runner->viewCurrent = 0; - runner->renderer->CameraCurrent = runner->viewCurrent; + runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; } // ===[ Instance Creation Helper ]=== diff --git a/src/vm_builtins.c b/src/vm_builtins.c index a06de181e..1e4ead7a8 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -3505,11 +3505,6 @@ static RValue builtin_camera_set_proj_mat(VMContext* ctx, RValue* args, int32_t if (camera == nullptr || !rvalueIsMatrix(args[1])) return RValue_makeUndefined(); Matrix4f m; matrixFromGml(&m, args[1].array); - // Orthographic projection: m[0,0] = 2/width, m[1,1] = 2/height. - GMLReal m00 = m.m[Matrix_getIndex(0, 0)]; - GMLReal m11 = m.m[Matrix_getIndex(1, 1)]; - if (m00 != 0.0) camera->viewWidth = (int32_t) lround(GMLReal_fabs(2.0 / m00)); - if (m11 != 0.0) camera->viewHeight = (int32_t) lround(GMLReal_fabs(2.0 / m11)); camera->ProjectionMatrix = m; camera->ProjectionMatrix.m[Matrix_getIndex(1, 1)] = -m.m[Matrix_getIndex(1, 1)]; return RValue_makeUndefined(); @@ -3587,8 +3582,6 @@ static RValue builtin_camera_set_view_angle(VMContext* ctx, RValue* args, int32_ if (camera != nullptr) { camera->viewAngle = (float) RValue_toReal(args[1]); - float x = camera->viewX + camera->viewWidth/2; - float y = camera->viewY + camera->viewHeight/2; UpdateCamera(camera); } return RValue_makeUndefined(); @@ -3709,13 +3702,8 @@ static RValue builtin_camera_apply(VMContext* ctx, RValue* args, int32_t argCoun if (1 > argCount) return RValue_makeUndefined(); Runner* runner = ctx->runner; GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); - if (camera != nullptr) { - - Matrix4f ViewMatrix = camera->ViewMatrix; - Matrix4f ProjectionMatrix = camera->ProjectionMatrix; - - runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); - + if (camera != nullptr) { + runner->renderer->vtable->applyProjection(runner->renderer, &camera->ViewMatrix, &camera->ProjectionMatrix); } return RValue_makeUndefined(); } From d62f345d1946c80c1f66483ebf43a9987ce957fa Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Mon, 15 Jun 2026 22:28:24 +0200 Subject: [PATCH 11/21] remove hacks and hopefully it's good enough --- src/gl/gl_renderer.c | 32 ++++++++++++++++++++++---------- src/renderer.h | 3 --- src/runner.c | 40 +++++++++++----------------------------- src/vm_builtins.c | 23 +++++++++++------------ 4 files changed, 44 insertions(+), 54 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index 16e896031..e5e94c379 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -1976,6 +1976,15 @@ static bool glSurfaceGetPixels(Renderer* renderer, int32_t surfaceId, uint8_t* o static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implicitApplicationSurface) { GLRenderer* gl = (GLRenderer*) renderer; + flushBatch(gl); + + int32_t ViewCurrent = 0; + if (renderer->runner->viewsEnabled) { + ViewCurrent = renderer->runner->viewCurrent; + } + RuntimeView* view = &renderer->runner->views[ViewCurrent]; + gl->base.CameraCurrent = view->cameraId; + GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.CameraCurrent); if (0 > surfaceId || (uint32_t) surfaceId >= gl->surfaceCount) return false; if (gl->surfaces[surfaceId] == 0) return false; @@ -1985,17 +1994,19 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic if (surfaceId == renderer->runner->applicationSurfaceId && implicitApplicationSurface) { glViewport(gl->base.CPortX, gl->base.CPortY, gl->base.CPortW, gl->base.CPortH); glEnable(GL_SCISSOR_TEST); - glApplyProjection(renderer, &renderer->V_ViewMatrix,&renderer->V_ProjectionMatrix); - gl->base.CameraCurrent = renderer->runner->viewCurrent; - glShaderSettingsRefresh(renderer); + + glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); + return true; } - if (surfaceId == renderer->V_SurfaceID) { - //we go back to the camera's settings for this - glApplyProjection(renderer, &renderer->V_ViewMatrix,&renderer->V_ProjectionMatrix); - gl->base.CameraCurrent = renderer->runner->viewCurrent; + if (surfaceId == view->surfaceId) { + //the surface belongs to the view we are rending, we use the view's camera. + glViewport(0, 0, gl->surfaceWidth[surfaceId], gl->surfaceHeight[surfaceId]); + glDisable(GL_SCISSOR_TEST); + glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); + return true; } else { Matrix4f ProjectionMatrix; Matrix4f_Orthographic(&ProjectionMatrix, (float) gl->surfaceWidth[surfaceId], (float) -gl->surfaceHeight[surfaceId], 32000.0, 0.0); @@ -2005,7 +2016,6 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic float y = (float) gl->surfaceHeight[surfaceId] /2; Matrix4f_identity(&ViewMatrix); Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - glApplyProjection(renderer, &ViewMatrix,&ProjectionMatrix); gl->base.CameraCurrent = SURFACE_CAMERA; GMLCamera* camera = &renderer->runner->surfaceCamera; @@ -2024,12 +2034,15 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic camera->ProjectionMatrix = ProjectionMatrix; camera->ViewMatrix = ViewMatrix; + glViewport(0, 0, gl->surfaceWidth[surfaceId], gl->surfaceHeight[surfaceId]); + glDisable(GL_SCISSOR_TEST); + glApplyProjection(renderer, &ViewMatrix,&ProjectionMatrix); + return true; } glViewport(0, 0, gl->surfaceWidth[surfaceId], gl->surfaceHeight[surfaceId]); glDisable(GL_SCISSOR_TEST); - glShaderSettingsRefresh(renderer); return true; } @@ -2622,7 +2635,6 @@ Renderer* GLRenderer_create(void) { gl->base.drawValign = 0; gl->base.circlePrecision = 24; gl->base.currentShader = -1; - gl->base.V_SurfaceID = -1; gl->base.CameraCurrent = 0; return (Renderer*) gl; } diff --git a/src/renderer.h b/src/renderer.h index aba166257..4da9d52eb 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -174,9 +174,6 @@ struct Renderer { Runner* runner; Matrix4f gmlMatrices[MATRICES_MAX]; int32_t currentShader; - Matrix4f V_ViewMatrix; - Matrix4f V_ProjectionMatrix; - int32_t V_SurfaceID; int32_t CameraCurrent; }; diff --git a/src/runner.c b/src/runner.c index 04a505ffa..9945df1ec 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1035,9 +1035,6 @@ void Runner_drawGUI(Runner* runner, int32_t windowW, int32_t windowH, int32_t ta Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); - runner->renderer->V_ViewMatrix = ViewMatrix; - runner->renderer->V_ProjectionMatrix = ProjectionMatrix; - runner->renderer->V_SurfaceID = -1; fireDrawSubtype(runner, drawables, drawableCount, DRAW_GUI_BEGIN); fireDrawSubtype(runner, drawables, drawableCount, DRAW_GUI); @@ -1155,9 +1152,6 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh Matrix4f ViewMatrix = camera->ViewMatrix; Matrix4f ProjectionMatrix = camera->ProjectionMatrix; - renderer->V_ViewMatrix = ViewMatrix; - renderer->V_ProjectionMatrix = ProjectionMatrix; - renderer->V_SurfaceID = view->surfaceId; runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); @@ -1188,9 +1182,6 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh Matrix4f ViewMatrix = camera->ViewMatrix; Matrix4f ProjectionMatrix = camera->ProjectionMatrix; - renderer->V_ViewMatrix = ViewMatrix; - renderer->V_ProjectionMatrix = ProjectionMatrix; - renderer->V_SurfaceID = -1; runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); Runner_draw(runner); @@ -1221,14 +1212,11 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh float y = (float) gameH /2; Matrix4f_identity(&ViewMatrix); Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - renderer->V_ViewMatrix = ViewMatrix; - renderer->V_ProjectionMatrix = ProjectionMatrix; if (camera != nullptr) { camera->ViewMatrix = ViewMatrix; camera->ProjectionMatrix = ProjectionMatrix; } - renderer->V_SurfaceID = -1; runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); Runner_draw(runner); @@ -1342,7 +1330,7 @@ GMLCamera* Runner_getCameraById(Runner* runner, int32_t id) { if (0 > id) return nullptr; else if (MAX_DEFAULT_ROOM_CAMERAS > id) camera = &runner->defaultCameras[id]; else if (MAX_CAMERAS > id) camera = &runner->userCameras[id - MAX_DEFAULT_ROOM_CAMERAS]; - else if (id == 8192) camera = &runner->surfaceCamera; + else if (id == SURFACE_CAMERA) camera = &runner->surfaceCamera; else return nullptr; if (!camera->allocated) return nullptr; return camera; @@ -1367,22 +1355,22 @@ static void initDefaultCameraFromRoomView(GMLCamera* camera, RoomView* roomView) camera->objectId = roomView->objectId; camera->viewAngle = 0; //make default projection - Matrix4f Projection; - Matrix4f_Orthographic(&Projection, (float) camera->viewWidth, (float) -camera->viewHeight, 32000.0, 0.0); + Matrix4f ProjectionMatrix; + Matrix4f_Orthographic(&ProjectionMatrix, (float) camera->viewWidth, (float) -camera->viewHeight, 32000.0, 0.0); - Matrix4f View; + Matrix4f ViewMatrix; float x = camera->viewX + camera->viewWidth/2; float y = camera->viewY + camera->viewHeight/2; - Matrix4f_identity(&View); - Matrix4f_LookAt(&View, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - Matrix4f_translate(&View, x, y, 0.0f); - Matrix4f_rotateZ(&View, -camera->viewAngle * (float) M_PI / 180.0f); - Matrix4f_translate(&View, -x, -y, 0.0f); + Matrix4f_identity(&ViewMatrix); + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + Matrix4f_translate(&ViewMatrix, x, y, 0.0f); + Matrix4f_rotateZ(&ViewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); + Matrix4f_translate(&ViewMatrix, -x, -y, 0.0f); - camera->ProjectionMatrix = Projection; - camera->ViewMatrix = View; + camera->ProjectionMatrix = ProjectionMatrix; + camera->ViewMatrix = ViewMatrix; } // Copies the viewport (port) properties and enabled flag from parsed room data. @@ -3947,9 +3935,6 @@ bool Runner_surfaceSetTarget(Runner* runner, int32_t surfaceID) { runner->surfaceStack[slot] = surfaceID; runner->renderer->vtable->flush(runner->renderer); - GMLCamera* camera = Runner_getCameraForView(runner, (int32_t) runner->viewCurrent); - runner->renderer->V_ProjectionMatrix = camera->ProjectionMatrix; - runner->renderer->V_ViewMatrix = camera->ViewMatrix; return runner->renderer->vtable->setRenderTarget(runner->renderer, surfaceID, false); } @@ -3964,9 +3949,6 @@ bool Runner_surfaceResetTarget(Runner* runner) { int32_t newTop = findStackTop(runner); int32_t newTarget = newTop == -1 ? runner->applicationSurfaceId : runner->surfaceStack[newTop]; - GMLCamera* camera = Runner_getCameraForView(runner, (int32_t) runner->viewCurrent); - runner->renderer->V_ProjectionMatrix = camera->ProjectionMatrix; - runner->renderer->V_ViewMatrix = camera->ViewMatrix; runner->renderer->vtable->setRenderTarget(runner->renderer, newTarget, newTop == -1); if (newTop == -1 && runner->inGuiPass) { // Inside Pre Draw / Post Draw / Draw GUI the base target is the GUI pass target with the GUI projection, not the room view. diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 1e4ead7a8..fc105ca74 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -216,7 +216,7 @@ static DsStack* dsStackGet(Runner* runner, int32_t id) { return &runner->dsStackPool[id]; } -static void UpdateCamera(GMLCamera* camera) { +static void UpdateCameraViewSimple(GMLCamera* camera) { float x = camera->viewX + camera->viewWidth/2; float y = camera->viewY + camera->viewHeight/2; @@ -1574,7 +1574,7 @@ void VMBuiltins_setVariable(VMContext* ctx, Instance* inst, int16_t builtinVarId GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { camera->viewX = RValue_toReal(val); - UpdateCamera(camera); + UpdateCameraViewSimple(camera); } return; } @@ -1582,23 +1582,23 @@ void VMBuiltins_setVariable(VMContext* ctx, Instance* inst, int16_t builtinVarId GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { camera->viewY = RValue_toInt32(val); - UpdateCamera(camera); + UpdateCameraViewSimple(camera); } return; } case BUILTIN_VAR_VIEW_WVIEW: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { - camera->viewWidth = RValue_toInt32(val); - UpdateCamera(camera); - } + camera->viewWidth = RValue_toInt32(val); + UpdateCameraViewSimple(camera); + } return; } case BUILTIN_VAR_VIEW_HVIEW: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { camera->viewHeight = RValue_toInt32(val); - UpdateCamera(camera); + UpdateCameraViewSimple(camera); } return; } @@ -1627,7 +1627,7 @@ void VMBuiltins_setVariable(VMContext* ctx, Instance* inst, int16_t builtinVarId GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { camera->viewAngle = (float) RValue_toReal(val); - UpdateCamera(camera); + UpdateCameraViewSimple(camera); } return; } @@ -3467,7 +3467,7 @@ static RValue builtin_camera_set_view_pos(VMContext* ctx, RValue* args, int32_t if (camera != nullptr) { camera->viewX = RValue_toReal(args[1]); camera->viewY = RValue_toReal(args[2]); - UpdateCamera(camera); + UpdateCameraViewSimple(camera); } return RValue_makeUndefined(); } @@ -3582,7 +3582,7 @@ static RValue builtin_camera_set_view_angle(VMContext* ctx, RValue* args, int32_ if (camera != nullptr) { camera->viewAngle = (float) RValue_toReal(args[1]); - UpdateCamera(camera); + UpdateCameraViewSimple(camera); } return RValue_makeUndefined(); } @@ -3648,7 +3648,7 @@ static RValue builtin_camera_create_view(VMContext* ctx, RValue* args, int32_t a if (argCount > 9) camera->borderY = (uint32_t) RValue_toInt32(args[9]); - UpdateCamera(camera); + UpdateCameraViewSimple(camera); return RValue_makeReal(id); } @@ -3684,7 +3684,6 @@ static RValue builtin_view_set_camera(VMContext* ctx, RValue* args, int32_t argC static RValue builtin_camera_get_active(VMContext* ctx, MAYBE_UNUSED RValue* args, MAYBE_UNUSED int32_t argCount) { Runner* runner = ctx->runner; if (runner->viewCurrent >= 0 && MAX_VIEWS > runner->viewCurrent) { - //return RValue_makeReal(runner->views[runner->viewCurrent].cameraId); return RValue_makeReal(runner->renderer->CameraCurrent); } return RValue_makeReal(-1); From 0111cadf12769f41747fc9bb8ea5dba1a98e8ab0 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Tue, 16 Jun 2026 20:55:59 +0200 Subject: [PATCH 12/21] remove more hacks and smth else I forgor --- src/gl/gl_renderer.c | 70 ++++++++++++++++++------------ src/gl_legacy/gl_legacy_renderer.c | 2 +- src/runner.c | 24 +++++++--- src/vm_builtins.c | 3 +- 4 files changed, 64 insertions(+), 35 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index e5e94c379..01d597ec1 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -442,6 +442,32 @@ static void glShaderSettingsRefresh(Renderer* renderer) { } } +// camera_apply: swap the active world->clip projection on the current target without touching its viewport. +static void glApplyProjection(Renderer* renderer, const Matrix4f* ViewMatrix,const Matrix4f* ProjectionMatrix) { + GLRenderer* gl = (GLRenderer*) renderer; + + // Flush first so pending quads draw under the projection they were issued with. + flushBatch(gl); + + Matrix4f World = renderer->gmlMatrices[MATRIX_WORLD]; + Matrix4f View = *ViewMatrix; + Matrix4f Projection = *ProjectionMatrix; + + Matrix4f WorldView; + Matrix4f_multiply(&WorldView, &View, &World); + + Matrix4f WorldViewProjection; + Matrix4f_multiply(&WorldViewProjection, &View, &World); + Matrix4f_multiply(&WorldViewProjection, &Projection, &WorldViewProjection); + + renderer->gmlMatrices[MATRIX_VIEW] = View; + renderer->gmlMatrices[MATRIX_PROJECTION] = Projection; + renderer->gmlMatrices[MATRIX_WORLD_VIEW] = WorldView; + renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = WorldViewProjection; + //oh my I hope it's good enough. + glShaderSettingsRefresh(renderer); +} + static void glGpuResetShader(Renderer* renderer) { GLRenderer* gl = (GLRenderer*) renderer; flushBatch(gl); @@ -515,7 +541,7 @@ static void glBeginFrame(Renderer* renderer, int32_t gameW, int32_t gameH, int32 gl->base.CPortH = gameH; } -static void glBeginView(Renderer* renderer, int32_t viewX, int32_t viewY, int32_t viewW, int32_t viewH, int32_t portX, int32_t portY, int32_t portW, int32_t portH, float viewAngle) { +static void glBeginView(Renderer* renderer, MAYBE_UNUSED int32_t viewX, MAYBE_UNUSED int32_t viewY, MAYBE_UNUSED int32_t viewW, MAYBE_UNUSED int32_t viewH, int32_t portX, int32_t portY, int32_t portW, int32_t portH, MAYBE_UNUSED float viewAngle) { GLRenderer* gl = (GLRenderer*) renderer; gl->batchCount = 0; @@ -535,6 +561,20 @@ static void glBeginView(Renderer* renderer, int32_t viewX, int32_t viewY, int32_ glEnable(GL_SCISSOR_TEST); glScissor(portX, portY, portW, portH); + int32_t ViewCurrent = 0; + if (renderer->runner->viewsEnabled) { + ViewCurrent = renderer->runner->viewCurrent; + } + RuntimeView* view = &renderer->runner->views[ViewCurrent]; + gl->base.CameraCurrent = view->cameraId; + GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.CameraCurrent); + glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); + + //Matrix4f ViewMatrix = camera->ViewMatrix; + //Matrix4f ProjectionMatrix = camera->ProjectionMatrix; + //runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); + + glShaderSettingsRefresh(renderer); glActiveTexture(GL_TEXTURE1); @@ -547,33 +587,7 @@ static void glEndView(Renderer* renderer) { glDisable(GL_SCISSOR_TEST); } -// camera_apply: swap the active world->clip projection on the current target without touching its viewport. -static void glApplyProjection(Renderer* renderer, const Matrix4f* ViewMatrix,const Matrix4f* ProjectionMatrix) { - GLRenderer* gl = (GLRenderer*) renderer; - - // Flush first so pending quads draw under the projection they were issued with. - flushBatch(gl); - - Matrix4f World = renderer->gmlMatrices[MATRIX_WORLD]; - Matrix4f View = *ViewMatrix; - Matrix4f Projection = *ProjectionMatrix; - - Matrix4f WorldView; - Matrix4f_multiply(&WorldView, &View, &World); - - Matrix4f WorldViewProjection; - Matrix4f_multiply(&WorldViewProjection, &View, &World); - Matrix4f_multiply(&WorldViewProjection, &Projection, &WorldViewProjection); - - renderer->gmlMatrices[MATRIX_VIEW] = View; - renderer->gmlMatrices[MATRIX_PROJECTION] = Projection; - renderer->gmlMatrices[MATRIX_WORLD_VIEW] = WorldView; - renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = WorldViewProjection; - //oh my I hope it's good enough. - glShaderSettingsRefresh(renderer); -} - -static void glBeginGUI(Renderer* renderer, int32_t guiW, int32_t guiH, int32_t portX, int32_t portY, int32_t portW, int32_t portH, int32_t targetSurfaceId) { +static void glBeginGUI(Renderer* renderer, MAYBE_UNUSED int32_t guiW, MAYBE_UNUSED int32_t guiH, int32_t portX, int32_t portY, int32_t portW, int32_t portH, int32_t targetSurfaceId) { GLRenderer* gl = (GLRenderer*) renderer; gl->batchCount = 0; diff --git a/src/gl_legacy/gl_legacy_renderer.c b/src/gl_legacy/gl_legacy_renderer.c index 9be5f2288..b7437eaed 100644 --- a/src/gl_legacy/gl_legacy_renderer.c +++ b/src/gl_legacy/gl_legacy_renderer.c @@ -186,7 +186,7 @@ static void glEndView(MAYBE_UNUSED Renderer* renderer) { } // camera_apply: swap the active world->clip projection on the current target without touching its viewport. -static void glApplyProjection(Renderer* renderer, const Matrix4f* ViewMatrix,const Matrix4f* ProjectionMatrix) { +static void glApplyProjection(Renderer* renderer, MAYBE_UNUSED const Matrix4f* ViewMatrix, MAYBE_UNUSED const Matrix4f* ProjectionMatrix) { Matrix4f projection = *ProjectionMatrix; //fix it later Matrix4f_flipClipY(&projection); glMatrixMode(GL_PROJECTION); diff --git a/src/runner.c b/src/runner.c index 9945df1ec..9dba84fc7 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1180,10 +1180,6 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; renderer->vtable->beginView(renderer, viewX, viewY, viewW, viewH, portX, portY, portW, portH, viewAngle); - Matrix4f ViewMatrix = camera->ViewMatrix; - Matrix4f ProjectionMatrix = camera->ProjectionMatrix; - runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); - Runner_draw(runner); if (debugShowCollisionMasks) DebugOverlay_drawCollisionMasks(runner); @@ -1213,6 +1209,11 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh Matrix4f_identity(&ViewMatrix); Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); if (camera != nullptr) { + camera->viewX = 0; + camera->viewY = 0; + camera->viewWidth = gameW; + camera->viewHeight = gameH; + camera->viewAngle = 0.0; camera->ViewMatrix = ViewMatrix; camera->ProjectionMatrix = ProjectionMatrix; } @@ -3924,7 +3925,20 @@ void Runner_guiSizeChanged(Runner* runner) { runner->guiPassH = guiH; int32_t top = findStackTop(runner); bool renderingToUserSurface = (top != -1 && runner->surfaceStack[top] != runner->applicationSurfaceId); - runner->renderer->vtable->setGuiProjection(runner->renderer, guiW, guiH, runner->guiPassPortW, runner->guiPassPortH, renderingToUserSurface); + float MULT = 1.0; + if (renderingToUserSurface == true) { + MULT = -1.0; + } + Matrix4f ProjectionMatrix; + Matrix4f_Orthographic(&ProjectionMatrix, (float) runner->guiPassW, (float) runner->guiPassH*MULT, 32000.0, 0.0); + + Matrix4f ViewMatrix; + float x = (float) runner->guiPassW /2; + float y = (float) runner->guiPassH /2; + Matrix4f_identity(&ViewMatrix); + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + + runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); } bool Runner_surfaceSetTarget(Runner* runner, int32_t surfaceID) { diff --git a/src/vm_builtins.c b/src/vm_builtins.c index fc105ca74..430774856 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -3701,8 +3701,9 @@ static RValue builtin_camera_apply(VMContext* ctx, RValue* args, int32_t argCoun if (1 > argCount) return RValue_makeUndefined(); Runner* runner = ctx->runner; GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); - if (camera != nullptr) { + if (camera != nullptr) { runner->renderer->vtable->applyProjection(runner->renderer, &camera->ViewMatrix, &camera->ProjectionMatrix); + runner->renderer->CameraCurrent = RValue_toInt32(args[0]); } return RValue_makeUndefined(); } From 427fc0c56e2cb6956410a4baf6a97f14bd17c9bf Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Thu, 18 Jun 2026 21:50:25 +0200 Subject: [PATCH 13/21] rebase and fix little things --- src/gl/gl_renderer.c | 33 +++++++++++++++++++++------------ src/runner.c | 3 ++- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index 01d597ec1..0faded55a 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -250,6 +250,10 @@ static void glInit(Renderer* renderer, DataWin* dataWin) { GLRenderer* gl = (GLRenderer*) renderer; renderer->dataWin = dataWin; + Matrix4f World; + Matrix4f_identity(&World); + renderer->gmlMatrices[MATRIX_WORLD] = World; + GMLShader* defaultShader = safeCalloc(1, sizeof(GMLShader)); bool success = compileProgram(defaultShader, "default", defaultVertexShaderSource, defaultFragmentShaderSource, 0, nullptr); if (!success) { @@ -400,8 +404,14 @@ static void glGpuSetShader(Renderer* renderer, int32_t shaderIndex) { GLShaderUniform* gmAlphaTestEnabledUniform = findShaderUniformByName(gmlShader, "gm_AlphaTestEnabled"); GLShaderUniform* gmAlphaRefValue = findShaderUniformByName(gmlShader, "gm_AlphaRefValue"); + Matrix4f FlippedClip[MATRICES_MAX]; + for (int32_t i = 0; i < MATRICES_MAX; i++) { + FlippedClip[i] = renderer->gmlMatrices[i]; + Matrix4f_flipClipY(&FlippedClip[i]); + } + if (gmMatricesUniform != nullptr) { - glUniformMatrix4fv(gmMatricesUniform->location, 5, GL_FALSE, renderer->gmlMatrices[0].m); + glUniformMatrix4fv(gmMatricesUniform->location, 5, GL_FALSE, FlippedClip[0].m); } if (gmFogColourUniform != nullptr) { glUniform1i(gmFogColourUniform->location, gl->fogColor); @@ -428,13 +438,18 @@ static void glShaderSettingsRefresh(Renderer* renderer) { glUseProgram(gl->defaultShaderProgram->shaderId); - GLShaderUniform* uProjection = findShaderUniformByName(gl->defaultShaderProgram, "uProjection"); + GLShaderUniform* uWorldViewProjection = findShaderUniformByName(gl->defaultShaderProgram, "uWorldViewProjection"); GLShaderUniform* uFogColor = findShaderUniformByName(gl->defaultShaderProgram, "uFogColor"); GLShaderUniform* uAlphaTestRef = findShaderUniformByName(gl->defaultShaderProgram, "uAlphaTestRef"); GLShaderUniform* uAlphaTestEnabled = findShaderUniformByName(gl->defaultShaderProgram, "uAlphaTestEnabled"); GLShaderUniform* uTexture = findShaderUniformByName(gl->defaultShaderProgram, "uTexture"); + Matrix4f FlippedClip[MATRICES_MAX]; + for (int32_t i = 0; i < MATRICES_MAX; i++) { + FlippedClip[i] = renderer->gmlMatrices[i]; + Matrix4f_flipClipY(&FlippedClip[i]); + } - glUniformMatrix4fv(uProjection->location, 1, GL_FALSE, renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION].m); + glUniformMatrix4fv(uWorldViewProjection->location, 1, GL_FALSE, FlippedClip[MATRIX_WORLD_VIEW_PROJECTION].m); glUniform4f(uFogColor->location, fogR, fogG, fogB, gl->fogEnable ? 1.0f : 0.0f); glUniform1f(uAlphaTestRef->location, gl->alphaTestRef); glUniform1i(uAlphaTestEnabled->location, gl->alphaTestEnable); @@ -457,8 +472,7 @@ static void glApplyProjection(Renderer* renderer, const Matrix4f* ViewMatrix,con Matrix4f_multiply(&WorldView, &View, &World); Matrix4f WorldViewProjection; - Matrix4f_multiply(&WorldViewProjection, &View, &World); - Matrix4f_multiply(&WorldViewProjection, &Projection, &WorldViewProjection); + Matrix4f_multiply(&WorldViewProjection, &Projection, &WorldView); renderer->gmlMatrices[MATRIX_VIEW] = View; renderer->gmlMatrices[MATRIX_PROJECTION] = Projection; @@ -570,11 +584,6 @@ static void glBeginView(Renderer* renderer, MAYBE_UNUSED int32_t viewX, MAYBE_UN GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.CameraCurrent); glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); - //Matrix4f ViewMatrix = camera->ViewMatrix; - //Matrix4f ProjectionMatrix = camera->ProjectionMatrix; - //runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); - - glShaderSettingsRefresh(renderer); glActiveTexture(GL_TEXTURE1); @@ -2022,6 +2031,7 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); return true; } else { + //camera will use full surface. Matrix4f ProjectionMatrix; Matrix4f_Orthographic(&ProjectionMatrix, (float) gl->surfaceWidth[surfaceId], (float) -gl->surfaceHeight[surfaceId], 32000.0, 0.0); @@ -2558,8 +2568,7 @@ static void glSetMatrix(Renderer* renderer, int32_t MatrixType, Matrix4f Matrix) Matrix4f_multiply(&WorldView, &View, &World); Matrix4f WorldViewProjection; - Matrix4f_multiply(&WorldViewProjection, &View, &World); - Matrix4f_multiply(&WorldViewProjection, &Projection, &WorldViewProjection); + Matrix4f_multiply(&WorldViewProjection, &Projection, &WorldView); renderer->gmlMatrices[MATRIX_WORLD_VIEW] = WorldView; renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = WorldViewProjection; diff --git a/src/runner.c b/src/runner.c index 9dba84fc7..6c411bcd7 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1218,7 +1218,8 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh camera->ProjectionMatrix = ProjectionMatrix; } - runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); + renderer->vtable->beginView(renderer, fullViewX, fullViewY, fullViewW, fullViewH, 0, 0, gameW, gameH, 0.0f); + Runner_draw(runner); if (debugShowCollisionMasks) DebugOverlay_drawCollisionMasks(runner); From 9f8379a86b80a46bf08ae141a17318c34363f959 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Fri, 19 Jun 2026 18:37:16 +0200 Subject: [PATCH 14/21] remove more thing, try fix GUI kinda --- src/gl/gl_renderer.c | 42 ++++++++++++++++++++++++++++++------------ src/runner.c | 31 ++++--------------------------- src/vm_builtins.c | 16 ++++++++++++++-- 3 files changed, 48 insertions(+), 41 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index 0faded55a..c84b1110c 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -596,7 +596,7 @@ static void glEndView(Renderer* renderer) { glDisable(GL_SCISSOR_TEST); } -static void glBeginGUI(Renderer* renderer, MAYBE_UNUSED int32_t guiW, MAYBE_UNUSED int32_t guiH, int32_t portX, int32_t portY, int32_t portW, int32_t portH, int32_t targetSurfaceId) { +static void glBeginGUI(Renderer* renderer, MAYBE_UNUSED int32_t guiW, MAYBE_UNUSED int32_t guiH, int32_t portX, int32_t portY, int32_t portW, MAYBE_UNUSED int32_t portH, int32_t targetSurfaceId) { GLRenderer* gl = (GLRenderer*) renderer; gl->batchCount = 0; @@ -617,25 +617,43 @@ static void glBeginGUI(Renderer* renderer, MAYBE_UNUSED int32_t guiW, MAYBE_UNUS glEnable(GL_SCISSOR_TEST); - //Matrix4f projection; - //Matrix4f_guiProjection(&projection, (float) guiW, (float) guiH, (float) portW, (float) portH); - //Matrix4f_flipClipY(&projection); - //renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; - glShaderSettingsRefresh(renderer); + gl->base.CameraCurrent = 0; //replace this number with whatver camera ID is used for the GUI. maybe some special ID? I have no idea how it should be + //GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.CameraCurrent); use this or something later + Matrix4f ProjectionMatrix; + Matrix4f_Orthographic(&ProjectionMatrix, (float) guiW, (float) guiH, 32000.0, 0.0); + + Matrix4f ViewMatrix; + float x = (float) guiW /2; + float y = (float) guiH /2; + Matrix4f_identity(&ViewMatrix); + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + + glApplyProjection(renderer,&ViewMatrix,&ProjectionMatrix); + + glActiveTexture(GL_TEXTURE1); glBindVertexArray(gl->vao); } -static void glSetGuiProjection(Renderer* renderer, int32_t guiW, int32_t guiH, int32_t portW, int32_t portH, bool renderingToUserSurface) { +static void glSetGuiProjection(Renderer* renderer, int32_t guiW, int32_t guiH, MAYBE_UNUSED int32_t portW, MAYBE_UNUSED int32_t portH, MAYBE_UNUSED bool renderingToUserSurface) { GLRenderer* gl = (GLRenderer*) renderer; flushBatch(gl); - Matrix4f projection; - Matrix4f_guiProjection(&projection, (float) guiW, (float) guiH, (float) portW, (float) portH); + // GL surfaces are stored bottom-up and draw_surface samples them with vertical flip. - // Flip the projection when we are rendering to a user surface so it comes back upright. - if (renderingToUserSurface) Matrix4f_flipClipY(&projection); - renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; + gl->base.CameraCurrent = 0; //replace this number with whatver camera ID is used for the GUI. maybe some special ID? I have no idea how it should be + //GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.CameraCurrent); use this or something later + //yeah no I have no idea how to do the GUI + Matrix4f ProjectionMatrix; + Matrix4f_Orthographic(&ProjectionMatrix, (float) guiW, (float) guiH, 32000.0, 0.0); + if (renderingToUserSurface) Matrix4f_flipClipY(&ProjectionMatrix); + Matrix4f ViewMatrix; + float x = (float) guiW * 0.5f; + float y = (float) guiH * 0.5f; + Matrix4f_identity(&ViewMatrix); + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + + glApplyProjection(renderer,&ViewMatrix,&ProjectionMatrix); glShaderSettingsRefresh(renderer); } diff --git a/src/runner.c b/src/runner.c index 6c411bcd7..a6ce16dc9 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1023,19 +1023,6 @@ void Runner_drawGUI(Runner* runner, int32_t windowW, int32_t windowH, int32_t ta int32_t guiW = runner->guiWidth > 0 ? runner->guiWidth : targetW; int32_t guiH = runner->guiHeight > 0 ? runner->guiHeight : targetH; beginGuiPass(runner, guiW, guiH, windowW, windowH, RENDER_TARGET_HOST_FRAMEBUFFER); - - //make default projection - Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) guiW, (float) guiH, 32000.0, 0.0); - - Matrix4f ViewMatrix; - float x = (float) guiW / 2; - float y = (float) guiH / 2; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - - runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); - fireDrawSubtype(runner, drawables, drawableCount, DRAW_GUI_BEGIN); fireDrawSubtype(runner, drawables, drawableCount, DRAW_GUI); fireDrawSubtype(runner, drawables, drawableCount, DRAW_GUI_END); @@ -1157,6 +1144,9 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh runner->viewCurrent = (int32_t) vi; runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; + runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); + + Runner_draw(runner); renderer->vtable->flush(renderer); @@ -3926,20 +3916,7 @@ void Runner_guiSizeChanged(Runner* runner) { runner->guiPassH = guiH; int32_t top = findStackTop(runner); bool renderingToUserSurface = (top != -1 && runner->surfaceStack[top] != runner->applicationSurfaceId); - float MULT = 1.0; - if (renderingToUserSurface == true) { - MULT = -1.0; - } - Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) runner->guiPassW, (float) runner->guiPassH*MULT, 32000.0, 0.0); - - Matrix4f ViewMatrix; - float x = (float) runner->guiPassW /2; - float y = (float) runner->guiPassH /2; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - - runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); + runner->renderer->vtable->setGuiProjection(runner->renderer, guiW, guiH, runner->guiPassPortW, runner->guiPassPortH, renderingToUserSurface); } bool Runner_surfaceSetTarget(Runner* runner, int32_t surfaceID) { diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 430774856..315d97add 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -2929,14 +2929,26 @@ static RValue builtin_matrix_build_projection_perspective_fov(MAYBE_UNUSED VMCon } static RValue builtin_matrix_get(MAYBE_UNUSED VMContext *ctx, RValue *args, int32_t argCount) { int32_t Matrix = RValue_toInt32(args[0]); - return RValue_makeArray(matrixToGml(&ctx->runner->renderer->gmlMatrices[Matrix])); + if (Matrix < 0 || Matrix > 2) return RValue_makeUndefined(); + bool toPrevMatrix = argCount == 2; + GMLArray *destArray = toPrevMatrix ? args[1].array : nullptr; + if (toPrevMatrix && !rvalueIsMatrix(args[1])) return RValue_makeUndefined(); + + if (!toPrevMatrix) { + return RValue_makeArray(matrixToGml(&ctx->runner->renderer->gmlMatrices[Matrix])); + } else { + repeat (16, i) { + *GMLArray_slot(destArray, i) = RValue_makeReal(ctx->runner->renderer->gmlMatrices[Matrix].m[i]); + } + return RValue_makeArrayWeak(destArray); + } } static RValue builtin_matrix_set(MAYBE_UNUSED VMContext *ctx, RValue *args, int32_t argCount) { int32_t Matrix = RValue_toInt32(args[0]); Matrix4f m; matrixFromGml(&m, args[1].array); - //add safe guards or whatever itis + if (Matrix < 0 || Matrix > 2) return RValue_makeUndefined(); if (ctx->runner->renderer != nullptr) { ctx->runner->renderer->vtable->setMatrix(ctx->runner->renderer, Matrix, m); } From 220f5963c935be37d3a0869551dc13f236ee6c79 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Fri, 19 Jun 2026 18:58:02 +0200 Subject: [PATCH 15/21] try to fix things, I wanna give up --- src/gl/gl_renderer.c | 43 ++++++++++++++++++++++++++++++++++--------- src/renderer.h | 3 ++- src/runner.c | 1 + src/runner.h | 1 + 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index c84b1110c..ff45ae949 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -616,9 +616,21 @@ static void glBeginGUI(Renderer* renderer, MAYBE_UNUSED int32_t guiW, MAYBE_UNUS } glEnable(GL_SCISSOR_TEST); + //I dunno hopefully this is at least somewhat correct... + gl->base.CameraCurrent = GUI_CAMERA; + GMLCamera* camera = &renderer->runner->guiCamera; + camera->allocated = true; + camera->viewX = 0.0; + camera->viewY = 0.0; + camera->viewWidth = guiW; + camera->viewHeight = guiH; + camera->borderX = 0; + camera->borderY = 0; + camera->speedX = 0; + camera->speedY = 0; + camera->objectId = -1; + camera->viewAngle = 0; - gl->base.CameraCurrent = 0; //replace this number with whatver camera ID is used for the GUI. maybe some special ID? I have no idea how it should be - //GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.CameraCurrent); use this or something later Matrix4f ProjectionMatrix; Matrix4f_Orthographic(&ProjectionMatrix, (float) guiW, (float) guiH, 32000.0, 0.0); @@ -627,8 +639,9 @@ static void glBeginGUI(Renderer* renderer, MAYBE_UNUSED int32_t guiW, MAYBE_UNUS float y = (float) guiH /2; Matrix4f_identity(&ViewMatrix); Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - - glApplyProjection(renderer,&ViewMatrix,&ProjectionMatrix); + camera->ViewMatrix = ViewMatrix; + camera->ProjectionMatrix = ProjectionMatrix; + glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); glActiveTexture(GL_TEXTURE1); @@ -641,8 +654,20 @@ static void glSetGuiProjection(Renderer* renderer, int32_t guiW, int32_t guiH, M flushBatch(gl); // GL surfaces are stored bottom-up and draw_surface samples them with vertical flip. - gl->base.CameraCurrent = 0; //replace this number with whatver camera ID is used for the GUI. maybe some special ID? I have no idea how it should be - //GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.CameraCurrent); use this or something later + gl->base.CameraCurrent = GUI_CAMERA; + GMLCamera* camera = &renderer->runner->guiCamera; + camera->allocated = true; + camera->viewX = 0.0; + camera->viewY = 0.0; + camera->viewWidth = guiW; + camera->viewHeight = guiH; + camera->borderX = 0; + camera->borderY = 0; + camera->speedX = 0; + camera->speedY = 0; + camera->objectId = -1; + camera->viewAngle = 0; + //yeah no I have no idea how to do the GUI Matrix4f ProjectionMatrix; Matrix4f_Orthographic(&ProjectionMatrix, (float) guiW, (float) guiH, 32000.0, 0.0); @@ -652,9 +677,9 @@ static void glSetGuiProjection(Renderer* renderer, int32_t guiW, int32_t guiH, M float y = (float) guiH * 0.5f; Matrix4f_identity(&ViewMatrix); Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - - glApplyProjection(renderer,&ViewMatrix,&ProjectionMatrix); - glShaderSettingsRefresh(renderer); + camera->ViewMatrix = ViewMatrix; + camera->ProjectionMatrix = ProjectionMatrix; + glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); } static void glEndGUI(Renderer* renderer) { diff --git a/src/renderer.h b/src/renderer.h index 4da9d52eb..59d42234f 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -40,7 +40,8 @@ #define MAX_VS_LIGHTS 8 #define MAX_TEXTURE_STAGES 8 - +//these 2 IDs are just IDs I simply made up, replace them with proper ones eventually oki? +#define GUI_CAMERA 4096 #define SURFACE_CAMERA 8192 // Sentinel returned by ensureApplicationSurface on platforms that don't back the application_surface with a real entry in the renderer's surface table. diff --git a/src/runner.c b/src/runner.c index a6ce16dc9..0b7fd8618 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1323,6 +1323,7 @@ GMLCamera* Runner_getCameraById(Runner* runner, int32_t id) { else if (MAX_DEFAULT_ROOM_CAMERAS > id) camera = &runner->defaultCameras[id]; else if (MAX_CAMERAS > id) camera = &runner->userCameras[id - MAX_DEFAULT_ROOM_CAMERAS]; else if (id == SURFACE_CAMERA) camera = &runner->surfaceCamera; + else if (id == GUI_CAMERA) camera = &runner->guiCamera; else return nullptr; if (!camera->allocated) return nullptr; return camera; diff --git a/src/runner.h b/src/runner.h index d76cdc099..ede102c6b 100644 --- a/src/runner.h +++ b/src/runner.h @@ -473,6 +473,7 @@ struct Runner { GMLCamera defaultCameras[MAX_DEFAULT_ROOM_CAMERAS]; GMLCamera userCameras[MAX_USER_CAMERAS]; GMLCamera surfaceCamera; + GMLCamera guiCamera; RunnerGamepadState* gamepads; RuntimeBackground backgrounds[8]; uint32_t backgroundColor; // runtime-mutable (BGR format) From 7014b01101cbae0a265680438e28427238abacf4 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Sat, 20 Jun 2026 14:33:57 +0200 Subject: [PATCH 16/21] fix merge conflict --- src/gl/gl_renderer.c | 10 +++++----- src/runner.c | 35 +++++++++++++++++++---------------- src/vm_builtins.c | 2 +- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index ff45ae949..32eb78692 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -635,8 +635,8 @@ static void glBeginGUI(Renderer* renderer, MAYBE_UNUSED int32_t guiW, MAYBE_UNUS Matrix4f_Orthographic(&ProjectionMatrix, (float) guiW, (float) guiH, 32000.0, 0.0); Matrix4f ViewMatrix; - float x = (float) guiW /2; - float y = (float) guiH /2; + float x = (float) guiW * 0.5f; + float y = (float) guiH * 0.5f; Matrix4f_identity(&ViewMatrix); Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); camera->ViewMatrix = ViewMatrix; @@ -2076,11 +2076,11 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic } else { //camera will use full surface. Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) gl->surfaceWidth[surfaceId], (float) -gl->surfaceHeight[surfaceId], 32000.0, 0.0); + Matrix4f_Orthographic(&ProjectionMatrix, (float) gl->surfaceWidth[surfaceId], -((float) gl->surfaceHeight[surfaceId]), 32000.0, 0.0); Matrix4f ViewMatrix; - float x = (float) gl->surfaceWidth[surfaceId] /2; - float y = (float) gl->surfaceHeight[surfaceId] /2; + float x = (float) gl->surfaceWidth[surfaceId] * 0.5f; + float y = (float) gl->surfaceHeight[surfaceId] * 0.5f; Matrix4f_identity(&ViewMatrix); Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); gl->base.CameraCurrent = SURFACE_CAMERA; diff --git a/src/runner.c b/src/runner.c index 0b7fd8618..ff125a1db 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1181,28 +1181,31 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh } if (!anyViewRendered) { - // See GameMaker-HTML5's "DrawViews", in specific the !m_enableviews path - // When views aren't used, the room width/height is used - int32_t viewX, viewY, viewW, viewH; - expandViewAxis(0, (int32_t) runner->currentRoom->width, gameW, widescreenBaseW, &viewX, &viewW); - expandViewAxis(0, (int32_t) runner->currentRoom->height, gameH, widescreenBaseH, &viewY, &viewH); - applyFreeCamera(runner, &viewX, &viewY, &viewW, &viewH); - renderer->vtable->beginView(renderer, viewX, viewY, viewW, viewH, 0, 0, gameW, gameH, 0); - + // No views enabled: render with default full-screen view. + // gameW/gameH already include the widescreen extra, shift the world origin by half of it on each grown axis so the original room stays centered and the revealed area is split evenly between the opposing edges. + runner->viewCurrent = 0; + GMLCamera* camera = Runner_getCameraForView(runner, (int32_t) runner->viewCurrent); + runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; + int32_t fullViewX = -(runner->widescreenExtraWidth / 2); + int32_t fullViewY = -(runner->widescreenExtraHeight / 2); + int32_t fullViewW = gameW; + int32_t fullViewH = gameH; + applyFreeCamera(runner, &fullViewX, &fullViewY, &fullViewW, &fullViewH); + //make default projection Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) gameW, (float) -gameH, 32000.0, 0.0); + Matrix4f_Orthographic(&ProjectionMatrix, (float) runner->currentRoom->width, -((float) runner->currentRoom->height), 32000.0, 0.0); Matrix4f ViewMatrix; - float x = (float) gameW /2; - float y = (float) gameH /2; + float x = (float) runner->currentRoom->width * 0.5f; + float y = (float) runner->currentRoom->height * 0.5f; Matrix4f_identity(&ViewMatrix); Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); if (camera != nullptr) { camera->viewX = 0; camera->viewY = 0; - camera->viewWidth = gameW; - camera->viewHeight = gameH; + camera->viewWidth = runner->currentRoom->width; + camera->viewHeight = runner->currentRoom->height; camera->viewAngle = 0.0; camera->ViewMatrix = ViewMatrix; camera->ProjectionMatrix = ProjectionMatrix; @@ -1349,11 +1352,11 @@ static void initDefaultCameraFromRoomView(GMLCamera* camera, RoomView* roomView) camera->viewAngle = 0; //make default projection Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) camera->viewWidth, (float) -camera->viewHeight, 32000.0, 0.0); + Matrix4f_Orthographic(&ProjectionMatrix, (float) camera->viewWidth, -((float) camera->viewHeight), 32000.0, 0.0); Matrix4f ViewMatrix; - float x = camera->viewX + camera->viewWidth/2; - float y = camera->viewY + camera->viewHeight/2; + float x = camera->viewX + camera->viewWidth * 0.5f; + float y = camera->viewY + camera->viewHeight * 0.5f; Matrix4f_identity(&ViewMatrix); Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); Matrix4f_translate(&ViewMatrix, x, y, 0.0f); diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 315d97add..61118a825 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -228,7 +228,7 @@ static void UpdateCameraViewSimple(GMLCamera* camera) { Matrix4f_translate(&ViewMatrix, -x, -y, 0.0f); Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) camera->viewWidth, (float) -camera->viewHeight, 32000.0, 0.0); + Matrix4f_Orthographic(&ProjectionMatrix, (float) camera->viewWidth, -((float) camera->viewHeight), 32000.0, 0.0); camera->ViewMatrix = ViewMatrix; From 9aa731133226a851232869a9b71c78125a9bd44e Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Sun, 21 Jun 2026 15:37:14 +0200 Subject: [PATCH 17/21] fix little oversight and PS2 build --- src/ps2/gs_renderer.c | 3 ++- src/runner.c | 17 ++++++++--------- src/vm_builtins.c | 1 + 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/ps2/gs_renderer.c b/src/ps2/gs_renderer.c index 55b2be668..4031a6ca4 100644 --- a/src/ps2/gs_renderer.c +++ b/src/ps2/gs_renderer.c @@ -1157,8 +1157,9 @@ static void gsEndView(MAYBE_UNUSED Renderer* renderer) { // No-op } -static void gsApplyProjection(MAYBE_UNUSED Renderer* renderer, MAYBE_UNUSED const Matrix4f* worldToClip) { +static void gsApplyProjection(MAYBE_UNUSED Renderer* renderer, MAYBE_UNUSED const Matrix4f* ViewMatrix, MAYBE_UNUSED const Matrix4f* ProjectionMatrix) { // No-op + //Um but I do feel like the PS2 should be capable of this though? } static void gsSetGuiProjection(Renderer* renderer, int32_t guiW, int32_t guiH, MAYBE_UNUSED int32_t portW, MAYBE_UNUSED int32_t portH, MAYBE_UNUSED bool renderingToUserSurface) { diff --git a/src/runner.c b/src/runner.c index ff125a1db..0fcbf0740 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1181,17 +1181,16 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh } if (!anyViewRendered) { - // No views enabled: render with default full-screen view. - // gameW/gameH already include the widescreen extra, shift the world origin by half of it on each grown axis so the original room stays centered and the revealed area is split evenly between the opposing edges. runner->viewCurrent = 0; GMLCamera* camera = Runner_getCameraForView(runner, (int32_t) runner->viewCurrent); runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; - int32_t fullViewX = -(runner->widescreenExtraWidth / 2); - int32_t fullViewY = -(runner->widescreenExtraHeight / 2); - int32_t fullViewW = gameW; - int32_t fullViewH = gameH; - applyFreeCamera(runner, &fullViewX, &fullViewY, &fullViewW, &fullViewH); - + // See GameMaker-HTML5's "DrawViews", in specific the !m_enableviews path + // When views aren't used, the room width/height is used + int32_t viewX, viewY, viewW, viewH; + expandViewAxis(0, (int32_t) runner->currentRoom->width, gameW, widescreenBaseW, &viewX, &viewW); + expandViewAxis(0, (int32_t) runner->currentRoom->height, gameH, widescreenBaseH, &viewY, &viewH); + applyFreeCamera(runner, &viewX, &viewY, &viewW, &viewH); + //whenever somebody feels like it, do make that free cam thingy work with this //make default projection Matrix4f ProjectionMatrix; Matrix4f_Orthographic(&ProjectionMatrix, (float) runner->currentRoom->width, -((float) runner->currentRoom->height), 32000.0, 0.0); @@ -1211,7 +1210,7 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh camera->ProjectionMatrix = ProjectionMatrix; } - renderer->vtable->beginView(renderer, fullViewX, fullViewY, fullViewW, fullViewH, 0, 0, gameW, gameH, 0.0f); + renderer->vtable->beginView(renderer, viewX, viewY, viewW, viewH, 0, 0, gameW, gameH, 0); Runner_draw(runner); diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 61118a825..0f0e20124 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -3572,6 +3572,7 @@ static RValue builtin_camera_set_view_size(VMContext* ctx, RValue* args, int32_t if (camera != nullptr) { camera->viewWidth = RValue_toInt32(args[1]); camera->viewHeight = RValue_toInt32(args[2]); + UpdateCameraViewSimple(camera); } return RValue_makeUndefined(); } From 0dfcb018ae60d2d5e0a2e3968edece1f2d99f30f Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Sun, 21 Jun 2026 17:21:31 +0200 Subject: [PATCH 18/21] fix object follow --- src/runner.c | 23 +++++++++++++++++++++++ src/runner.h | 4 ++++ src/vm_builtins.c | 21 --------------------- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/runner.c b/src/runner.c index 0fcbf0740..27b06b1ab 100644 --- a/src/runner.c +++ b/src/runner.c @@ -2339,6 +2339,28 @@ void Runner_destroyInstance(MAYBE_UNUSED Runner* runner, Instance* inst, bool ru #endif } +void UpdateCameraViewSimple(GMLCamera* camera) { + + float x = camera->viewX + camera->viewWidth/2; + float y = camera->viewY + camera->viewHeight/2; + Matrix4f ViewMatrix; + Matrix4f_identity(&ViewMatrix); + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + Matrix4f_translate(&ViewMatrix, x, y, 0.0f); + Matrix4f_rotateZ(&ViewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); + Matrix4f_translate(&ViewMatrix, -x, -y, 0.0f); + + Matrix4f ProjectionMatrix; + Matrix4f_Orthographic(&ProjectionMatrix, (float) camera->viewWidth, -((float) camera->viewHeight), 32000.0, 0.0); + + + camera->ViewMatrix = ViewMatrix; + camera->ProjectionMatrix = ProjectionMatrix; + +} + + + RuntimeLayer* Runner_findRuntimeLayerByName(Runner* runner, char* name) { size_t count = arrlenu(runner->runtimeLayers); repeat(count, i) { @@ -3250,6 +3272,7 @@ static void updateViews(Runner* runner) { int32_t iy = (int32_t) GMLReal_floor(target->y); camera->viewX = followAxis(camera->viewX, camera->viewWidth, ix, camera->borderX, camera->speedX, (int32_t) room->width); camera->viewY = followAxis(camera->viewY, camera->viewHeight, iy, camera->borderY, camera->speedY, (int32_t) room->height); + UpdateCameraViewSimple(camera); } } } diff --git a/src/runner.h b/src/runner.h index ede102c6b..121c4edf5 100644 --- a/src/runner.h +++ b/src/runner.h @@ -673,6 +673,10 @@ void Runner_removeInstanceFromObjectLists(Runner* runner, Instance* inst); // Reset every per-object list to length 0 without releasing the backing arrays. void Runner_clearAllObjectLists(Runner* runner); +// Update the Camera with simple things! +void UpdateCameraViewSimple(GMLCamera* camera); + + // Push a snapshot of instancesByObject[targetObjIndex] onto runner->instanceSnapshots. Returns the base offset where this snapshot begins. // The length is arrlen(runner->instanceSnapshots) - base. // Invalid indices or empty buckets push zero entries (base == current arena length). diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 0f0e20124..6b3b9ce0f 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -216,27 +216,6 @@ static DsStack* dsStackGet(Runner* runner, int32_t id) { return &runner->dsStackPool[id]; } -static void UpdateCameraViewSimple(GMLCamera* camera) { - - float x = camera->viewX + camera->viewWidth/2; - float y = camera->viewY + camera->viewHeight/2; - Matrix4f ViewMatrix; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - Matrix4f_translate(&ViewMatrix, x, y, 0.0f); - Matrix4f_rotateZ(&ViewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); - Matrix4f_translate(&ViewMatrix, -x, -y, 0.0f); - - Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) camera->viewWidth, -((float) camera->viewHeight), 32000.0, 0.0); - - - camera->ViewMatrix = ViewMatrix; - camera->ProjectionMatrix = ProjectionMatrix; - -} - - // ===[ BUILT-IN VARIABLE GET/SET ]=== static bool isValidAlarmIndex(int alarmIndex) { From cd4e7e6782a9ec6f19feb02afe2bb7e44a60df7c Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Sun, 21 Jun 2026 21:40:52 +0200 Subject: [PATCH 19/21] rebase AGAIN --- src/vm_builtins.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 6b3b9ce0f..b83687177 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -2914,7 +2914,7 @@ static RValue builtin_matrix_get(MAYBE_UNUSED VMContext *ctx, RValue *args, int3 if (toPrevMatrix && !rvalueIsMatrix(args[1])) return RValue_makeUndefined(); if (!toPrevMatrix) { - return RValue_makeArray(matrixToGml(&ctx->runner->renderer->gmlMatrices[Matrix])); + return RValue_makeArray(matrixToGml(ctx->dataWin->gen8.wadVersion, &ctx->runner->renderer->gmlMatrices[Matrix])); } else { repeat (16, i) { *GMLArray_slot(destArray, i) = RValue_makeReal(ctx->runner->renderer->gmlMatrices[Matrix].m[i]); @@ -3479,14 +3479,14 @@ static RValue builtin_camera_get_view_mat(VMContext* ctx, RValue* args, int32_t Runner* runner = ctx->runner; GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); if (camera == nullptr) return RValue_makeUndefined(); - return RValue_makeArray(matrixToGml(&camera->ViewMatrix)); + return RValue_makeArray(matrixToGml(ctx->dataWin->gen8.wadVersion, &camera->ViewMatrix)); } static RValue builtin_camera_get_proj_mat(VMContext* ctx, RValue* args, int32_t argCount) { Runner* runner = ctx->runner; GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); if (camera == nullptr) return RValue_makeUndefined(); - return RValue_makeArray(matrixToGml(&camera->ProjectionMatrix)); + return RValue_makeArray(matrixToGml(ctx->dataWin->gen8.wadVersion, &camera->ProjectionMatrix)); } static RValue builtin_camera_set_proj_mat(VMContext* ctx, RValue* args, int32_t argCount) { From bd5f64f8cafc055836f58cfaa9e76e5575502b0a Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Mon, 22 Jun 2026 01:32:35 +0200 Subject: [PATCH 20/21] trying to be more consistent with the project's conventions --- src/gl/gl_renderer.c | 148 ++++++++++++++--------------- src/gl_legacy/gl_legacy_renderer.c | 4 +- src/matrix_math.h | 4 +- src/ps2/gs_renderer.c | 2 +- src/renderer.h | 4 +- src/runner.c | 77 ++++++++------- src/runner.h | 7 +- src/vm_builtins.c | 64 ++++++------- 8 files changed, 154 insertions(+), 156 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index 32eb78692..de3468ece 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -250,9 +250,9 @@ static void glInit(Renderer* renderer, DataWin* dataWin) { GLRenderer* gl = (GLRenderer*) renderer; renderer->dataWin = dataWin; - Matrix4f World; - Matrix4f_identity(&World); - renderer->gmlMatrices[MATRIX_WORLD] = World; + Matrix4f world; + Matrix4f_identity(&world); + renderer->gmlMatrices[MATRIX_WORLD] = world; GMLShader* defaultShader = safeCalloc(1, sizeof(GMLShader)); bool success = compileProgram(defaultShader, "default", defaultVertexShaderSource, defaultFragmentShaderSource, 0, nullptr); @@ -404,14 +404,14 @@ static void glGpuSetShader(Renderer* renderer, int32_t shaderIndex) { GLShaderUniform* gmAlphaTestEnabledUniform = findShaderUniformByName(gmlShader, "gm_AlphaTestEnabled"); GLShaderUniform* gmAlphaRefValue = findShaderUniformByName(gmlShader, "gm_AlphaRefValue"); - Matrix4f FlippedClip[MATRICES_MAX]; + Matrix4f flippedClip[MATRICES_MAX]; for (int32_t i = 0; i < MATRICES_MAX; i++) { - FlippedClip[i] = renderer->gmlMatrices[i]; - Matrix4f_flipClipY(&FlippedClip[i]); + flippedClip[i] = renderer->gmlMatrices[i]; + Matrix4f_flipClipY(&flippedClip[i]); } if (gmMatricesUniform != nullptr) { - glUniformMatrix4fv(gmMatricesUniform->location, 5, GL_FALSE, FlippedClip[0].m); + glUniformMatrix4fv(gmMatricesUniform->location, 5, GL_FALSE, flippedClip[0].m); } if (gmFogColourUniform != nullptr) { glUniform1i(gmFogColourUniform->location, gl->fogColor); @@ -443,13 +443,13 @@ static void glShaderSettingsRefresh(Renderer* renderer) { GLShaderUniform* uAlphaTestRef = findShaderUniformByName(gl->defaultShaderProgram, "uAlphaTestRef"); GLShaderUniform* uAlphaTestEnabled = findShaderUniformByName(gl->defaultShaderProgram, "uAlphaTestEnabled"); GLShaderUniform* uTexture = findShaderUniformByName(gl->defaultShaderProgram, "uTexture"); - Matrix4f FlippedClip[MATRICES_MAX]; + Matrix4f flippedClip[MATRICES_MAX]; for (int32_t i = 0; i < MATRICES_MAX; i++) { - FlippedClip[i] = renderer->gmlMatrices[i]; - Matrix4f_flipClipY(&FlippedClip[i]); + flippedClip[i] = renderer->gmlMatrices[i]; + Matrix4f_flipClipY(&flippedClip[i]); } - glUniformMatrix4fv(uWorldViewProjection->location, 1, GL_FALSE, FlippedClip[MATRIX_WORLD_VIEW_PROJECTION].m); + glUniformMatrix4fv(uWorldViewProjection->location, 1, GL_FALSE, flippedClip[MATRIX_WORLD_VIEW_PROJECTION].m); glUniform4f(uFogColor->location, fogR, fogG, fogB, gl->fogEnable ? 1.0f : 0.0f); glUniform1f(uAlphaTestRef->location, gl->alphaTestRef); glUniform1i(uAlphaTestEnabled->location, gl->alphaTestEnable); @@ -458,26 +458,26 @@ static void glShaderSettingsRefresh(Renderer* renderer) { } // camera_apply: swap the active world->clip projection on the current target without touching its viewport. -static void glApplyProjection(Renderer* renderer, const Matrix4f* ViewMatrix,const Matrix4f* ProjectionMatrix) { +static void glApplyProjection(Renderer* renderer, const Matrix4f* viewMatrix,const Matrix4f* projectionMatrix) { GLRenderer* gl = (GLRenderer*) renderer; // Flush first so pending quads draw under the projection they were issued with. flushBatch(gl); - Matrix4f World = renderer->gmlMatrices[MATRIX_WORLD]; - Matrix4f View = *ViewMatrix; - Matrix4f Projection = *ProjectionMatrix; + Matrix4f world = renderer->gmlMatrices[MATRIX_WORLD]; + Matrix4f view = *viewMatrix; + Matrix4f projection = *projectionMatrix; - Matrix4f WorldView; - Matrix4f_multiply(&WorldView, &View, &World); + Matrix4f worldView; + Matrix4f_multiply(&worldView, &view, &world); - Matrix4f WorldViewProjection; - Matrix4f_multiply(&WorldViewProjection, &Projection, &WorldView); + Matrix4f worldViewProjection; + Matrix4f_multiply(&worldViewProjection, &projection, &worldView); - renderer->gmlMatrices[MATRIX_VIEW] = View; - renderer->gmlMatrices[MATRIX_PROJECTION] = Projection; - renderer->gmlMatrices[MATRIX_WORLD_VIEW] = WorldView; - renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = WorldViewProjection; + renderer->gmlMatrices[MATRIX_VIEW] = view; + renderer->gmlMatrices[MATRIX_PROJECTION] = projection; + renderer->gmlMatrices[MATRIX_WORLD_VIEW] = worldView; + renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = worldViewProjection; //oh my I hope it's good enough. glShaderSettingsRefresh(renderer); } @@ -575,14 +575,14 @@ static void glBeginView(Renderer* renderer, MAYBE_UNUSED int32_t viewX, MAYBE_UN glEnable(GL_SCISSOR_TEST); glScissor(portX, portY, portW, portH); - int32_t ViewCurrent = 0; + int32_t viewCurrent = 0; if (renderer->runner->viewsEnabled) { - ViewCurrent = renderer->runner->viewCurrent; + viewCurrent = renderer->runner->viewCurrent; } - RuntimeView* view = &renderer->runner->views[ViewCurrent]; - gl->base.CameraCurrent = view->cameraId; - GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.CameraCurrent); - glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); + RuntimeView* view = &renderer->runner->views[viewCurrent]; + gl->base.cameraCurrent = view->cameraId; + GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.cameraCurrent); + glApplyProjection(renderer,&camera->viewMatrix,&camera->projectionMatrix); glShaderSettingsRefresh(renderer); glActiveTexture(GL_TEXTURE1); @@ -617,7 +617,7 @@ static void glBeginGUI(Renderer* renderer, MAYBE_UNUSED int32_t guiW, MAYBE_UNUS glEnable(GL_SCISSOR_TEST); //I dunno hopefully this is at least somewhat correct... - gl->base.CameraCurrent = GUI_CAMERA; + gl->base.cameraCurrent = GUI_CAMERA; GMLCamera* camera = &renderer->runner->guiCamera; camera->allocated = true; camera->viewX = 0.0; @@ -631,17 +631,17 @@ static void glBeginGUI(Renderer* renderer, MAYBE_UNUSED int32_t guiW, MAYBE_UNUS camera->objectId = -1; camera->viewAngle = 0; - Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) guiW, (float) guiH, 32000.0, 0.0); + Matrix4f projectionMatrix; + Matrix4f_orthographic(&projectionMatrix, (float) guiW, (float) guiH, 32000.0, 0.0); - Matrix4f ViewMatrix; + Matrix4f viewMatrix; float x = (float) guiW * 0.5f; float y = (float) guiH * 0.5f; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - camera->ViewMatrix = ViewMatrix; - camera->ProjectionMatrix = ProjectionMatrix; - glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); + Matrix4f_identity(&viewMatrix); + Matrix4f_lookAt(&viewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + camera->viewMatrix = viewMatrix; + camera->projectionMatrix = projectionMatrix; + glApplyProjection(renderer,&camera->viewMatrix,&camera->projectionMatrix); glActiveTexture(GL_TEXTURE1); @@ -654,7 +654,7 @@ static void glSetGuiProjection(Renderer* renderer, int32_t guiW, int32_t guiH, M flushBatch(gl); // GL surfaces are stored bottom-up and draw_surface samples them with vertical flip. - gl->base.CameraCurrent = GUI_CAMERA; + gl->base.cameraCurrent = GUI_CAMERA; GMLCamera* camera = &renderer->runner->guiCamera; camera->allocated = true; camera->viewX = 0.0; @@ -669,17 +669,17 @@ static void glSetGuiProjection(Renderer* renderer, int32_t guiW, int32_t guiH, M camera->viewAngle = 0; //yeah no I have no idea how to do the GUI - Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) guiW, (float) guiH, 32000.0, 0.0); - if (renderingToUserSurface) Matrix4f_flipClipY(&ProjectionMatrix); - Matrix4f ViewMatrix; + Matrix4f projectionMatrix; + Matrix4f_orthographic(&projectionMatrix, (float) guiW, (float) guiH, 32000.0, 0.0); + if (renderingToUserSurface) Matrix4f_flipClipY(&projectionMatrix); + Matrix4f viewMatrix; float x = (float) guiW * 0.5f; float y = (float) guiH * 0.5f; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - camera->ViewMatrix = ViewMatrix; - camera->ProjectionMatrix = ProjectionMatrix; - glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); + Matrix4f_identity(&viewMatrix); + Matrix4f_lookAt(&viewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + camera->viewMatrix = viewMatrix; + camera->projectionMatrix = projectionMatrix; + glApplyProjection(renderer,&camera->viewMatrix,&camera->projectionMatrix); } static void glEndGUI(Renderer* renderer) { @@ -2044,13 +2044,13 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic GLRenderer* gl = (GLRenderer*) renderer; flushBatch(gl); - int32_t ViewCurrent = 0; + int32_t viewCurrent = 0; if (renderer->runner->viewsEnabled) { - ViewCurrent = renderer->runner->viewCurrent; + viewCurrent = renderer->runner->viewCurrent; } - RuntimeView* view = &renderer->runner->views[ViewCurrent]; - gl->base.CameraCurrent = view->cameraId; - GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.CameraCurrent); + RuntimeView* view = &renderer->runner->views[viewCurrent]; + gl->base.cameraCurrent = view->cameraId; + GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.cameraCurrent); if (0 > surfaceId || (uint32_t) surfaceId >= gl->surfaceCount) return false; if (gl->surfaces[surfaceId] == 0) return false; @@ -2061,7 +2061,7 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic glViewport(gl->base.CPortX, gl->base.CPortY, gl->base.CPortW, gl->base.CPortH); glEnable(GL_SCISSOR_TEST); - glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); + glApplyProjection(renderer,&camera->viewMatrix,&camera->projectionMatrix); return true; } @@ -2071,19 +2071,19 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic //the surface belongs to the view we are rending, we use the view's camera. glViewport(0, 0, gl->surfaceWidth[surfaceId], gl->surfaceHeight[surfaceId]); glDisable(GL_SCISSOR_TEST); - glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); + glApplyProjection(renderer,&camera->viewMatrix,&camera->projectionMatrix); return true; } else { //camera will use full surface. - Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) gl->surfaceWidth[surfaceId], -((float) gl->surfaceHeight[surfaceId]), 32000.0, 0.0); + Matrix4f projectionMatrix; + Matrix4f_orthographic(&projectionMatrix, (float) gl->surfaceWidth[surfaceId], -((float) gl->surfaceHeight[surfaceId]), 32000.0, 0.0); - Matrix4f ViewMatrix; + Matrix4f viewMatrix; float x = (float) gl->surfaceWidth[surfaceId] * 0.5f; float y = (float) gl->surfaceHeight[surfaceId] * 0.5f; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - gl->base.CameraCurrent = SURFACE_CAMERA; + Matrix4f_identity(&viewMatrix); + Matrix4f_lookAt(&viewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + gl->base.cameraCurrent = SURFACE_CAMERA; GMLCamera* camera = &renderer->runner->surfaceCamera; @@ -2099,11 +2099,11 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic camera->objectId = -1; camera->viewAngle = 0; - camera->ProjectionMatrix = ProjectionMatrix; - camera->ViewMatrix = ViewMatrix; + camera->projectionMatrix = projectionMatrix; + camera->viewMatrix = viewMatrix; glViewport(0, 0, gl->surfaceWidth[surfaceId], gl->surfaceHeight[surfaceId]); glDisable(GL_SCISSOR_TEST); - glApplyProjection(renderer, &ViewMatrix,&ProjectionMatrix); + glApplyProjection(renderer, &viewMatrix,&projectionMatrix); return true; } @@ -2603,18 +2603,18 @@ static void glSetMatrix(Renderer* renderer, int32_t MatrixType, Matrix4f Matrix) renderer->gmlMatrices[MatrixType] = Matrix; //yeah just recalculate everything when we change a matrix //TODO LATR: only allow these 3 to be changed directly, other ones should only be allowed to be calculated by the rest of the function - Matrix4f World = renderer->gmlMatrices[MATRIX_WORLD]; - Matrix4f View = renderer->gmlMatrices[MATRIX_VIEW]; - Matrix4f Projection = renderer->gmlMatrices[MATRIX_PROJECTION]; + Matrix4f world = renderer->gmlMatrices[MATRIX_WORLD]; + Matrix4f view = renderer->gmlMatrices[MATRIX_VIEW]; + Matrix4f projection = renderer->gmlMatrices[MATRIX_PROJECTION]; - Matrix4f WorldView; - Matrix4f_multiply(&WorldView, &View, &World); + Matrix4f worldView; + Matrix4f_multiply(&worldView, &view, &world); - Matrix4f WorldViewProjection; - Matrix4f_multiply(&WorldViewProjection, &Projection, &WorldView); + Matrix4f worldViewProjection; + Matrix4f_multiply(&worldViewProjection, &projection, &worldView); - renderer->gmlMatrices[MATRIX_WORLD_VIEW] = WorldView; - renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = WorldViewProjection; + renderer->gmlMatrices[MATRIX_WORLD_VIEW] = worldView; + renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = worldViewProjection; glShaderSettingsRefresh(renderer); @@ -2701,6 +2701,6 @@ Renderer* GLRenderer_create(void) { gl->base.drawValign = 0; gl->base.circlePrecision = 24; gl->base.currentShader = -1; - gl->base.CameraCurrent = 0; + gl->base.cameraCurrent = 0; return (Renderer*) gl; } diff --git a/src/gl_legacy/gl_legacy_renderer.c b/src/gl_legacy/gl_legacy_renderer.c index b7437eaed..5d808940e 100644 --- a/src/gl_legacy/gl_legacy_renderer.c +++ b/src/gl_legacy/gl_legacy_renderer.c @@ -186,8 +186,8 @@ static void glEndView(MAYBE_UNUSED Renderer* renderer) { } // camera_apply: swap the active world->clip projection on the current target without touching its viewport. -static void glApplyProjection(Renderer* renderer, MAYBE_UNUSED const Matrix4f* ViewMatrix, MAYBE_UNUSED const Matrix4f* ProjectionMatrix) { - Matrix4f projection = *ProjectionMatrix; //fix it later +static void glApplyProjection(Renderer* renderer, MAYBE_UNUSED const Matrix4f* viewMatrix, MAYBE_UNUSED const Matrix4f* projectionMatrix) { + Matrix4f projection = *projectionMatrix; //fix it later Matrix4f_flipClipY(&projection); glMatrixMode(GL_PROJECTION); glLoadMatrixf(projection.m); diff --git a/src/matrix_math.h b/src/matrix_math.h index 7c15807a6..9bc8700f7 100644 --- a/src/matrix_math.h +++ b/src/matrix_math.h @@ -51,7 +51,7 @@ static inline Matrix4f* Matrix4f_multiply(Matrix4f* dest, const Matrix4f* a, con return dest; } -static inline Matrix4f* Matrix4f_LookAt(Matrix4f* dest, float x_from, float y_from, float z_from, float x_to, float y_to, float z_to, float x_up, float y_up, float z_up) { +static inline Matrix4f* Matrix4f_lookAt(Matrix4f* dest, float x_from, float y_from, float z_from, float x_to, float y_to, float z_to, float x_up, float y_up, float z_up) { double xFrom = x_from; double yFrom = y_from; @@ -119,7 +119,7 @@ static inline Matrix4f* Matrix4f_LookAt(Matrix4f* dest, float x_from, float y_fr return dest; } -static inline Matrix4f* Matrix4f_Orthographic(Matrix4f* dest, float width, float height, float zfar, float znear) { +static inline Matrix4f* Matrix4f_orthographic(Matrix4f* dest, float width, float height, float zfar, float znear) { memset(dest->m, 0, sizeof(dest->m)); dest->m[Matrix_getIndex(0,0)] = 2.0f / width; diff --git a/src/ps2/gs_renderer.c b/src/ps2/gs_renderer.c index 4031a6ca4..d04ed3585 100644 --- a/src/ps2/gs_renderer.c +++ b/src/ps2/gs_renderer.c @@ -1157,7 +1157,7 @@ static void gsEndView(MAYBE_UNUSED Renderer* renderer) { // No-op } -static void gsApplyProjection(MAYBE_UNUSED Renderer* renderer, MAYBE_UNUSED const Matrix4f* ViewMatrix, MAYBE_UNUSED const Matrix4f* ProjectionMatrix) { +static void gsApplyProjection(MAYBE_UNUSED Renderer* renderer, MAYBE_UNUSED const Matrix4f* viewMatrix, MAYBE_UNUSED const Matrix4f* projectionMatrix) { // No-op //Um but I do feel like the PS2 should be capable of this though? } diff --git a/src/renderer.h b/src/renderer.h index 59d42234f..4f29e8028 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -75,7 +75,7 @@ typedef struct { void (*endFrameEnd)(Renderer* renderer); void (*beginView)(Renderer* renderer, int32_t viewX, int32_t viewY, int32_t viewW, int32_t viewH, int32_t portX, int32_t portY, int32_t portW, int32_t portH, float viewAngle); void (*endView)(Renderer* renderer); - void (*applyProjection)(Renderer* renderer, const Matrix4f* ViewMatrix,const Matrix4f* ProjectionMatrix); + void (*applyProjection)(Renderer* renderer, const Matrix4f* viewMatrix,const Matrix4f* projectionMatrix); // GUI pass: coordinates are (0,0)..(guiW,guiH) mapped to the current view's port rect. Called after endView. // targetSurfaceId is the surface the pass renders into, or RENDER_TARGET_HOST_FRAMEBUFFER. void (*beginGUI)(Renderer* renderer, int32_t guiW, int32_t guiH, int32_t portX, int32_t portY, int32_t portW, int32_t portH, int32_t targetSurfaceId); @@ -175,7 +175,7 @@ struct Renderer { Runner* runner; Matrix4f gmlMatrices[MATRICES_MAX]; int32_t currentShader; - int32_t CameraCurrent; + int32_t cameraCurrent; }; // ===[ Shared Helpers (platform-agnostic) ]=== diff --git a/src/runner.c b/src/runner.c index 27b06b1ab..c123f6370 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1137,14 +1137,14 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh if (runner->drawBackgroundColor) renderer->vtable->clearScreen(renderer, runner->currentRoom->backgroundColor, 1.0f); - Matrix4f ViewMatrix = camera->ViewMatrix; - Matrix4f ProjectionMatrix = camera->ProjectionMatrix; - runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); + Matrix4f viewMatrix = camera->viewMatrix; + Matrix4f projectionMatrix = camera->projectionMatrix; + runner->renderer->vtable->applyProjection(runner->renderer, &viewMatrix, &projectionMatrix); runner->viewCurrent = (int32_t) vi; - runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; - runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); + runner->renderer->cameraCurrent = runner->views[runner->viewCurrent].cameraId; + runner->renderer->vtable->applyProjection(runner->renderer, &viewMatrix, &projectionMatrix); Runner_draw(runner); @@ -1167,7 +1167,7 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh float viewAngle = camera->viewAngle; runner->viewCurrent = (int32_t) vi; - runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; + runner->renderer->cameraCurrent = runner->views[runner->viewCurrent].cameraId; renderer->vtable->beginView(renderer, viewX, viewY, viewW, viewH, portX, portY, portW, portH, viewAngle); Runner_draw(runner); @@ -1183,7 +1183,7 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh if (!anyViewRendered) { runner->viewCurrent = 0; GMLCamera* camera = Runner_getCameraForView(runner, (int32_t) runner->viewCurrent); - runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; + runner->renderer->cameraCurrent = runner->views[runner->viewCurrent].cameraId; // See GameMaker-HTML5's "DrawViews", in specific the !m_enableviews path // When views aren't used, the room width/height is used int32_t viewX, viewY, viewW, viewH; @@ -1192,22 +1192,22 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh applyFreeCamera(runner, &viewX, &viewY, &viewW, &viewH); //whenever somebody feels like it, do make that free cam thingy work with this //make default projection - Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) runner->currentRoom->width, -((float) runner->currentRoom->height), 32000.0, 0.0); + Matrix4f projectionMatrix; + Matrix4f_orthographic(&projectionMatrix, (float) runner->currentRoom->width, -((float) runner->currentRoom->height), 32000.0, 0.0); - Matrix4f ViewMatrix; + Matrix4f viewMatrix; float x = (float) runner->currentRoom->width * 0.5f; float y = (float) runner->currentRoom->height * 0.5f; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + Matrix4f_identity(&viewMatrix); + Matrix4f_lookAt(&viewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); if (camera != nullptr) { camera->viewX = 0; camera->viewY = 0; camera->viewWidth = runner->currentRoom->width; camera->viewHeight = runner->currentRoom->height; camera->viewAngle = 0.0; - camera->ViewMatrix = ViewMatrix; - camera->ProjectionMatrix = ProjectionMatrix; + camera->viewMatrix = viewMatrix; + camera->projectionMatrix = projectionMatrix; } renderer->vtable->beginView(renderer, viewX, viewY, viewW, viewH, 0, 0, gameW, gameH, 0); @@ -1222,7 +1222,7 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh // Reset view_current to 0 so non-Draw events (Step, Alarm, Create) see view_current = 0 runner->viewCurrent = 0; - runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; + runner->renderer->cameraCurrent = runner->views[runner->viewCurrent].cameraId; } // ===[ Instance Creation Helper ]=== @@ -1350,22 +1350,22 @@ static void initDefaultCameraFromRoomView(GMLCamera* camera, RoomView* roomView) camera->objectId = roomView->objectId; camera->viewAngle = 0; //make default projection - Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) camera->viewWidth, -((float) camera->viewHeight), 32000.0, 0.0); + Matrix4f projectionMatrix; + Matrix4f_orthographic(&projectionMatrix, (float) camera->viewWidth, -((float) camera->viewHeight), 32000.0, 0.0); - Matrix4f ViewMatrix; + Matrix4f viewMatrix; float x = camera->viewX + camera->viewWidth * 0.5f; float y = camera->viewY + camera->viewHeight * 0.5f; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - Matrix4f_translate(&ViewMatrix, x, y, 0.0f); - Matrix4f_rotateZ(&ViewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); - Matrix4f_translate(&ViewMatrix, -x, -y, 0.0f); + Matrix4f_identity(&viewMatrix); + Matrix4f_lookAt(&viewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + Matrix4f_translate(&viewMatrix, x, y, 0.0f); + Matrix4f_rotateZ(&viewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); + Matrix4f_translate(&viewMatrix, -x, -y, 0.0f); - camera->ProjectionMatrix = ProjectionMatrix; - camera->ViewMatrix = ViewMatrix; + camera->projectionMatrix = projectionMatrix; + camera->viewMatrix = viewMatrix; } // Copies the viewport (port) properties and enabled flag from parsed room data. @@ -2339,23 +2339,22 @@ void Runner_destroyInstance(MAYBE_UNUSED Runner* runner, Instance* inst, bool ru #endif } -void UpdateCameraViewSimple(GMLCamera* camera) { +void Runner_updateCameraViewSimple(GMLCamera* camera) { float x = camera->viewX + camera->viewWidth/2; float y = camera->viewY + camera->viewHeight/2; - Matrix4f ViewMatrix; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - Matrix4f_translate(&ViewMatrix, x, y, 0.0f); - Matrix4f_rotateZ(&ViewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); - Matrix4f_translate(&ViewMatrix, -x, -y, 0.0f); - - Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) camera->viewWidth, -((float) camera->viewHeight), 32000.0, 0.0); + Matrix4f viewMatrix; + Matrix4f_identity(&viewMatrix); + Matrix4f_lookAt(&viewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + Matrix4f_translate(&viewMatrix, x, y, 0.0f); + Matrix4f_rotateZ(&viewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); + Matrix4f_translate(&viewMatrix, -x, -y, 0.0f); + + Matrix4f projectionMatrix; + Matrix4f_orthographic(&projectionMatrix, (float) camera->viewWidth, -((float) camera->viewHeight), 32000.0, 0.0); - - camera->ViewMatrix = ViewMatrix; - camera->ProjectionMatrix = ProjectionMatrix; + camera->viewMatrix = viewMatrix; + camera->projectionMatrix = projectionMatrix; } @@ -3272,7 +3271,7 @@ static void updateViews(Runner* runner) { int32_t iy = (int32_t) GMLReal_floor(target->y); camera->viewX = followAxis(camera->viewX, camera->viewWidth, ix, camera->borderX, camera->speedX, (int32_t) room->width); camera->viewY = followAxis(camera->viewY, camera->viewHeight, iy, camera->borderY, camera->speedY, (int32_t) room->height); - UpdateCameraViewSimple(camera); + Runner_updateCameraViewSimple(camera); } } } diff --git a/src/runner.h b/src/runner.h index 121c4edf5..84d84c0af 100644 --- a/src/runner.h +++ b/src/runner.h @@ -155,8 +155,8 @@ typedef struct { int32_t speedY; int32_t objectId; // follow target (object index), -1 = none float viewAngle; - Matrix4f ViewMatrix; - Matrix4f ProjectionMatrix; + Matrix4f viewMatrix; + Matrix4f projectionMatrix; } GMLCamera; typedef struct { @@ -674,8 +674,7 @@ void Runner_removeInstanceFromObjectLists(Runner* runner, Instance* inst); void Runner_clearAllObjectLists(Runner* runner); // Update the Camera with simple things! -void UpdateCameraViewSimple(GMLCamera* camera); - +void Runner_updateCameraViewSimple(GMLCamera* camera); // Push a snapshot of instancesByObject[targetObjIndex] onto runner->instanceSnapshots. Returns the base offset where this snapshot begins. // The length is arrlen(runner->instanceSnapshots) - base. diff --git a/src/vm_builtins.c b/src/vm_builtins.c index b83687177..0faaa834c 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -1552,32 +1552,32 @@ void VMBuiltins_setVariable(VMContext* ctx, Instance* inst, int16_t builtinVarId case BUILTIN_VAR_VIEW_XVIEW: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { - camera->viewX = RValue_toReal(val); - UpdateCameraViewSimple(camera); + camera->viewX = RValue_toReal(val); + Runner_updateCameraViewSimple(camera); } return; } case BUILTIN_VAR_VIEW_YVIEW: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { - camera->viewY = RValue_toInt32(val); - UpdateCameraViewSimple(camera); + camera->viewY = RValue_toInt32(val); + Runner_updateCameraViewSimple(camera); } return; } case BUILTIN_VAR_VIEW_WVIEW: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { - camera->viewWidth = RValue_toInt32(val); - UpdateCameraViewSimple(camera); + camera->viewWidth = RValue_toInt32(val); + Runner_updateCameraViewSimple(camera); } return; } case BUILTIN_VAR_VIEW_HVIEW: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { - camera->viewHeight = RValue_toInt32(val); - UpdateCameraViewSimple(camera); + camera->viewHeight = RValue_toInt32(val); + Runner_updateCameraViewSimple(camera); } return; } @@ -1605,8 +1605,8 @@ void VMBuiltins_setVariable(VMContext* ctx, Instance* inst, int16_t builtinVarId case BUILTIN_VAR_VIEW_ANGLE: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { - camera->viewAngle = (float) RValue_toReal(val); - UpdateCameraViewSimple(camera); + camera->viewAngle = (float) RValue_toReal(val); + Runner_updateCameraViewSimple(camera); } return; } @@ -2862,7 +2862,7 @@ static RValue builtin_matrix_build_projection_ortho(MAYBE_UNUSED VMContext *ctx, if (toPrevMatrix && !rvalueIsMatrix(args[4])) return RValue_makeUndefined(); Matrix4f mat; - Matrix4f_Orthographic(&mat, width, height, zfar, znear); + Matrix4f_orthographic(&mat, width, height, zfar, znear); if (!toPrevMatrix) { return RValue_makeArray(matrixToGml(ctx->dataWin->gen8.wadVersion, &mat)); @@ -2907,29 +2907,29 @@ static RValue builtin_matrix_build_projection_perspective_fov(MAYBE_UNUSED VMCon } } static RValue builtin_matrix_get(MAYBE_UNUSED VMContext *ctx, RValue *args, int32_t argCount) { - int32_t Matrix = RValue_toInt32(args[0]); - if (Matrix < 0 || Matrix > 2) return RValue_makeUndefined(); + int32_t matrix = RValue_toInt32(args[0]); + if (matrix < 0 || matrix > 2) return RValue_makeUndefined(); bool toPrevMatrix = argCount == 2; GMLArray *destArray = toPrevMatrix ? args[1].array : nullptr; if (toPrevMatrix && !rvalueIsMatrix(args[1])) return RValue_makeUndefined(); if (!toPrevMatrix) { - return RValue_makeArray(matrixToGml(ctx->dataWin->gen8.wadVersion, &ctx->runner->renderer->gmlMatrices[Matrix])); + return RValue_makeArray(matrixToGml(ctx->dataWin->gen8.wadVersion, &ctx->runner->renderer->gmlMatrices[matrix])); } else { repeat (16, i) { - *GMLArray_slot(destArray, i) = RValue_makeReal(ctx->runner->renderer->gmlMatrices[Matrix].m[i]); + *GMLArray_slot(destArray, i) = RValue_makeReal(ctx->runner->renderer->gmlMatrices[matrix].m[i]); } return RValue_makeArrayWeak(destArray); } } static RValue builtin_matrix_set(MAYBE_UNUSED VMContext *ctx, RValue *args, int32_t argCount) { - int32_t Matrix = RValue_toInt32(args[0]); + int32_t matrix = RValue_toInt32(args[0]); Matrix4f m; matrixFromGml(&m, args[1].array); - if (Matrix < 0 || Matrix > 2) return RValue_makeUndefined(); + if (matrix < 0 || matrix > 2) return RValue_makeUndefined(); if (ctx->runner->renderer != nullptr) { - ctx->runner->renderer->vtable->setMatrix(ctx->runner->renderer, Matrix, m); + ctx->runner->renderer->vtable->setMatrix(ctx->runner->renderer, matrix, m); } return RValue_makeUndefined(); @@ -2953,7 +2953,7 @@ static RValue builtin_matrix_build_lookat(MAYBE_UNUSED VMContext *ctx, RValue *a Matrix4f matrix; Matrix4f_identity(&matrix); - Matrix4f_LookAt(&matrix, xFrom, yFrom, zFrom, xTo, yTo, zTo, xUp, yUp, zUp); + Matrix4f_lookAt(&matrix, xFrom, yFrom, zFrom, xTo, yTo, zTo, xUp, yUp, zUp); bool toPrevMatrix = argCount == 10; GMLArray *destArray = toPrevMatrix ? args[9].array : nullptr; @@ -3458,7 +3458,7 @@ static RValue builtin_camera_set_view_pos(VMContext* ctx, RValue* args, int32_t if (camera != nullptr) { camera->viewX = RValue_toReal(args[1]); camera->viewY = RValue_toReal(args[2]); - UpdateCameraViewSimple(camera); + Runner_updateCameraViewSimple(camera); } return RValue_makeUndefined(); } @@ -3471,7 +3471,7 @@ static RValue builtin_camera_set_view_mat(VMContext* ctx, RValue* args, int32_t if (camera == nullptr || !rvalueIsMatrix(args[1])) return RValue_makeUndefined(); Matrix4f m; matrixFromGml(&m, args[1].array); - camera->ViewMatrix = m; + camera->viewMatrix = m; return RValue_makeUndefined(); } @@ -3479,14 +3479,14 @@ static RValue builtin_camera_get_view_mat(VMContext* ctx, RValue* args, int32_t Runner* runner = ctx->runner; GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); if (camera == nullptr) return RValue_makeUndefined(); - return RValue_makeArray(matrixToGml(ctx->dataWin->gen8.wadVersion, &camera->ViewMatrix)); + return RValue_makeArray(matrixToGml(ctx->dataWin->gen8.wadVersion, &camera->viewMatrix)); } static RValue builtin_camera_get_proj_mat(VMContext* ctx, RValue* args, int32_t argCount) { Runner* runner = ctx->runner; GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); if (camera == nullptr) return RValue_makeUndefined(); - return RValue_makeArray(matrixToGml(ctx->dataWin->gen8.wadVersion, &camera->ProjectionMatrix)); + return RValue_makeArray(matrixToGml(ctx->dataWin->gen8.wadVersion, &camera->projectionMatrix)); } static RValue builtin_camera_set_proj_mat(VMContext* ctx, RValue* args, int32_t argCount) { @@ -3496,8 +3496,8 @@ static RValue builtin_camera_set_proj_mat(VMContext* ctx, RValue* args, int32_t if (camera == nullptr || !rvalueIsMatrix(args[1])) return RValue_makeUndefined(); Matrix4f m; matrixFromGml(&m, args[1].array); - camera->ProjectionMatrix = m; - camera->ProjectionMatrix.m[Matrix_getIndex(1, 1)] = -m.m[Matrix_getIndex(1, 1)]; + camera->projectionMatrix = m; + camera->projectionMatrix.m[Matrix_getIndex(1, 1)] = -m.m[Matrix_getIndex(1, 1)]; return RValue_makeUndefined(); } @@ -3551,7 +3551,7 @@ static RValue builtin_camera_set_view_size(VMContext* ctx, RValue* args, int32_t if (camera != nullptr) { camera->viewWidth = RValue_toInt32(args[1]); camera->viewHeight = RValue_toInt32(args[2]); - UpdateCameraViewSimple(camera); + Runner_updateCameraViewSimple(camera); } return RValue_makeUndefined(); } @@ -3573,8 +3573,8 @@ static RValue builtin_camera_set_view_angle(VMContext* ctx, RValue* args, int32_ GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); if (camera != nullptr) { - camera->viewAngle = (float) RValue_toReal(args[1]); - UpdateCameraViewSimple(camera); + camera->viewAngle = (float) RValue_toReal(args[1]); + Runner_updateCameraViewSimple(camera); } return RValue_makeUndefined(); } @@ -3640,7 +3640,7 @@ static RValue builtin_camera_create_view(VMContext* ctx, RValue* args, int32_t a if (argCount > 9) camera->borderY = (uint32_t) RValue_toInt32(args[9]); - UpdateCameraViewSimple(camera); + Runner_updateCameraViewSimple(camera); return RValue_makeReal(id); } @@ -3676,7 +3676,7 @@ static RValue builtin_view_set_camera(VMContext* ctx, RValue* args, int32_t argC static RValue builtin_camera_get_active(VMContext* ctx, MAYBE_UNUSED RValue* args, MAYBE_UNUSED int32_t argCount) { Runner* runner = ctx->runner; if (runner->viewCurrent >= 0 && MAX_VIEWS > runner->viewCurrent) { - return RValue_makeReal(runner->renderer->CameraCurrent); + return RValue_makeReal(runner->renderer->cameraCurrent); } return RValue_makeReal(-1); } @@ -3694,8 +3694,8 @@ static RValue builtin_camera_apply(VMContext* ctx, RValue* args, int32_t argCoun Runner* runner = ctx->runner; GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); if (camera != nullptr) { - runner->renderer->vtable->applyProjection(runner->renderer, &camera->ViewMatrix, &camera->ProjectionMatrix); - runner->renderer->CameraCurrent = RValue_toInt32(args[0]); + runner->renderer->vtable->applyProjection(runner->renderer, &camera->viewMatrix, &camera->projectionMatrix); + runner->renderer->cameraCurrent = RValue_toInt32(args[0]); } return RValue_makeUndefined(); } From 01103146a4c5fdfba3cb757b7cffd92b99976e2a Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Mon, 22 Jun 2026 10:42:55 +0200 Subject: [PATCH 21/21] fix spacing and indentation --- src/gl/gl_renderer.c | 24 +++++------------------- src/runner.c | 10 ---------- src/vm_builtins.c | 5 +++-- 3 files changed, 8 insertions(+), 31 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index de3468ece..21c6b92e1 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -404,11 +404,11 @@ static void glGpuSetShader(Renderer* renderer, int32_t shaderIndex) { GLShaderUniform* gmAlphaTestEnabledUniform = findShaderUniformByName(gmlShader, "gm_AlphaTestEnabled"); GLShaderUniform* gmAlphaRefValue = findShaderUniformByName(gmlShader, "gm_AlphaRefValue"); - Matrix4f flippedClip[MATRICES_MAX]; - for (int32_t i = 0; i < MATRICES_MAX; i++) { - flippedClip[i] = renderer->gmlMatrices[i]; - Matrix4f_flipClipY(&flippedClip[i]); - } + Matrix4f flippedClip[MATRICES_MAX]; + for (int32_t i = 0; i < MATRICES_MAX; i++) { + flippedClip[i] = renderer->gmlMatrices[i]; + Matrix4f_flipClipY(&flippedClip[i]); + } if (gmMatricesUniform != nullptr) { glUniformMatrix4fv(gmMatricesUniform->location, 5, GL_FALSE, flippedClip[0].m); @@ -583,10 +583,8 @@ static void glBeginView(Renderer* renderer, MAYBE_UNUSED int32_t viewX, MAYBE_UN gl->base.cameraCurrent = view->cameraId; GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.cameraCurrent); glApplyProjection(renderer,&camera->viewMatrix,&camera->projectionMatrix); - glShaderSettingsRefresh(renderer); glActiveTexture(GL_TEXTURE1); - glBindVertexArray(gl->vao); } @@ -642,10 +640,7 @@ static void glBeginGUI(Renderer* renderer, MAYBE_UNUSED int32_t guiW, MAYBE_UNUS camera->viewMatrix = viewMatrix; camera->projectionMatrix = projectionMatrix; glApplyProjection(renderer,&camera->viewMatrix,&camera->projectionMatrix); - - glActiveTexture(GL_TEXTURE1); - glBindVertexArray(gl->vao); } @@ -727,7 +722,6 @@ static void glClearScreen(Renderer* renderer, uint32_t color, float alpha) { //No it doesn't? glClearColor(r, g, b, alpha); glClear(GL_COLOR_BUFFER_BIT); - } // Lazily decodes and uploads a TXTR page on first access. @@ -2060,13 +2054,11 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic if (surfaceId == renderer->runner->applicationSurfaceId && implicitApplicationSurface) { glViewport(gl->base.CPortX, gl->base.CPortY, gl->base.CPortW, gl->base.CPortH); glEnable(GL_SCISSOR_TEST); - glApplyProjection(renderer,&camera->viewMatrix,&camera->projectionMatrix); return true; } - if (surfaceId == view->surfaceId) { //the surface belongs to the view we are rending, we use the view's camera. glViewport(0, 0, gl->surfaceWidth[surfaceId], gl->surfaceHeight[surfaceId]); @@ -2084,7 +2076,6 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic Matrix4f_identity(&viewMatrix); Matrix4f_lookAt(&viewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); gl->base.cameraCurrent = SURFACE_CAMERA; - GMLCamera* camera = &renderer->runner->surfaceCamera; camera->allocated = true; @@ -2107,7 +2098,6 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic return true; } - glViewport(0, 0, gl->surfaceWidth[surfaceId], gl->surfaceHeight[surfaceId]); glDisable(GL_SCISSOR_TEST); @@ -2606,17 +2596,13 @@ static void glSetMatrix(Renderer* renderer, int32_t MatrixType, Matrix4f Matrix) Matrix4f world = renderer->gmlMatrices[MATRIX_WORLD]; Matrix4f view = renderer->gmlMatrices[MATRIX_VIEW]; Matrix4f projection = renderer->gmlMatrices[MATRIX_PROJECTION]; - Matrix4f worldView; Matrix4f_multiply(&worldView, &view, &world); - Matrix4f worldViewProjection; Matrix4f_multiply(&worldViewProjection, &projection, &worldView); - renderer->gmlMatrices[MATRIX_WORLD_VIEW] = worldView; renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = worldViewProjection; - glShaderSettingsRefresh(renderer); } diff --git a/src/runner.c b/src/runner.c index c123f6370..74973ade7 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1141,12 +1141,10 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh Matrix4f projectionMatrix = camera->projectionMatrix; runner->renderer->vtable->applyProjection(runner->renderer, &viewMatrix, &projectionMatrix); - runner->viewCurrent = (int32_t) vi; runner->renderer->cameraCurrent = runner->views[runner->viewCurrent].cameraId; runner->renderer->vtable->applyProjection(runner->renderer, &viewMatrix, &projectionMatrix); - Runner_draw(runner); renderer->vtable->flush(renderer); @@ -1352,7 +1350,6 @@ static void initDefaultCameraFromRoomView(GMLCamera* camera, RoomView* roomView) //make default projection Matrix4f projectionMatrix; Matrix4f_orthographic(&projectionMatrix, (float) camera->viewWidth, -((float) camera->viewHeight), 32000.0, 0.0); - Matrix4f viewMatrix; float x = camera->viewX + camera->viewWidth * 0.5f; float y = camera->viewY + camera->viewHeight * 0.5f; @@ -1362,8 +1359,6 @@ static void initDefaultCameraFromRoomView(GMLCamera* camera, RoomView* roomView) Matrix4f_rotateZ(&viewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); Matrix4f_translate(&viewMatrix, -x, -y, 0.0f); - - camera->projectionMatrix = projectionMatrix; camera->viewMatrix = viewMatrix; } @@ -2340,7 +2335,6 @@ void Runner_destroyInstance(MAYBE_UNUSED Runner* runner, Instance* inst, bool ru } void Runner_updateCameraViewSimple(GMLCamera* camera) { - float x = camera->viewX + camera->viewWidth/2; float y = camera->viewY + camera->viewHeight/2; Matrix4f viewMatrix; @@ -2349,17 +2343,13 @@ void Runner_updateCameraViewSimple(GMLCamera* camera) { Matrix4f_translate(&viewMatrix, x, y, 0.0f); Matrix4f_rotateZ(&viewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); Matrix4f_translate(&viewMatrix, -x, -y, 0.0f); - Matrix4f projectionMatrix; Matrix4f_orthographic(&projectionMatrix, (float) camera->viewWidth, -((float) camera->viewHeight), 32000.0, 0.0); camera->viewMatrix = viewMatrix; camera->projectionMatrix = projectionMatrix; - } - - RuntimeLayer* Runner_findRuntimeLayerByName(Runner* runner, char* name) { size_t count = arrlenu(runner->runtimeLayers); repeat(count, i) { diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 0faaa834c..2e6ca42dd 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -2906,6 +2906,7 @@ static RValue builtin_matrix_build_projection_perspective_fov(MAYBE_UNUSED VMCon return RValue_makeArrayWeak(destArray); } } + static RValue builtin_matrix_get(MAYBE_UNUSED VMContext *ctx, RValue *args, int32_t argCount) { int32_t matrix = RValue_toInt32(args[0]); if (matrix < 0 || matrix > 2) return RValue_makeUndefined(); @@ -3639,7 +3640,6 @@ static RValue builtin_camera_create_view(VMContext* ctx, RValue* args, int32_t a if (argCount > 8) camera->borderX = (uint32_t) RValue_toInt32(args[8]); if (argCount > 9) camera->borderY = (uint32_t) RValue_toInt32(args[9]); - Runner_updateCameraViewSimple(camera); return RValue_makeReal(id); @@ -15476,7 +15476,8 @@ void VMBuiltins_registerAll(VMContext* ctx) { VM_registerBuiltin(ctx, "matrix_build_projection_ortho", builtin_matrix_build_projection_ortho); VM_registerBuiltin(ctx, "matrix_build_projection_perspective_fov", builtin_matrix_build_projection_perspective_fov); VM_registerBuiltin(ctx, "matrix_get", builtin_matrix_get); - VM_registerBuiltin(ctx, "matrix_set", builtin_matrix_set); + VM_registerBuiltin(ctx, "matrix_set", builtin_matrix_set); + // Random VM_registerBuiltin(ctx, "random", builtin_random); VM_registerBuiltin(ctx, "random_range", builtin_random_range);