Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
246 changes: 194 additions & 52 deletions src/gl/gl_renderer.c

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/gl_legacy/gl_legacy_renderer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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, 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);
Expand Down
81 changes: 81 additions & 0 deletions src/matrix_math.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
9 changes: 7 additions & 2 deletions src/renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
#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.
//
Expand Down Expand Up @@ -72,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* 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);
Expand Down Expand Up @@ -149,6 +152,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 ]===
Expand All @@ -163,14 +167,15 @@ 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;
int32_t CPortH;
Runner* runner;
Matrix4f gmlMatrices[MATRICES_MAX];
int32_t currentShader;
int32_t CameraCurrent;
};

// ===[ Shared Helpers (platform-agnostic) ]===
Expand Down
54 changes: 50 additions & 4 deletions src/runner.c
Original file line number Diff line number Diff line change
Expand Up @@ -1130,12 +1130,14 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh
continue;

Runner_surfaceSetTarget(runner, view->surfaceId);

Matrix4f ViewMatrix = camera->ViewMatrix;
Matrix4f ProjectionMatrix = camera->ProjectionMatrix;
runner->viewCurrent = (int32_t) vi;
runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId;
runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix);

Matrix4f proj;
Matrix4f_viewProjection(&proj, (float) camera->viewX, (float) camera->viewY, (float) camera->viewWidth, (float) camera->viewHeight, camera->viewAngle);
renderer->vtable->applyProjection(renderer, &proj);

runner->viewCurrent = (int32_t) vi;
Runner_draw(runner);

renderer->vtable->flush(renderer);
Expand All @@ -1156,6 +1158,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;
renderer->vtable->beginView(renderer, viewX, viewY, viewW, viewH, portX, portY, portW, portH, viewAngle);

Runner_draw(runner);
Expand All @@ -1172,12 +1175,35 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh
// 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 ViewMatrix;
float x = (float) gameW /2;
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);
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;
}

renderer->vtable->beginView(renderer, fullViewX, fullViewY, fullViewW, fullViewH, 0, 0, gameW, gameH, 0.0f);

Runner_draw(runner);

if (debugShowCollisionMasks) DebugOverlay_drawCollisionMasks(runner);
Expand All @@ -1188,6 +1214,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;
}

// ===[ Instance Creation Helper ]===
Expand Down Expand Up @@ -1289,6 +1316,8 @@ 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 == SURFACE_CAMERA) camera = &runner->surfaceCamera;
else if (id == GUI_CAMERA) camera = &runner->guiCamera;
else return nullptr;
if (!camera->allocated) return nullptr;
return camera;
Expand All @@ -1312,6 +1341,23 @@ static void initDefaultCameraFromRoomView(GMLCamera* camera, RoomView* roomView)
camera->speedY = roomView->speedY;
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 ViewMatrix;
float x = camera->viewX + camera->viewWidth/2;
float y = camera->viewY + camera->viewHeight/2;
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;
}

// Copies the viewport (port) properties and enabled flag from parsed room data.
Expand Down
11 changes: 6 additions & 5 deletions src/runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -155,9 +155,8 @@ 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;

typedef struct {
Expand Down Expand Up @@ -466,6 +465,8 @@ struct Runner {
RuntimeView views[MAX_VIEWS];
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)
Expand Down
Loading