From 988891306d6e19611edc05a87fd66e400b9fde5c Mon Sep 17 00:00:00 2001 From: Dethrace Engineering Department <78985374+dethrace-labs@users.noreply.github.com> Date: Fri, 28 Jan 2022 13:27:21 +1300 Subject: [PATCH] Adds skidmarks (#78) --- src/BRSRC13/include/brender/br_defs.h | 1 + src/DETHRACE/common/car.c | 19 ++- src/DETHRACE/common/displays.c | 2 - src/DETHRACE/common/mainloop.c | 4 + src/DETHRACE/common/oil.c | 23 +++- src/DETHRACE/common/opponent.c | 3 +- src/DETHRACE/common/piping.c | 2 +- src/DETHRACE/common/skidmark.c | 185 ++++++++++++++++++++++++-- src/harness/harness.c | 7 + src/harness/include/harness/config.h | 1 + src/harness/sdl/gl_renderer.c | 9 +- src/harness/sdl/gl_renderer_shaders.c | 8 +- 12 files changed, 243 insertions(+), 21 deletions(-) diff --git a/src/BRSRC13/include/brender/br_defs.h b/src/BRSRC13/include/brender/br_defs.h index f35588b2..974d8b00 100644 --- a/src/BRSRC13/include/brender/br_defs.h +++ b/src/BRSRC13/include/brender/br_defs.h @@ -33,6 +33,7 @@ #define BR_LENGTH2(a, b) ((br_scalar)sqrt((a) * (a) + (b) * (b))) #define BR_LENGTH3(a, b, c) ((br_scalar)sqrt((a) * (a) + (b) * (b) + (c) * (c))) #define BR_SCALAR_EPSILON 1.192092896e-7f + #define BR_SCALAR_MAX 3.402823466e+38f #define BR_SCALAR_MIN (-3.402823466e+38f) diff --git a/src/DETHRACE/common/car.c b/src/DETHRACE/common/car.c index eca9d233..941551c9 100644 --- a/src/DETHRACE/common/car.c +++ b/src/DETHRACE/common/car.c @@ -3981,7 +3981,24 @@ void AmIGettingBoredWatchingCameraSpin() { // IDA: void __cdecl ViewNetPlayer() void ViewNetPlayer() { LOG_TRACE("()"); - NOT_IMPLEMENTED(); + + if (gOpponent_viewing_mode) { + if (gProgram_state.cockpit_on) { + ToggleCockpit(); + } + gNet_player_to_view_index++; + if (gNumber_of_net_players <= gNet_player_to_view_index) { + gNet_player_to_view_index = -1; + } + if (gNet_player_to_view_index < 0) { + gCar_to_view = GetRaceLeader(); + } else { + gCar_to_view = gNet_players[gNet_player_to_view_index].car; + } + gCamera_yaw = 0; + InitialiseExternalCamera(); + PositionExternalCamera(gCar_to_view, 200u); + } } // IDA: void __cdecl ViewOpponent() diff --git a/src/DETHRACE/common/displays.c b/src/DETHRACE/common/displays.c index dea152cc..405f5762 100644 --- a/src/DETHRACE/common/displays.c +++ b/src/DETHRACE/common/displays.c @@ -1177,8 +1177,6 @@ int SpendCredits(int pAmount) { int amount; LOG_TRACE("(%d)", pAmount); - LOG_DEBUG("spending"); - gProgram_state.credits_lost += pAmount; if (gNet_mode == eNet_mode_none) { return 0; diff --git a/src/DETHRACE/common/mainloop.c b/src/DETHRACE/common/mainloop.c index fbf77d4e..04f83743 100644 --- a/src/DETHRACE/common/mainloop.c +++ b/src/DETHRACE/common/mainloop.c @@ -406,6 +406,10 @@ void CheckTimer() { static tU32 last_demo_time_in_seconds = 0; LOG_TRACE("()"); + if (harness_game_config.freeze_timer) { + return; + } + if (!gFreeze_timer && !gCountdown && !gRace_finished) { if (gFrame_period < gTimer) { if (gNet_mode == eNet_mode_none) { diff --git a/src/DETHRACE/common/oil.c b/src/DETHRACE/common/oil.c index a96b3fda..ea498476 100644 --- a/src/DETHRACE/common/oil.c +++ b/src/DETHRACE/common/oil.c @@ -126,7 +126,10 @@ int OKToSpillOil(tOil_spill_info* pOil) { // IDA: void __usercall Vector3Interpolate(br_vector3 *pDst@, br_vector3 *pFrom@, br_vector3 *pTo@, br_scalar pP) void Vector3Interpolate(br_vector3* pDst, br_vector3* pFrom, br_vector3* pTo, br_scalar pP) { LOG_TRACE("(%p, %p, %p, %f)", pDst, pFrom, pTo, pP); - NOT_IMPLEMENTED(); + + pDst->v[0] = (pTo->v[0] - pFrom->v[0]) * pP + pFrom->v[0]; + pDst->v[1] = (pTo->v[1] - pFrom->v[1]) * pP + pFrom->v[1]; + pDst->v[2] = (pTo->v[2] - pFrom->v[2]) * pP + pFrom->v[2]; } // IDA: void __usercall EnsureGroundDetailVisible(br_vector3 *pNew_pos@, br_vector3 *pGround_normal@, br_vector3 *pOld_pos@) @@ -136,7 +139,23 @@ void EnsureGroundDetailVisible(br_vector3* pNew_pos, br_vector3* pGround_normal, br_scalar dist; br_vector3 to_camera; LOG_TRACE("(%p, %p, %p)", pNew_pos, pGround_normal, pOld_pos); - NOT_IMPLEMENTED(); + + to_camera.v[0] = gCamera_to_world.m[3][0] - pOld_pos->v[0]; + to_camera.v[1] = gCamera_to_world.m[3][1] - pOld_pos->v[1]; + to_camera.v[2] = gCamera_to_world.m[3][2] - pOld_pos->v[2]; + dist = BrVector3Length(&to_camera); + if (dist > BR_SCALAR_EPSILON) { + factor = BrVector3Dot(pGround_normal, &to_camera) / dist; + if (fabs(factor) <= 0.0099999998) { + s = 0.0099999998; + } else { + s = 0.0099999998 / factor; + if (s > 0.1) { + s = 0.1; + } + } + Vector3Interpolate(pNew_pos, pOld_pos, (br_vector3*)gCamera_to_world.m[3], s); + } } // IDA: void __usercall MungeOilsHeightAboveGround(tOil_spill_info *pOil@) diff --git a/src/DETHRACE/common/opponent.c b/src/DETHRACE/common/opponent.c index 2eed81b1..5436144a 100644 --- a/src/DETHRACE/common/opponent.c +++ b/src/DETHRACE/common/opponent.c @@ -952,7 +952,8 @@ void DisposeOpponents() { void WakeUpOpponentsToTheFactThatTheStartHasBeenJumped(int pWhat_the_countdown_was) { int i; LOG_TRACE("(%d)", pWhat_the_countdown_was); - NOT_IMPLEMENTED(); + + STUB(); } // IDA: void __usercall ReportMurderToPoliceDepartment(tCar_spec *pCar_spec@) diff --git a/src/DETHRACE/common/piping.c b/src/DETHRACE/common/piping.c index 25dfb216..a900e8ac 100644 --- a/src/DETHRACE/common/piping.c +++ b/src/DETHRACE/common/piping.c @@ -394,7 +394,7 @@ void PipingFrameReset() { // IDA: void __usercall PipeSingleSkidAdjustment(int pSkid_num@, br_matrix34 *pMatrix@, int pMaterial_index@) void PipeSingleSkidAdjustment(int pSkid_num, br_matrix34* pMatrix, int pMaterial_index) { LOG_TRACE("(%d, %p, %d)", pSkid_num, pMatrix, pMaterial_index); - NOT_IMPLEMENTED(); + STUB_ONCE(); } // IDA: void __cdecl ResetPiping() diff --git a/src/DETHRACE/common/skidmark.c b/src/DETHRACE/common/skidmark.c index 534027f0..54e6baee 100644 --- a/src/DETHRACE/common/skidmark.c +++ b/src/DETHRACE/common/skidmark.c @@ -4,6 +4,10 @@ #include "globvrbm.h" #include "harness/trace.h" #include "loading.h" +#include "oil.h" +#include "piping.h" +#include +#include #include #include @@ -18,13 +22,45 @@ void StretchMark(tSkid* pMark, br_vector3* pFrom, br_vector3* pTo, br_scalar pTe br_scalar len; br_model* model; LOG_TRACE("(%p, %p, %p, %f)", pMark, pFrom, pTo, pTexture_start); - NOT_IMPLEMENTED(); + + //LOG_DEBUG("(%p, %p, %p, %f)", pMark, pFrom, pTo, pTexture_start); + + rows = (br_vector3*)&pMark->actor->t.t.mat; + BrVector3Sub(&temp, pTo, pFrom); + len = BrVector3Length(&temp); + + rows[2].v[0] = pMark->normal.v[2] * temp.v[1] - pMark->normal.v[1] * temp.v[2]; + rows[2].v[1] = pMark->normal.v[0] * temp.v[2] - pMark->normal.v[2] * temp.v[0]; + rows[2].v[2] = pMark->normal.v[1] * temp.v[0] - pMark->normal.v[0] * temp.v[1]; + + if (len > BR_SCALAR_EPSILON) { + rows[2].v[0] = 0.050000001 / len * rows[2].v[0]; + rows[2].v[1] = 0.050000001 / len * rows[2].v[1]; + rows[2].v[2] = 0.050000001 / len * rows[2].v[2]; + rows->v[0] = len / len * temp.v[0]; + rows->v[1] = len / len * temp.v[1]; + rows->v[2] = len / len * temp.v[2]; + BrVector3Add(&temp, pTo, pFrom); + BrVector3Scale(&pMark->pos, &temp, 0.5); + rows[3] = pMark->pos; + model = pMark->actor->model; + model->vertices[1].map.v[0] = pTexture_start / 0.050000001; + model->vertices[0].map.v[0] = model->vertices[1].map.v[0]; + model->vertices[3].map.v[0] = (pTexture_start + len) / 0.050000001; + model->vertices[2].map.v[0] = model->vertices[3].map.v[0]; + BrModelUpdate(model, 0x7FFFu); + } } // IDA: br_material* __usercall MaterialFromIndex@(int pIndex@) br_material* MaterialFromIndex(int pIndex) { LOG_TRACE("(%d)", pIndex); - NOT_IMPLEMENTED(); + + if (pIndex > -2) { + return gCurrent_race.material_modifiers[pIndex].skid_mark_material; + } else { + return gMaterial[-2 - pIndex]; + } } // IDA: void __usercall AdjustSkid(int pSkid_num@, br_matrix34 *pMatrix@, int pMaterial_index@) @@ -40,7 +76,14 @@ int FarFromLine2D(br_vector3* pPt, br_vector3* pL1, br_vector3* pL2) { br_scalar line_len; br_scalar cross; LOG_TRACE("(%p, %p, %p)", pPt, pL1, pL2); - NOT_IMPLEMENTED(); + + line.v[0] = pL2->v[0] - pL1->v[0]; + line.v[1] = pL2->v[2] - pL1->v[2]; + to_pt.v[0] = pPt->v[0] - pL2->v[0]; + to_pt.v[1] = pPt->v[2] - pL2->v[2]; + cross = -line.v[0] * to_pt.v[1] + to_pt.v[0] * line.v[1]; + line_len = sqrt(line.v[0] * line.v[0] + line.v[1] * line.v[1]); + return fabs(cross) > line_len * 0.050000001; } // IDA: int __usercall Reflex2D@(br_vector3 *pPt@, br_vector3 *pL1@, br_vector3 *pL2@) @@ -48,7 +91,12 @@ int Reflex2D(br_vector3* pPt, br_vector3* pL1, br_vector3* pL2) { br_vector2 line; br_vector2 to_pt; LOG_TRACE("(%p, %p, %p)", pPt, pL1, pL2); - NOT_IMPLEMENTED(); + + line.v[0] = pL2->v[0] - pL1->v[0]; + line.v[1] = pL2->v[2] - pL1->v[2]; + to_pt.v[0] = pPt->v[0] - pL2->v[0]; + to_pt.v[1] = pPt->v[2] - pL2->v[2]; + return to_pt.v[1] * line.v[1] + to_pt.v[0] * line.v[0] < 0.0; } // IDA: void __cdecl InitSkids() @@ -91,7 +139,7 @@ void InitSkids() { gSkids[skid].actor = BrActorAllocate(BR_ACTOR_MODEL, NULL); BrActorAdd(gNon_track_actor, gSkids[skid].actor); gSkids[skid].actor->t.t.mat.m[1][1] = 0.0099999998; - gSkids[skid].actor->render_style = 1; + gSkids[skid].actor->render_style = BR_RSTYLE_NONE; square = BrModelAllocate(NULL, 4, 2); square->vertices[0].p.v[0] = -0.5; square->vertices[0].p.v[1] = 1.0; @@ -130,7 +178,8 @@ void InitSkids() { // IDA: void __usercall HideSkid(int pSkid_num@) void HideSkid(int pSkid_num) { LOG_TRACE("(%d)", pSkid_num); - NOT_IMPLEMENTED(); + + gSkids[pSkid_num].actor->render_style = BR_RSTYLE_NONE; } // IDA: void __cdecl HideSkids() @@ -138,13 +187,19 @@ void HideSkids() { int skid; LOG_TRACE("()"); - STUB(); + for (skid = 0; skid < 100; skid++) { + HideSkid(skid); + } } // IDA: br_scalar __usercall SkidLen@(int pSkid@) br_scalar SkidLen(int pSkid) { LOG_TRACE("(%d)", pSkid); - NOT_IMPLEMENTED(); + + return sqrt( + gSkids[pSkid].actor->t.t.mat.m[0][2] * gSkids[pSkid].actor->t.t.mat.m[0][2] + + gSkids[pSkid].actor->t.t.mat.m[0][1] * gSkids[pSkid].actor->t.t.mat.m[0][1] + + gSkids[pSkid].actor->t.t.mat.m[0][0] * gSkids[pSkid].actor->t.t.mat.m[0][0]); } // IDA: void __usercall SkidSection(tCar_spec *pCar@, int pWheel_num@, br_vector3 *pPos@, int pMaterial_index@) @@ -152,7 +207,37 @@ void SkidSection(tCar_spec* pCar, int pWheel_num, br_vector3* pPos, int pMateria static tU16 skid; br_material* material; LOG_TRACE("(%p, %d, %p, %d)", pCar, pWheel_num, pPos, pMaterial_index); - NOT_IMPLEMENTED(); + + if (BrVector3Dot(&pCar->prev_nor[pWheel_num], &pCar->nor[pWheel_num]) < 0.99699998 + || fabs(BrVector3Dot(&pCar->nor[pWheel_num], pPos) - BrVector3Dot(&pCar->prev_skid_pos[pWheel_num], &pCar->nor[pWheel_num])) > 0.0099999998) { + pCar->old_skidding &= ~(1 << pWheel_num); + pCar->old_skid[pWheel_num] = -1; + return; + } + + material = MaterialFromIndex(pMaterial_index); + if (pCar->old_skid[pWheel_num] >= 100 + || gSkids[pCar->old_skid[pWheel_num]].actor->material != material + || SkidLen(pCar->old_skid[pWheel_num]) > 0.5 + || FarFromLine2D(pPos, &pCar->skid_line_start[pWheel_num], &pCar->skid_line_end[pWheel_num]) + || Reflex2D(pPos, &pCar->skid_line_start[pWheel_num], &pCar->prev_skid_pos[pWheel_num])) { + + pCar->skid_line_start[pWheel_num] = pCar->prev_skid_pos[pWheel_num]; + pCar->skid_line_end[pWheel_num] = *pPos; + gSkids[skid].actor->render_style = BR_RSTYLE_DEFAULT; + gSkids[skid].actor->material = material; + gSkids[skid].normal = pCar->nor[pWheel_num]; + gSkids[skid].normal.v[0] = 0; + gSkids[skid].normal.v[1] = 1; + gSkids[skid].normal.v[2] = 0; + StretchMark(&gSkids[skid], &pCar->prev_skid_pos[pWheel_num], pPos, pCar->total_length[pWheel_num]); + PipeSingleSkidAdjustment(skid, &gSkids[skid].actor->t.t.mat, pMaterial_index); + pCar->old_skid[pWheel_num] = skid; + skid = (skid + 1) % 100; + } else { + StretchMark(&gSkids[pCar->old_skid[pWheel_num]], &pCar->skid_line_start[pWheel_num], pPos, pCar->total_length[pWheel_num]); + PipeSingleSkidAdjustment(pCar->old_skid[pWheel_num], &gSkids[pCar->old_skid[pWheel_num]].actor->t.t.mat, pMaterial_index); + } } // IDA: void __usercall SkidMark(tCar_spec *pCar@, int pWheel_num@) @@ -168,21 +253,97 @@ void SkidMark(tCar_spec* pCar, int pWheel_num) { br_material* material; LOG_TRACE("(%p, %d)", pCar, pWheel_num); - STUB_ONCE(); + on_ground = pCar->susp_height[pWheel_num >> 1] > pCar->oldd[pWheel_num]; + if (!on_ground) { + pCar->special_start[pWheel_num].v[0] = FLT_MAX; + } + if (pCar->blood_remaining[pWheel_num] != 0 && on_ground) { + pCar->new_skidding |= 1 << pWheel_num; + material_index = -3; + } else if (pCar->oil_remaining[pWheel_num] != 0 && on_ground) { + pCar->new_skidding |= 1 << pWheel_num; + material_index = -2; + } else { + material_index = pCar->material_index[pWheel_num]; + if (!gCurrent_race.material_modifiers[material_index].skid_mark_material) { + pCar->old_skidding &= ~(1 << pWheel_num); + return; + } + } + + if (((1 << pWheel_num) & pCar->new_skidding) != 0 || ((1 << pWheel_num) & pCar->old_skidding) != 0) { + if ((pWheel_num & 1) != 0) { + pos.v[0] = pCar->bounds[1].max.v[0] - 0.1725; + } else { + pos.v[0] = pCar->bounds[1].min.v[0] + 0.1725; + } + pos.v[1] = pCar->wpos[pWheel_num].v[1] - pCar->oldd[pWheel_num]; + pos.v[2] = pCar->wpos[pWheel_num].v[2]; + BrMatrix34ApplyP(&world_pos, &pos, &pCar->car_master_actor->t.t.mat); + BrVector3InvScale(&world_pos, &world_pos, WORLD_SCALE); + if (pCar->special_start[pWheel_num].v[0] != FLT_MAX) { + + BrVector3Sub(&spesh_to_wheel, &world_pos, &pCar->special_start[pWheel_num]); + dist = BrVector3Length(&spesh_to_wheel); + if (dist <= BR_SCALAR_EPSILON || (BrVector3Dot(&pCar->direction, &spesh_to_wheel) / dist < 0.70700002)) { + return; + } + world_pos = pCar->special_start[pWheel_num]; + pCar->special_start[pWheel_num].v[0] = FLT_MAX; + } + if (((1 << pWheel_num) & pCar->new_skidding) != 0) { + if (((1 << pWheel_num) & pCar->old_skidding) != 0) { + BrVector3Sub(&disp, &world_pos, &pCar->prev_skid_pos[pWheel_num]); + dist2 = BrVector3Length(&disp); + if (dist2 < 0.050000001) { + return; + } + SkidSection(pCar, pWheel_num, &world_pos, material_index); + pCar->total_length[pWheel_num] = pCar->total_length[pWheel_num] + dist2; + pCar->oil_remaining[pWheel_num] = pCar->oil_remaining[pWheel_num] - dist2; + if (pCar->oil_remaining[pWheel_num] < 0.0) { + pCar->oil_remaining[pWheel_num] = 0.0; + } + pCar->blood_remaining[pWheel_num] = pCar->blood_remaining[pWheel_num] - dist2; + if (pCar->blood_remaining[pWheel_num] < 0.0) { + pCar->blood_remaining[pWheel_num] = 0.0; + } + } else { + pCar->old_skidding |= 1 << pWheel_num; + pCar->total_length[pWheel_num] = 0.0; + pCar->old_skid[pWheel_num] = -1; + } + } else { + pCar->old_skidding &= ~(1 << pWheel_num); + } + pCar->prev_skid_pos[pWheel_num] = world_pos; + pCar->prev_nor[pWheel_num] = pCar->nor[pWheel_num]; + } } // IDA: void __usercall InitCarSkidStuff(tCar_spec *pCar@) void InitCarSkidStuff(tCar_spec* pCar) { int wheel; LOG_TRACE("(%p)", pCar); - STUB(); + + pCar->old_skidding = 0; + for (wheel = 0; wheel < 4; wheel++) { + pCar->special_start[wheel].v[0] = FLT_MAX; + pCar->blood_remaining[wheel] = 0.0; + pCar->oil_remaining[wheel] = 0.0; + } } // IDA: void __cdecl SkidsPerFrame() void SkidsPerFrame() { int skid; LOG_TRACE("()"); - STUB_ONCE(); + + for (skid = 0; skid < COUNT_OF(gSkids); skid++) { + if (gSkids[skid].actor->render_style != BR_RSTYLE_NONE) { + EnsureGroundDetailVisible(&gSkids[skid].actor->t.t.translate.t, &gSkids[skid].normal, &gSkids[skid].pos); + } + } } // IDA: void __cdecl RemoveMaterialsFromSkidmarks() diff --git a/src/harness/harness.c b/src/harness/harness.c index e52c6df4..d8f0b1f0 100644 --- a/src/harness/harness.c +++ b/src/harness/harness.c @@ -27,6 +27,7 @@ int rendered_scenes_last_frame = 0; unsigned int last_frame_time = 0; +// Provided by game extern void BrPixelmapFill(br_pixelmap* dst, br_uint_32 colour); extern unsigned int GetTotalTime(); extern uint8_t gScan_code[123][2]; @@ -67,6 +68,8 @@ void Harness_Init(int* argc, char* argv[]) { harness_game_config.physics_step_time = 40; // do not limit fps by default harness_game_config.fps = 0; + // do not freeze timer + harness_game_config.freeze_timer = 0; Harness_ProcessCommandLine(argc, argv); @@ -130,6 +133,10 @@ int Harness_ProcessCommandLine(int* argc, char* argv[]) { harness_game_config.fps = atoi(s + 1); LOG_INFO("FPS limiter set to %f", harness_game_config.fps); handled = 1; + } else if (strcasecmp(argv[i], "--freeze-timer") == 0) { + LOG_INFO("Timer frozen"); + harness_game_config.freeze_timer = 1; + handled = 1; } if (handled) { diff --git a/src/harness/include/harness/config.h b/src/harness/include/harness/config.h index 92ad23bd..a933058d 100644 --- a/src/harness/include/harness/config.h +++ b/src/harness/include/harness/config.h @@ -22,6 +22,7 @@ typedef struct tHarness_game_config { int disable_cd_check; float physics_step_time; float fps; + int freeze_timer; } tHarness_game_config; extern tHarness_game_info harness_game_info; diff --git a/src/harness/sdl/gl_renderer.c b/src/harness/sdl/gl_renderer.c index 9d1d71f2..f323ea37 100644 --- a/src/harness/sdl/gl_renderer.c +++ b/src/harness/sdl/gl_renderer.c @@ -120,6 +120,8 @@ void GLRenderer_CreateWindow(char* title, int width, int height) { } SDL_SetRelativeMouseMode(SDL_TRUE); + //SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN); + context = SDL_GL_CreateContext(window); if (!context) { LOG_PANIC("Failed to call SDL_GL_CreateContext. %s", SDL_GetError()); @@ -401,7 +403,6 @@ void build_model(br_model* model) { free(verts); free(indices); - model->stored = ctx; } @@ -431,6 +432,8 @@ void GLRenderer_RenderModel(br_model* model, br_matrix34 model_matrix) { model_matrix.m[3][0], model_matrix.m[3][1], model_matrix.m[3][2], 1 }; + GLuint tex_u = glGetUniformLocation(shader_program_3d, "textureSample"); + GLuint model_u = glGetUniformLocation(shader_program_3d, "model"); glUniformMatrix4fv(model_u, 1, GL_FALSE, m); @@ -447,8 +450,10 @@ void GLRenderer_RenderModel(br_model* model, br_matrix34 model_matrix) { tStored_material* mat = (tStored_material*)v11->groups[g].stored; if (mat && mat->texture) { glBindTexture(GL_TEXTURE_2D, mat->texture->id); + glUniform1i(tex_u, 1); } else { glBindTexture(GL_TEXTURE_2D, 0); + glUniform1i(tex_u, 0); } glDrawElements(GL_TRIANGLES, v11->groups[g].nfaces * 3, GL_UNSIGNED_INT, (void*)(element_index * sizeof(int))); @@ -468,6 +473,8 @@ void GLRenderer_RenderModel(br_model* model, br_matrix34 model_matrix) { void GLRenderer_BufferMaterial(br_material* mat) { if (!mat->stored) { + if (!mat->colour_map) { + } if (mat->colour_map) { GLRenderer_BufferTexture(mat->colour_map); if (mat->colour_map->stored) { diff --git a/src/harness/sdl/gl_renderer_shaders.c b/src/harness/sdl/gl_renderer_shaders.c index 40eca334..42ab7956 100644 --- a/src/harness/sdl/gl_renderer_shaders.c +++ b/src/harness/sdl/gl_renderer_shaders.c @@ -106,6 +106,7 @@ const char* fs_3d = "#version 330 core\n" "uniform vec3 lightColor;\n" "uniform vec3 objectColor;\n" "uniform sampler2D tex;\n" + "uniform int textureSample = 1;\n" "void main()\n" "{\n" " // ambient\n" @@ -118,6 +119,11 @@ const char* fs_3d = "#version 330 core\n" " vec3 diffuse = diff * lightColor;\n" " vec3 result = (ambient + diffuse) * objectColor;\n" " FragColor = vec4(result, 1.0);\n" - " FragColor = texture(tex, UV);\n" + " if (textureSample == 1) {" + " FragColor = texture(tex, UV);\n" + " }\n" + " else {\n" + " FragColor = vec4(0,0,0,1);\n" + " }\n" " FragColor.a = 1.0;\n" "}\n\0";