Implements depth effects (#95)
* implements depth effects * fix missing skidmark textures * implement sky color * temporary fix for missing kerb materials
This commit is contained in:
parent
26fd105889
commit
92b67a9314
|
|
@ -244,7 +244,7 @@ void BrPixelmapDirtyRectangleDoubleBuffer(br_pixelmap* dst, br_pixelmap* src, br
|
|||
// IDA: void __cdecl BrPixelmapPixelSet(br_pixelmap *dst, br_int_32 x, br_int_32 y, br_uint_32 colour)
|
||||
void BrPixelmapPixelSet(br_pixelmap* dst, br_int_32 x, br_int_32 y, br_uint_32 colour) {
|
||||
br_point p;
|
||||
//LOG_TRACE("(%p, %d, %d, %d)", dst, x, y, colour);
|
||||
// LOG_TRACE("(%p, %d, %d, %d)", dst, x, y, colour);
|
||||
br_uint_8* dst_pix = (br_uint_8*)dst->pixels;
|
||||
dst_pix[(y * dst->row_bytes) + x] = (br_uint_8)colour;
|
||||
}
|
||||
|
|
@ -267,8 +267,8 @@ void BrPixelmapCopy(br_pixelmap* dst, br_pixelmap* src) {
|
|||
|
||||
// IDA: void __cdecl BrPixelmapLine(br_pixelmap *dst, br_int_32 x1, br_int_32 y1, br_int_32 x2, br_int_32 y2, br_uint_32 colour)
|
||||
void BrPixelmapLine(br_pixelmap* dst, br_int_32 x1, br_int_32 y1, br_int_32 x2, br_int_32 y2, br_uint_32 colour) {
|
||||
//br_point s;
|
||||
//br_point e;
|
||||
// br_point s;
|
||||
// br_point e;
|
||||
LOG_TRACE("(%p, %d, %d, %d, %d, %d)", dst, x1, y1, x2, y2, colour);
|
||||
|
||||
// Thanks Errol!
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ br_device_pixelmap* DevicePixelmapMemAllocate(br_uint_8 type, br_uint_16 w, br_u
|
|||
|
||||
tip = &pmTypeInfo[type];
|
||||
pm = BrResAllocate(_pixelmap.res, sizeof(br_device_pixelmap), BR_MEMORY_PIXELMAP);
|
||||
//pm->dispatch = &devicePixelmapDispatch;
|
||||
// pm->dispatch = &devicePixelmapDispatch;
|
||||
pm->pm_identifier = NULL;
|
||||
pm->pm_map = NULL;
|
||||
pm->pm_flags = BR_PMF_LINEAR;
|
||||
|
|
@ -129,11 +129,11 @@ br_device_pixelmap* DevicePixelmapMemAllocate(br_uint_8 type, br_uint_16 w, br_u
|
|||
pm->pm_type = type;
|
||||
pm->pm_width = w;
|
||||
pm->pm_height = h;
|
||||
//8 bits, 1, 4 align, 1
|
||||
// 8 bits, 1, 4 align, 1
|
||||
|
||||
//v11 = (tip->align + w - 1) / tip->align * tip->align * tip->bits;
|
||||
//pm->pm_row_bytes = (v11 - (__CFSHL__(v11 >> 31, 3) + 8 * (v11 >> 31))) >> 3;
|
||||
// TODO: calculate this differently
|
||||
// v11 = (tip->align + w - 1) / tip->align * tip->align * tip->bits;
|
||||
// pm->pm_row_bytes = (v11 - (__CFSHL__(v11 >> 31, 3) + 8 * (v11 >> 31))) >> 3;
|
||||
// TODO: calculate this differently
|
||||
pm->pm_row_bytes = w;
|
||||
pm->pm_row_bytes = tip->bits * tip->align * ((w + tip->align - 1) / tip->align) / 8;
|
||||
|
||||
|
|
@ -147,8 +147,8 @@ br_device_pixelmap* DevicePixelmapMemAllocate(br_uint_8 type, br_uint_16 w, br_u
|
|||
pm->pm_pixels = BrResAllocate(pm, pm->pm_height * pm->pm_row_bytes, BR_MEMORY_PIXELS);
|
||||
}
|
||||
}
|
||||
//TODO: not sure we need this
|
||||
//pm->pm_pixels_qualifier = (unsigned __int16)_GetSysQual();
|
||||
// TODO: not sure we need this
|
||||
// pm->pm_pixels_qualifier = (unsigned __int16)_GetSysQual();
|
||||
if (flags & BR_PMAF_INVERTED) {
|
||||
pm->pm_pixels = (char*)pm->pm_pixels + (pm->pm_height - 1) * pm->pm_row_bytes;
|
||||
pm->pm_row_bytes *= -1;
|
||||
|
|
@ -183,7 +183,7 @@ br_error _M_br_device_pixelmap_mem_allocateSub(br_device_pixelmap* self, br_devi
|
|||
pm->pm_stored = 0;
|
||||
pm->dispatch = &devicePixelmapDispatch;
|
||||
if (pm->pm_width != self->pm_width) {
|
||||
pm->pm_flags &= 0xFDu; //unset BR_PMF_LINEAR
|
||||
pm->pm_flags &= 0xFDu; // unset BR_PMF_LINEAR
|
||||
}
|
||||
*newpm = pm;
|
||||
return 0;
|
||||
|
|
@ -301,6 +301,9 @@ br_error _M_br_device_pixelmap_mem_match(br_device_pixelmap* self, br_device_pix
|
|||
// }
|
||||
|
||||
if (mt.use == BRT_DEPTH) {
|
||||
|
||||
// TODO: hack this to make it work
|
||||
mt.pixel_type = BR_PMT_DEPTH_16;
|
||||
pm = DevicePixelmapMemAllocate(mt.pixel_type, mt.width, mt.height, NULL, (self->pm_row_bytes < 0) | BR_PMAF_NO_PIXELS);
|
||||
r = abs(self->pm_row_bytes);
|
||||
bytes = (signed int)pmTypeInfo[self->pm_type].bits >> 3;
|
||||
|
|
@ -322,7 +325,7 @@ br_error _M_br_device_pixelmap_mem_match(br_device_pixelmap* self, br_device_pix
|
|||
}
|
||||
pm->pm_origin_x = self->pm_origin_x;
|
||||
pm->pm_origin_y = self->pm_origin_y;
|
||||
//self->dispatch = pm;
|
||||
// self->dispatch = pm;
|
||||
*newpm = pm;
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,40 +4,40 @@
|
|||
#include "harness/trace.h"
|
||||
|
||||
render_style_cbfn RenderStyleCalls[8] = {
|
||||
renderFaces, /* BR_RSTYLE_DEFAULT */
|
||||
nullRender, /* BR_RSTYLE_NONE */
|
||||
renderPoints, /* BR_RSTYLE_POINTS */
|
||||
renderEdges, /* BR_RSTYLE_EDGES */
|
||||
renderFaces, /* BR_RSTYLE_FACES */
|
||||
boundingBoxRenderPoints, /* BR_RSTYLE_BOUNDING_POINTS */
|
||||
boundingBoxRenderEdges, /* BR_RSTYLE_BOUNDING_EDGES */
|
||||
boundingBoxRenderFaces, /* BR_RSTYLE_BOUNDING_FACES */
|
||||
renderFaces, /* BR_RSTYLE_DEFAULT */
|
||||
nullRender, /* BR_RSTYLE_NONE */
|
||||
renderPoints, /* BR_RSTYLE_POINTS */
|
||||
renderEdges, /* BR_RSTYLE_EDGES */
|
||||
renderFaces, /* BR_RSTYLE_FACES */
|
||||
boundingBoxRenderPoints, /* BR_RSTYLE_BOUNDING_POINTS */
|
||||
boundingBoxRenderEdges, /* BR_RSTYLE_BOUNDING_EDGES */
|
||||
boundingBoxRenderFaces, /* BR_RSTYLE_BOUNDING_FACES */
|
||||
};
|
||||
|
||||
v11face bounds_faces[12] = {
|
||||
{ { 5, 6, 7 }, { 0, 13, 14}, { { 1.0f, 0.0f, 0.0f, 1.0f } } },
|
||||
{ { 5, 4, 6 }, { 3, 4, 0}, { { 1.0f, 0.0f, 0.0f, 1.0f } } },
|
||||
{ { 7, 6, 2 }, { 13, 6, 0}, { { 0.0f, 1.0f, 0.0f, 1.0f } } },
|
||||
{ { 7, 2, 3 }, { 0, 5, 16}, { { 0.0f, 1.0f, 0.0f, 1.0f } } },
|
||||
{ { 1, 5, 7 }, { 11, 14, 0}, { { 0.0f, 0.0f, 1.0f, 1.0f } } },
|
||||
{ { 1, 7, 3 }, { 0, 16, 12}, { { 0.0f, 0.0f, 1.0f, 1.0f } } },
|
||||
{ { 3, 0, 1 }, { 0, 8, 12}, { { -1.0f, 0.0f, 0.0f, 1.0f } } },
|
||||
{ { 3, 2, 0 }, { 5, 1, 0}, { { -1.0f, 0.0f, 0.0f, 1.0f } } },
|
||||
{ { 1, 0, 4 }, { 8, 9, 0}, { { 0.0f, -1.0f, 0.0f, 1.0f } } },
|
||||
{ { 1, 4, 5 }, { 0, 3, 11}, { { 0.0f, -1.0f, 0.0f, 1.0f } } },
|
||||
{ { 0, 6, 4 }, { 0, 4, 9}, { { 0.0f, 0.0f, -1.0f, 1.0f } } },
|
||||
{ { 0, 2, 6 }, { 1, 6, 0}, { { 0.0f, 0.0f, -1.0f, 1.0f } } },
|
||||
{ { 5, 6, 7 }, { 0, 13, 14 }, { { 1.0f, 0.0f, 0.0f, 1.0f } } },
|
||||
{ { 5, 4, 6 }, { 3, 4, 0 }, { { 1.0f, 0.0f, 0.0f, 1.0f } } },
|
||||
{ { 7, 6, 2 }, { 13, 6, 0 }, { { 0.0f, 1.0f, 0.0f, 1.0f } } },
|
||||
{ { 7, 2, 3 }, { 0, 5, 16 }, { { 0.0f, 1.0f, 0.0f, 1.0f } } },
|
||||
{ { 1, 5, 7 }, { 11, 14, 0 }, { { 0.0f, 0.0f, 1.0f, 1.0f } } },
|
||||
{ { 1, 7, 3 }, { 0, 16, 12 }, { { 0.0f, 0.0f, 1.0f, 1.0f } } },
|
||||
{ { 3, 0, 1 }, { 0, 8, 12 }, { { -1.0f, 0.0f, 0.0f, 1.0f } } },
|
||||
{ { 3, 2, 0 }, { 5, 1, 0 }, { { -1.0f, 0.0f, 0.0f, 1.0f } } },
|
||||
{ { 1, 0, 4 }, { 8, 9, 0 }, { { 0.0f, -1.0f, 0.0f, 1.0f } } },
|
||||
{ { 1, 4, 5 }, { 0, 3, 11 }, { { 0.0f, -1.0f, 0.0f, 1.0f } } },
|
||||
{ { 0, 6, 4 }, { 0, 4, 9 }, { { 0.0f, 0.0f, -1.0f, 1.0f } } },
|
||||
{ { 0, 2, 6 }, { 1, 6, 0 }, { { 0.0f, 0.0f, -1.0f, 1.0f } } },
|
||||
};
|
||||
br_colour bounds_colours[12] = { 0 };
|
||||
fmt_vertex bounds_vertices[8] = {
|
||||
{ {{ -1.0f, -1.0f, -1.0f }}, {{ 0.0f, 0.0f }}, {{ -0.666f, -0.333f, -0.666f }} },
|
||||
{ {{ -1.0f, -1.0f, 1.0f }}, {{ 0.0f, 0.0f }}, {{ -0.333f, -0.666f, 0.666f }} },
|
||||
{ {{ -1.0f, 1.0f, -1.0f }}, {{ 0.0f, 1.0f }}, {{ -0.408f, 0.816f, -0.408f }} },
|
||||
{ {{ -1.0f, 1.0f, 1.0f }}, {{ 0.0f, 1.0f }}, {{ -0.816f, 0.408f, 0.408f }} },
|
||||
{ {{ 1.0f, -1.0f, -1.0f }}, {{ 1.0f, 0.0f }}, {{ 0.408f, -0.816f, -0.408f }} },
|
||||
{ {{ 1.0f, -1.0f, 1.0f }}, {{ 1.0f, 0.0f }}, {{ 0.816f, -0.408f, 0.408f }} },
|
||||
{ {{ 1.0f, 1.0f, -1.0f }}, {{ 1.0f, 1.0f }}, {{ 0.666f, 0.333f, -0.666f }} },
|
||||
{ {{ 1.0f, 1.0f, 1.0f }}, {{ 1.0f, 1.0f }}, {{ 0.333f, 0.666f, 0.666f }} },
|
||||
{ { { -1.0f, -1.0f, -1.0f } }, { { 0.0f, 0.0f } }, { { -0.666f, -0.333f, -0.666f } } },
|
||||
{ { { -1.0f, -1.0f, 1.0f } }, { { 0.0f, 0.0f } }, { { -0.333f, -0.666f, 0.666f } } },
|
||||
{ { { -1.0f, 1.0f, -1.0f } }, { { 0.0f, 1.0f } }, { { -0.408f, 0.816f, -0.408f } } },
|
||||
{ { { -1.0f, 1.0f, 1.0f } }, { { 0.0f, 1.0f } }, { { -0.816f, 0.408f, 0.408f } } },
|
||||
{ { { 1.0f, -1.0f, -1.0f } }, { { 1.0f, 0.0f } }, { { 0.408f, -0.816f, -0.408f } } },
|
||||
{ { { 1.0f, -1.0f, 1.0f } }, { { 1.0f, 0.0f } }, { { 0.816f, -0.408f, 0.408f } } },
|
||||
{ { { 1.0f, 1.0f, -1.0f } }, { { 1.0f, 1.0f } }, { { 0.666f, 0.333f, -0.666f } } },
|
||||
{ { { 1.0f, 1.0f, 1.0f } }, { { 1.0f, 1.0f } }, { { 0.333f, 0.666f, 0.666f } } },
|
||||
};
|
||||
v11group bounds_face_groups[1] = {
|
||||
{ NULL, bounds_faces, bounds_colours, NULL, bounds_vertices, bounds_colours, NULL, BR_ASIZE(bounds_faces), BR_ASIZE(bounds_vertices), 18 },
|
||||
|
|
@ -64,7 +64,7 @@ br_model bounds_model = {
|
|||
// IDA: void __usercall renderFaces(br_actor *actor@<EAX>, br_model *model@<EDX>, br_material *material@<EBX>, void *render_data@<ECX>, br_uint_8 style, int on_screen)
|
||||
void renderFaces(br_actor* actor, br_model* model, br_material* material, void* render_data, br_uint_8 style, int on_screen) {
|
||||
LOG_TRACE9("(%p, %p, %p, %p, %d, %d)", actor, model, material, render_data, style, on_screen);
|
||||
Harness_Hook_renderFaces(model, material, BRT_TRIANGLE);
|
||||
Harness_Hook_renderFaces(actor, model, material, BRT_TRIANGLE);
|
||||
}
|
||||
|
||||
// IDA: void __usercall renderEdges(br_actor *actor@<EAX>, br_model *model@<EDX>, br_material *material@<EBX>, void *render_data@<ECX>, br_uint_8 style, int on_screen)
|
||||
|
|
@ -123,11 +123,11 @@ br_model* makeMeshFromBounds(br_bounds* b) {
|
|||
bounds_vertices[7].p.v[2] = b->max.v[2];
|
||||
|
||||
// 2. Modify d in the face equation (a*x+b*y+c*y+d=0)
|
||||
for (i = 0; i < BR_ASIZE(bounds_faces)/4; i++) {
|
||||
bounds_faces[2*i+0].eqn.v[3] = b->min.v[i];
|
||||
bounds_faces[2*i+1].eqn.v[3] = b->min.v[i];
|
||||
bounds_faces[2*i+6].eqn.v[3] = b->max.v[i];
|
||||
bounds_faces[2*i+7].eqn.v[3] = b->max.v[i];
|
||||
for (i = 0; i < BR_ASIZE(bounds_faces) / 4; i++) {
|
||||
bounds_faces[2 * i + 0].eqn.v[3] = b->min.v[i];
|
||||
bounds_faces[2 * i + 1].eqn.v[3] = b->min.v[i];
|
||||
bounds_faces[2 * i + 6].eqn.v[3] = b->max.v[i];
|
||||
bounds_faces[2 * i + 7].eqn.v[3] = b->max.v[i];
|
||||
}
|
||||
|
||||
// 3. Copy bounds
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "errors.h"
|
||||
#include "globvars.h"
|
||||
#include "globvrkm.h"
|
||||
#include "harness/hooks.h"
|
||||
#include "harness/trace.h"
|
||||
#include "spark.h"
|
||||
#include "utility.h"
|
||||
|
|
@ -261,7 +262,66 @@ void DoDepthByShadeTable(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer
|
|||
int depth_line_skip;
|
||||
int render_line_skip;
|
||||
LOG_TRACE("(%p, %p, %p, %d, %d, %d)", pRender_buffer, pDepth_buffer, pShade_table, pShade_table_power, pStart, pEnd);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
// Added to ensure we've copied the framebuffer+depthbuffer back into main memory
|
||||
Harness_Hook_FlushRenderer();
|
||||
|
||||
too_near = 0xffff - (1 << pStart);
|
||||
shade_table_pixels = pShade_table->pixels;
|
||||
depth_shift_amount = pShade_table_power + 8 - pStart - pEnd;
|
||||
render_ptr = (tU8*)pRender_buffer->pixels + pRender_buffer->base_x + pRender_buffer->base_y * pRender_buffer->row_bytes;
|
||||
depth_ptr = pDepth_buffer->pixels;
|
||||
render_line_skip = pRender_buffer->row_bytes - pRender_buffer->width;
|
||||
depth_line_skip = pDepth_buffer->row_bytes / 2 - pRender_buffer->width;
|
||||
|
||||
if (depth_shift_amount <= 0) {
|
||||
if (depth_shift_amount >= 0) {
|
||||
for (y = 0; pRender_buffer->height > y; ++y) {
|
||||
for (x = 0; pRender_buffer->width > x; ++x) {
|
||||
if (*depth_ptr != 0xFFFF) {
|
||||
depth_value = *depth_ptr - too_near;
|
||||
if (depth_value < -(int16_t)too_near) {
|
||||
*render_ptr = shade_table_pixels[(depth_value & 0xFF00) + *render_ptr];
|
||||
}
|
||||
}
|
||||
++render_ptr;
|
||||
++depth_ptr;
|
||||
}
|
||||
render_ptr += render_line_skip;
|
||||
depth_ptr += depth_line_skip;
|
||||
}
|
||||
} else {
|
||||
for (y = 0; pRender_buffer->height > y; ++y) {
|
||||
for (x = 0; pRender_buffer->width > x; ++x) {
|
||||
if (*depth_ptr != 0xFFFF) {
|
||||
depth_value = *depth_ptr - too_near;
|
||||
if (depth_value < -(int16_t)too_near) {
|
||||
*render_ptr = shade_table_pixels[*render_ptr + ((depth_value >> (pEnd - (pShade_table_power + 8 - pStart))) & 0xFF00)];
|
||||
}
|
||||
}
|
||||
++render_ptr;
|
||||
++depth_ptr;
|
||||
}
|
||||
render_ptr += render_line_skip;
|
||||
depth_ptr += depth_line_skip;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (y = 0; pRender_buffer->height > y; ++y) {
|
||||
for (x = 0; pRender_buffer->width > x; ++x) {
|
||||
if (*depth_ptr != 0xFFFF) {
|
||||
depth_value = *depth_ptr - too_near;
|
||||
if (depth_value < -(int16_t)too_near) {
|
||||
*render_ptr = shade_table_pixels[*render_ptr + ((depth_value << depth_shift_amount) & 0xFF00)];
|
||||
}
|
||||
}
|
||||
++render_ptr;
|
||||
++depth_ptr;
|
||||
}
|
||||
render_ptr += render_line_skip;
|
||||
depth_ptr += depth_line_skip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall ExternalSky(br_pixelmap *pRender_buffer@<EAX>, br_pixelmap *pDepth_buffer@<EDX>, br_actor *pCamera@<EBX>, br_matrix34 *pCamera_to_world@<ECX>)
|
||||
|
|
@ -288,6 +348,8 @@ void ExternalSky(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_act
|
|||
int repetitions;
|
||||
br_pixelmap* col_map;
|
||||
LOG_TRACE("(%p, %p, %p, %p)", pRender_buffer, pDepth_buffer, pCamera, pCamera_to_world);
|
||||
|
||||
// TODO: Remove commented block in `ConditionallyFillWithSky` when we implement this properly
|
||||
return;
|
||||
dx = 0;
|
||||
col_map = gHorizon_material->colour_map;
|
||||
|
|
@ -369,31 +431,56 @@ void DoHorizon(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_actor
|
|||
br_angle yaw;
|
||||
br_actor* actor;
|
||||
LOG_TRACE("(%p, %p, %p, %p)", pRender_buffer, pDepth_buffer, pCamera, pCamera_to_world);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
STUB_ONCE();
|
||||
}
|
||||
|
||||
// IDA: void __usercall DoDepthCue(br_pixelmap *pRender_buffer@<EAX>, br_pixelmap *pDepth_buffer@<EDX>)
|
||||
void DoDepthCue(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer) {
|
||||
LOG_TRACE("(%p, %p)", pRender_buffer, pDepth_buffer);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
DoDepthByShadeTable(
|
||||
pRender_buffer,
|
||||
pDepth_buffer,
|
||||
gDepth_shade_table,
|
||||
gDepth_shade_table_power,
|
||||
gProgram_state.current_depth_effect.start,
|
||||
gProgram_state.current_depth_effect.end);
|
||||
}
|
||||
|
||||
// IDA: void __usercall DoFog(br_pixelmap *pRender_buffer@<EAX>, br_pixelmap *pDepth_buffer@<EDX>)
|
||||
void DoFog(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer) {
|
||||
LOG_TRACE("(%p, %p)", pRender_buffer, pDepth_buffer);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
DoDepthByShadeTable(
|
||||
pRender_buffer,
|
||||
pDepth_buffer,
|
||||
gFog_shade_table,
|
||||
gFog_shade_table_power,
|
||||
gProgram_state.current_depth_effect.start,
|
||||
gProgram_state.current_depth_effect.end);
|
||||
}
|
||||
|
||||
// IDA: void __usercall DepthEffect(br_pixelmap *pRender_buffer@<EAX>, br_pixelmap *pDepth_buffer@<EDX>, br_actor *pCamera@<EBX>, br_matrix34 *pCamera_to_world@<ECX>)
|
||||
void DepthEffect(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_actor* pCamera, br_matrix34* pCamera_to_world) {
|
||||
LOG_TRACE("(%p, %p, %p, %p)", pRender_buffer, pDepth_buffer, pCamera, pCamera_to_world);
|
||||
STUB_ONCE();
|
||||
|
||||
if (gProgram_state.current_depth_effect.type == eDepth_effect_darkness) {
|
||||
DoDepthCue(pRender_buffer, pDepth_buffer);
|
||||
}
|
||||
if (gProgram_state.current_depth_effect.type == eDepth_effect_fog) {
|
||||
DoFog(pRender_buffer, pDepth_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall DepthEffectSky(br_pixelmap *pRender_buffer@<EAX>, br_pixelmap *pDepth_buffer@<EDX>, br_actor *pCamera@<EBX>, br_matrix34 *pCamera_to_world@<ECX>)
|
||||
void DepthEffectSky(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_actor* pCamera, br_matrix34* pCamera_to_world) {
|
||||
LOG_TRACE("(%p, %p, %p, %p)", pRender_buffer, pDepth_buffer, pCamera, pCamera_to_world);
|
||||
STUB_ONCE();
|
||||
|
||||
if (gProgram_state.current_depth_effect.sky_texture
|
||||
&& (!gLast_camera_special_volume || gLast_camera_special_volume->sky_col < 0)) {
|
||||
DoHorizon(pRender_buffer, pDepth_buffer, pCamera, pCamera_to_world);
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall DoWobbleCamera(br_actor *pCamera@<EAX>)
|
||||
|
|
@ -584,8 +671,8 @@ void IncreaseAngle() {
|
|||
|
||||
for (i = 0; i < COUNT_OF(gCamera_list); i++) {
|
||||
camera_ptr = gCamera_list[i]->type_data;
|
||||
camera_ptr->field_of_view += 0x1c7; // 2.4993896484375 degrees
|
||||
if (camera_ptr->field_of_view > 0x78e3) { // 169.9969482421875 degrees
|
||||
camera_ptr->field_of_view += 0x1c7; // 2.4993896484375 degrees
|
||||
if (camera_ptr->field_of_view > 0x78e3) { // 169.9969482421875 degrees
|
||||
camera_ptr->field_of_view = 0x78e3;
|
||||
}
|
||||
#ifdef DETHRACE_FIX_BUGS
|
||||
|
|
@ -606,8 +693,8 @@ void DecreaseAngle() {
|
|||
|
||||
for (i = 0; i < COUNT_OF(gCamera_list); i++) {
|
||||
camera_ptr = gCamera_list[i]->type_data;
|
||||
camera_ptr->field_of_view -= 0x1c7; // 2.4993896484375 degrees
|
||||
if (camera_ptr->field_of_view < 0x71c) { // 9.99755859375 degrees
|
||||
camera_ptr->field_of_view -= 0x1c7; // 2.4993896484375 degrees
|
||||
if (camera_ptr->field_of_view < 0x71c) { // 9.99755859375 degrees
|
||||
camera_ptr->field_of_view = 0x71c;
|
||||
}
|
||||
#ifdef DETHRACE_FIX_BUGS
|
||||
|
|
|
|||
|
|
@ -1188,8 +1188,26 @@ int ConditionallyFillWithSky(br_pixelmap* pPixelmap) {
|
|||
int bgnd_col;
|
||||
LOG_TRACE("(%p)", pPixelmap);
|
||||
|
||||
STUB_ONCE();
|
||||
return 0;
|
||||
// TODO: Uncomment when ExternalSky is fully implemented
|
||||
LOG_WARN_ONCE("Uncomment this block when ExternalSky is fully implemented");
|
||||
// if (gProgram_state.current_depth_effect.sky_texture
|
||||
// && (!gLast_camera_special_volume || gLast_camera_special_volume->sky_col < 0)) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
if (gProgram_state.current_depth_effect.type == eDepth_effect_fog || gSwap_depth_effect_type == eDepth_effect_fog) {
|
||||
bgnd_col = 255;
|
||||
} else if (gProgram_state.current_depth_effect.type && gSwap_depth_effect_type) {
|
||||
if (gLast_camera_special_volume && gLast_camera_special_volume->sky_col >= 0) {
|
||||
bgnd_col = gLast_camera_special_volume->sky_col;
|
||||
} else {
|
||||
bgnd_col = 0;
|
||||
}
|
||||
} else {
|
||||
bgnd_col = 0;
|
||||
}
|
||||
BrPixelmapFill(pPixelmap, bgnd_col);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// IDA: void __usercall RenderAFrame(int pDepth_mask_on@<EAX>)
|
||||
|
|
@ -2295,7 +2313,7 @@ void TellyOutImage(br_pixelmap* pImage, int pLeft, int pTop) {
|
|||
// IDA: void __usercall SetShadowLevel(tShadow_level pLevel@<EAX>)
|
||||
void SetShadowLevel(tShadow_level pLevel) {
|
||||
LOG_TRACE("(%d)", pLevel);
|
||||
|
||||
|
||||
gShadow_level = pLevel;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ int ChoiceDisabled(int pChoice) {
|
|||
// IDA: void __cdecl ResetInterfaceTimeout()
|
||||
void ResetInterfaceTimeout() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gStart_time = PDGetTotalTime();
|
||||
}
|
||||
|
||||
// IDA: void __usercall ChangeSelection(tInterface_spec *pSpec@<EAX>, int *pOld_selection@<EDX>, int *pNew_selection@<EBX>, int pMode@<ECX>, int pSkip_disabled)
|
||||
|
|
@ -182,9 +183,6 @@ int DoInterfaceScreen(tInterface_spec* pSpec, int pOptions, int pCurrent_choice)
|
|||
void* palette_copy;
|
||||
LOG_TRACE("(%p, %d, %d)", pSpec, pOptions, pCurrent_choice);
|
||||
|
||||
//added
|
||||
int last_choice_2;
|
||||
|
||||
entry_status = gProgram_state.prog_status;
|
||||
gTyping_slot = -1;
|
||||
EdgeTriggerModeOn();
|
||||
|
|
@ -368,7 +366,7 @@ int DoInterfaceScreen(tInterface_spec* pSpec, int pOptions, int pCurrent_choice)
|
|||
}
|
||||
ProcessFlicQueue(gFrame_period);
|
||||
if (DoMouseCursor() || EitherMouseButtonDown()) {
|
||||
gStart_time = PDGetTotalTime();
|
||||
ResetInterfaceTimeout();
|
||||
}
|
||||
PDScreenBufferSwap(0);
|
||||
if (gMouse_in_use && !selection_changed) {
|
||||
|
|
@ -496,13 +494,11 @@ int DoInterfaceScreen(tInterface_spec* pSpec, int pOptions, int pCurrent_choice)
|
|||
UnlockFlic(pSpec->pushed_flics[i].flic_index);
|
||||
}
|
||||
|
||||
//v100 = gCurrent_choice;
|
||||
if (gCurrent_choice == pSpec->escape_code) {
|
||||
escaped = 1;
|
||||
go_ahead = 0;
|
||||
}
|
||||
if (escaped) {
|
||||
//v100 = pSpec->escape_code;
|
||||
gCurrent_choice = pSpec->escape_code;
|
||||
}
|
||||
if (pSpec->done_proc) {
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ int CheckQuit() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
//IDA: double __cdecl sqr(double pN)
|
||||
// IDA: double __cdecl sqr(double pN)
|
||||
double sqr(double pN) {
|
||||
return pN * pN;
|
||||
}
|
||||
|
|
@ -289,13 +289,13 @@ char* GetALineWithNoPossibleService(FILE* pF, /*unsigned*/ char* pS) {
|
|||
pS[i] -= 32;
|
||||
}
|
||||
}
|
||||
//LOG_DEBUG("%s", result);
|
||||
// LOG_DEBUG("%s", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// IDA: char* __usercall GetALineAndDontArgue@<EAX>(FILE *pF@<EAX>, char *pS@<EDX>)
|
||||
char* GetALineAndDontArgue(FILE* pF, char* pS) {
|
||||
//LOG_TRACE10("(%p, \"%s\")", pF, pS);
|
||||
// LOG_TRACE10("(%p, \"%s\")", pF, pS);
|
||||
PossibleService();
|
||||
return GetALineWithNoPossibleService(pF, pS);
|
||||
}
|
||||
|
|
@ -659,7 +659,8 @@ void PrintScreenFile(FILE* pF) {
|
|||
}
|
||||
offset -= 2 * gBack_screen->row_bytes;
|
||||
}
|
||||
WriteU16L(pF, 0);;
|
||||
WriteU16L(pF, 0);
|
||||
;
|
||||
}
|
||||
|
||||
// IDA: void __usercall PrintScreenFile16(FILE *pF@<EAX>)
|
||||
|
|
@ -795,7 +796,7 @@ int FindBestMatch(tRGB_colour* pRGB_colour, br_pixelmap* pPalette) {
|
|||
LOG_TRACE("(%p, %p)", pRGB_colour, pPalette);
|
||||
|
||||
near_c = 127;
|
||||
min_d = 1.79769e+308; // max double
|
||||
min_d = 1.79769e+308; // max double
|
||||
dp = pPalette->pixels;
|
||||
for (n = 0; n < 256; n++) {
|
||||
trial_RGB.red = (dp[n] >> 16) & 0xff;
|
||||
|
|
@ -893,9 +894,9 @@ br_pixelmap* GenerateDarkenedShadeTable(int pHeight, br_pixelmap* pPalette, int
|
|||
ref_col.blue = pBlue_mix;
|
||||
|
||||
for (c = 0, tab_ptr = the_table->pixels; c < 256; c++, tab_ptr++) {
|
||||
the_RGB.red = ((cp[i] >> 16) & 0xff) * pDarken;
|
||||
the_RGB.green = ((cp[i] >> 8) & 0xff) * pDarken;
|
||||
the_RGB.blue = ((cp[i] >> 0) & 0xff) * pDarken;
|
||||
the_RGB.red = ((cp[c] >> 16) & 0xff) * pDarken;
|
||||
the_RGB.green = ((cp[c] >> 8) & 0xff) * pDarken;
|
||||
the_RGB.blue = ((cp[c] >> 0) & 0xff) * pDarken;
|
||||
|
||||
if (pHeight == 1) {
|
||||
f_total_minus_1 = 1.;
|
||||
|
|
@ -919,9 +920,9 @@ br_pixelmap* GenerateDarkenedShadeTable(int pHeight, br_pixelmap* pPalette, int
|
|||
ratio2 = 1. - (1. - pThree_quarter) * (1. - ratio1) * 4.;
|
||||
}
|
||||
}
|
||||
new_RGB.red = ref_col.red * ratio2 + the_RGB.red * (1. - ratio2);
|
||||
new_RGB.red = ref_col.red * ratio2 + the_RGB.red * (1. - ratio2);
|
||||
new_RGB.green = ref_col.green * ratio2 + the_RGB.green * (1. - ratio2);
|
||||
new_RGB.blue = ref_col.blue * ratio2 + the_RGB.blue * (1. - ratio2);
|
||||
new_RGB.blue = ref_col.blue * ratio2 + the_RGB.blue * (1. - ratio2);
|
||||
*shade_ptr = FindBestMatch(&new_RGB, pPalette);
|
||||
}
|
||||
}
|
||||
|
|
@ -1438,22 +1439,22 @@ int AlreadyBlended(br_material* pMaterial) {
|
|||
|
||||
// IDA: void __usercall BlendifyMaterialTablishly(br_material *pMaterial@<EAX>, int pPercent@<EDX>)
|
||||
void BlendifyMaterialTablishly(br_material* pMaterial, int pPercent) {
|
||||
char* s;
|
||||
char* s = NULL;
|
||||
LOG_TRACE("(%p, %d)", pMaterial, pPercent);
|
||||
|
||||
switch (pPercent) {
|
||||
case 25:
|
||||
s = "BLEND75.TAB";
|
||||
break;
|
||||
case 50:
|
||||
s = "BLEND50.TAB";
|
||||
break;
|
||||
case 75:
|
||||
s = "BLEND25.TAB";
|
||||
break;
|
||||
default:
|
||||
PDFatalError("Invalid alpha");
|
||||
break;
|
||||
case 25:
|
||||
s = "BLEND75.TAB";
|
||||
break;
|
||||
case 50:
|
||||
s = "BLEND50.TAB";
|
||||
break;
|
||||
case 75:
|
||||
s = "BLEND25.TAB";
|
||||
break;
|
||||
default:
|
||||
PDFatalError("Invalid alpha");
|
||||
break;
|
||||
}
|
||||
pMaterial->index_blend = BrTableFind(s);
|
||||
if (pMaterial->index_blend == NULL) {
|
||||
|
|
@ -1465,17 +1466,17 @@ void BlendifyMaterialTablishly(br_material* pMaterial, int pPercent) {
|
|||
void BlendifyMaterialPrimitively(br_material* pMaterial, int pPercent) {
|
||||
static br_token_value alpha25[3] = {
|
||||
{ BRT_BLEND_B, { .b = 1 } },
|
||||
{ BRT_OPACITY_X, { .x = 0x400000 }},
|
||||
{ BRT_OPACITY_X, { .x = 0x400000 } },
|
||||
{ 0 },
|
||||
};
|
||||
static br_token_value alpha50[3] = {
|
||||
{ BRT_BLEND_B, { .b = 1 } },
|
||||
{ BRT_OPACITY_X, { .x = 0x800000 }},
|
||||
{ BRT_OPACITY_X, { .x = 0x800000 } },
|
||||
{ 0 },
|
||||
};
|
||||
static br_token_value alpha75[3] = {
|
||||
{ BRT_BLEND_B, { .b = 1 } },
|
||||
{ BRT_OPACITY_X, { .x = 0xc00000 }},
|
||||
{ BRT_OPACITY_X, { .x = 0xc00000 } },
|
||||
{ 0 },
|
||||
};
|
||||
LOG_TRACE("(%p, %d)", pMaterial, pPercent);
|
||||
|
|
|
|||
|
|
@ -84,8 +84,11 @@ void DebugCamera_Update() {
|
|||
glm_normalize_to(direction, cam_front);
|
||||
}
|
||||
|
||||
extern float gCamera_hither;
|
||||
extern float gCamera_yon;
|
||||
|
||||
float* DebugCamera_Projection() {
|
||||
glm_perspective(glm_rad(55.55), 320.0f / 200.0f /*4.0f / 3.0f*/, 0.1f, 10000.f, projection);
|
||||
glm_perspective(glm_rad(55.55), 320.0f / 200.0f /*4.0f / 3.0f*/, gCamera_hither, gCamera_yon, projection);
|
||||
return (float*)&projection;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ harness_br_renderer* renderer_state;
|
|||
br_pixelmap* last_dst = NULL;
|
||||
br_pixelmap* last_src = NULL;
|
||||
|
||||
br_pixelmap* color_buffer = NULL;
|
||||
br_pixelmap *last_colour_buffer, *last_depth_buffer;
|
||||
|
||||
unsigned int last_frame_time = 0;
|
||||
|
||||
|
|
@ -213,14 +213,16 @@ void Harness_Hook_MainGameLoop() {
|
|||
|
||||
// Begin 3d scene
|
||||
void Harness_Hook_BrZbSceneRenderBegin(br_actor* world, br_actor* camera, br_pixelmap* colour_buffer, br_pixelmap* depth_buffer) {
|
||||
last_colour_buffer = colour_buffer;
|
||||
last_depth_buffer = depth_buffer;
|
||||
platform->BeginScene(camera, colour_buffer);
|
||||
}
|
||||
|
||||
void Harness_Hook_BrZbSceneRenderAdd(br_actor* tree) {
|
||||
}
|
||||
|
||||
void Harness_Hook_renderFaces(br_model* model, br_material* material, br_token type) {
|
||||
platform->RenderModel(model, renderer_state->state.matrix.model_to_view);
|
||||
void Harness_Hook_renderFaces(br_actor* actor, br_model* model, br_material* material, br_token type) {
|
||||
platform->RenderModel(actor, model, renderer_state->state.matrix.model_to_view);
|
||||
}
|
||||
|
||||
void Harness_Hook_BrZbSceneRenderEnd() {
|
||||
|
|
@ -231,6 +233,7 @@ void Harness_Hook_BrZbSceneRenderEnd() {
|
|||
void Harness_Hook_BrPixelmapDoubleBuffer(br_pixelmap* dst, br_pixelmap* src) {
|
||||
|
||||
// draw the current colour_buffer (2d screen) contents
|
||||
platform->FlushBuffers(last_colour_buffer, last_depth_buffer);
|
||||
Harness_RenderScreen(dst, src);
|
||||
|
||||
platform->Swap();
|
||||
|
|
@ -266,4 +269,8 @@ void Harness_Hook_S3Service(int unk1, int unk2) {
|
|||
}
|
||||
|
||||
void Harness_Hook_S3StopAllOutletSounds() {
|
||||
}
|
||||
|
||||
void Harness_Hook_FlushRenderer() {
|
||||
platform->FlushBuffers(last_colour_buffer, last_depth_buffer);
|
||||
}
|
||||
|
|
@ -14,10 +14,11 @@ typedef struct tPlatform {
|
|||
void (*EndScene)();
|
||||
void (*SetPalette)(uint8_t* palette);
|
||||
void (*RenderFullScreenQuad)(uint8_t* src, int width, int height);
|
||||
void (*RenderModel)(br_model* model, br_matrix34 model_matrix);
|
||||
void (*RenderModel)(br_actor* actor, br_model* model, br_matrix34 model_matrix);
|
||||
void (*Swap)();
|
||||
void (*BufferTexture)(br_pixelmap* pm);
|
||||
void (*BufferMaterial)(br_material* mat);
|
||||
void (*FlushBuffers)(br_pixelmap* color_buffer, br_pixelmap* depth_buffer);
|
||||
|
||||
} tPlatform;
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ int Harness_Hook_KeyDown(unsigned char pScan_code);
|
|||
void Harness_Hook_PDServiceSystem();
|
||||
void Harness_Hook_PDSetKeyArray();
|
||||
void Harness_Hook_MainGameLoop(); // limit FPS
|
||||
void Harness_Hook_FlushRenderer(); // synchronize in-memory framebuffer and depthbuffer
|
||||
|
||||
// BRender hooks
|
||||
void Harness_Hook_DOSGfxBegin();
|
||||
|
|
@ -20,7 +21,7 @@ void Harness_Hook_BrPixelmapDoubleBuffer(br_pixelmap* dst, br_pixelmap* src);
|
|||
void Harness_Hook_BrV1dbRendererBegin();
|
||||
void Harness_Hook_BrZbSceneRenderBegin(br_actor* world, br_actor* camera, br_pixelmap* colour_buffer, br_pixelmap* depth_buffer);
|
||||
void Harness_Hook_BrZbSceneRenderAdd(br_actor* tree);
|
||||
void Harness_Hook_renderFaces(br_model* model, br_material* material, br_token type);
|
||||
void Harness_Hook_renderFaces(br_actor* actor, br_model* model, br_material* material, br_token type);
|
||||
void Harness_Hook_BrZbSceneRenderEnd();
|
||||
void Harness_Hook_BrBufferUpdate(br_pixelmap* pm, br_token use, br_uint_16 flags);
|
||||
void Harness_Hook_BrMaterialUpdate(br_material* mat, br_uint_16 flags);
|
||||
|
|
|
|||
|
|
@ -9,11 +9,12 @@ void Null_BeginFrame(br_actor* camera, br_pixelmap* colour_buffer) {}
|
|||
void Null_EndFrame() {}
|
||||
void Null_SetPalette(uint8_t* palette) {}
|
||||
void Null_RenderFullScreenQuad(uint8_t* src, int width, int height) {}
|
||||
void Null_RenderModel(br_model* model, br_matrix34 model_matrix) {}
|
||||
void Null_RenderModel(br_actor* actor, br_model* model, br_matrix34 model_matrix) {}
|
||||
void Null_RenderFrameBuffer() {}
|
||||
void Null_Swap() {}
|
||||
void Null_BufferTexture(br_pixelmap* pm) {}
|
||||
void Null_BufferMaterial(br_material* mat) {}
|
||||
void Null_FlushBuffers(br_pixelmap* color_buffer, br_pixelmap* depth_buffer) {}
|
||||
|
||||
tPlatform null_platform = {
|
||||
Null_Init,
|
||||
|
|
@ -28,5 +29,6 @@ tPlatform null_platform = {
|
|||
Null_RenderModel,
|
||||
Null_Swap,
|
||||
Null_BufferTexture,
|
||||
Null_BufferMaterial
|
||||
Null_BufferMaterial,
|
||||
Null_FlushBuffers
|
||||
};
|
||||
|
|
@ -18,7 +18,8 @@ tPlatform sdl_gl_platform = {
|
|||
GLRenderer_RenderModel,
|
||||
GLRenderer_Swap,
|
||||
GLRenderer_BufferTexture,
|
||||
GLRenderer_BufferMaterial
|
||||
GLRenderer_BufferMaterial,
|
||||
GLRenderer_FlushBuffers
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
SDL_Window* window;
|
||||
SDL_GLContext context;
|
||||
GLuint screen_buffer_vao, screen_buffer_ebo;
|
||||
GLuint screen_texture, palette_texture;
|
||||
GLuint screen_texture, palette_texture, depth_texture;
|
||||
|
||||
GLuint shader_program_2d;
|
||||
GLuint shader_program_3d;
|
||||
|
|
@ -23,11 +23,12 @@ GLuint framebuffer_id, framebuffer_texture = 0;
|
|||
unsigned int rbo;
|
||||
uint8_t gl_palette[4 * 256]; // RGBA
|
||||
uint8_t* screen_buffer_flip_pixels;
|
||||
uint16_t* depth_buffer_flip_pixels;
|
||||
|
||||
int window_width, window_height, render_width, render_height;
|
||||
|
||||
br_pixelmap* last_colour_buffer;
|
||||
br_pixelmap* last_shade_table = NULL;
|
||||
int dirty_buffers = 0;
|
||||
|
||||
struct {
|
||||
GLuint pixels, shade_table;
|
||||
|
|
@ -210,6 +211,7 @@ void InitializeOpenGLContext() {
|
|||
glGenTextures(1, &screen_texture);
|
||||
glGenTextures(1, &palette_texture);
|
||||
glGenTextures(1, &framebuffer_texture);
|
||||
glGenTextures(1, &depth_texture);
|
||||
|
||||
// setup framebuffer
|
||||
glGenFramebuffers(1, &framebuffer_id);
|
||||
|
|
@ -221,11 +223,12 @@ void InitializeOpenGLContext() {
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebuffer_texture, 0);
|
||||
|
||||
glGenRenderbuffers(1, &rbo);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, render_width, render_height);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
|
||||
glBindTexture(GL_TEXTURE_2D, depth_texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, render_width, render_height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0);
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depth_texture, 0);
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
LOG_PANIC("Framebuffer is not complete!");
|
||||
}
|
||||
|
|
@ -268,6 +271,7 @@ void GLRenderer_CreateWindow(char* title, int width, int height, int pRender_wid
|
|||
InitializeOpenGLContext();
|
||||
|
||||
screen_buffer_flip_pixels = malloc(sizeof(uint8_t) * render_width * render_height);
|
||||
depth_buffer_flip_pixels = malloc(sizeof(uint16_t) * render_width * render_height);
|
||||
}
|
||||
|
||||
void GLRenderer_SetPalette(uint8_t* rgba_colors) {
|
||||
|
|
@ -317,7 +321,6 @@ void GLRenderer_SetShadeTable(br_pixelmap* table) {
|
|||
extern br_v1db_state v1db;
|
||||
|
||||
void GLRenderer_BeginScene(br_actor* camera, br_pixelmap* colour_buffer) {
|
||||
last_colour_buffer = colour_buffer;
|
||||
glViewport(colour_buffer->base_x, colour_buffer->base_y, colour_buffer->width, colour_buffer->height);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
|
@ -363,26 +366,13 @@ void GLRenderer_EndScene() {
|
|||
// switch back to default fb
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
// pull framebuffer into cpu memory to emulate BRender behavior
|
||||
glBindTexture(GL_TEXTURE_2D, framebuffer_texture);
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, screen_buffer_flip_pixels);
|
||||
|
||||
// flip texture to match the expected orientation
|
||||
int dest_y = render_height;
|
||||
uint8_t* pm_pixels = last_colour_buffer->pixels;
|
||||
for (int y = 0; y < render_height; y++) {
|
||||
dest_y--;
|
||||
for (int x = 0; x < render_width; x++) {
|
||||
pm_pixels[dest_y * render_width + x] = screen_buffer_flip_pixels[y * render_width + x];
|
||||
}
|
||||
}
|
||||
CHECK_GL_ERROR("GLRenderer_RenderFullScreenQuad");
|
||||
}
|
||||
|
||||
void GLRenderer_RenderFullScreenQuad(uint8_t* screen_buffer, int width, int height) {
|
||||
glViewport(0, 0, window_width, window_height);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
|
||||
glUseProgram(shader_program_2d);
|
||||
glBindTexture(GL_TEXTURE_2D, screen_texture);
|
||||
|
|
@ -501,7 +491,30 @@ void build_model(br_model* model) {
|
|||
CHECK_GL_ERROR("after build model");
|
||||
}
|
||||
|
||||
void GLRenderer_RenderModel(br_model* model, br_matrix34 model_matrix) {
|
||||
void setActiveMaterial(tStored_material* material) {
|
||||
if (material) {
|
||||
glUniform1i(uniforms_3d.palette_index_override, material->index_base);
|
||||
if (material->shade_table) {
|
||||
GLRenderer_SetShadeTable(material->shade_table);
|
||||
}
|
||||
if ((material->flags & BR_MATF_LIGHT) && material->shade_table) {
|
||||
// TODO: light value shouldn't always be 0? Works for shadows, not sure about other things.
|
||||
glUniform1i(uniforms_3d.light_value, 0);
|
||||
} else {
|
||||
glUniform1i(uniforms_3d.light_value, -1);
|
||||
}
|
||||
|
||||
if (material->texture) {
|
||||
tStored_pixelmap* stored_px = material->texture->stored;
|
||||
if (stored_px) {
|
||||
glBindTexture(GL_TEXTURE_2D, stored_px->id);
|
||||
glUniform1i(uniforms_3d.palette_index_override, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLRenderer_RenderModel(br_actor* actor, br_model* model, br_matrix34 model_matrix) {
|
||||
tStored_model_context* ctx;
|
||||
ctx = model->stored;
|
||||
v11model* v11 = model->prepared;
|
||||
|
|
@ -536,41 +549,27 @@ void GLRenderer_RenderModel(br_model* model, br_matrix34 model_matrix) {
|
|||
|
||||
int element_index = 0;
|
||||
|
||||
// br_actor can have a material too, which is applied to the faces if the face doesn't have a texture
|
||||
if (actor->material) {
|
||||
setActiveMaterial(actor->material->stored);
|
||||
} else {
|
||||
// TODO: set defaults for now. This fixes missing curb materials but probably isn't the right fix.
|
||||
LOG_WARN_ONCE("set default palette override for missing actor material")
|
||||
glUniform1i(uniforms_3d.palette_index_override, 227);
|
||||
glUniform1i(uniforms_3d.light_value, -1);
|
||||
}
|
||||
|
||||
v11group* group;
|
||||
for (int g = 0; g < v11->ngroups; g++) {
|
||||
group = &v11->groups[g];
|
||||
tStored_material* material = group->stored;
|
||||
if (material) {
|
||||
glUniform1i(uniforms_3d.palette_index_override, material->index_base);
|
||||
if (material->shade_table) {
|
||||
GLRenderer_SetShadeTable(material->shade_table);
|
||||
}
|
||||
if ((material->flags & BR_MATF_LIGHT) && material->shade_table) {
|
||||
// TODO: light value shouldn't always be 0? Works for shadows, not sure about other things.
|
||||
glUniform1i(uniforms_3d.light_value, 0);
|
||||
} else {
|
||||
glUniform1i(uniforms_3d.light_value, -1);
|
||||
}
|
||||
|
||||
if (material->texture) {
|
||||
tStored_pixelmap* stored_px = material->texture->stored;
|
||||
if (stored_px) {
|
||||
glBindTexture(GL_TEXTURE_2D, stored_px->id);
|
||||
glUniform1i(uniforms_3d.palette_index_override, -1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// LOG_WARN("no material");
|
||||
glUniform1i(uniforms_3d.palette_index_override, 0);
|
||||
glUniform1i(uniforms_3d.light_value, -1);
|
||||
}
|
||||
|
||||
setActiveMaterial(group->stored);
|
||||
glDrawElements(GL_TRIANGLES, group->nfaces * 3, GL_UNSIGNED_INT, (void*)(element_index * sizeof(int)));
|
||||
element_index += group->nfaces * 3;
|
||||
}
|
||||
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
dirty_buffers = 1;
|
||||
|
||||
CHECK_GL_ERROR("GLRenderer_RenderModel");
|
||||
}
|
||||
|
|
@ -616,6 +615,47 @@ void GLRenderer_BufferTexture(br_pixelmap* pm) {
|
|||
CHECK_GL_ERROR("GLRenderer_BufferTexture");
|
||||
}
|
||||
|
||||
void GLRenderer_FlushBuffers(br_pixelmap* color_buffer, br_pixelmap* depth_buffer) {
|
||||
|
||||
if (!dirty_buffers) {
|
||||
return;
|
||||
}
|
||||
|
||||
// pull framebuffer into cpu memory to emulate BRender behavior
|
||||
glBindTexture(GL_TEXTURE_2D, framebuffer_texture);
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, screen_buffer_flip_pixels);
|
||||
|
||||
// flip texture to match the expected orientation
|
||||
int dest_y = render_height;
|
||||
uint8_t* pm_pixels = color_buffer->pixels;
|
||||
uint8_t new_pixel;
|
||||
for (int y = 0; y < render_height; y++) {
|
||||
dest_y--;
|
||||
for (int x = 0; x < render_width; x++) {
|
||||
new_pixel = screen_buffer_flip_pixels[y * render_width + x];
|
||||
if (new_pixel != 0) {
|
||||
pm_pixels[dest_y * render_width + x] = screen_buffer_flip_pixels[y * render_width + x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// pull depthbuffer into cpu memory to emulate BRender behavior
|
||||
glBindTexture(GL_TEXTURE_2D, depth_texture);
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, depth_buffer_flip_pixels);
|
||||
|
||||
dest_y = render_height;
|
||||
uint16_t* depth_pixels = depth_buffer->pixels;
|
||||
for (int y = 0; y < render_height; y++) {
|
||||
dest_y--;
|
||||
for (int x = 0; x < render_width; x++) {
|
||||
depth_pixels[dest_y * render_width + x] = depth_buffer_flip_pixels[y * render_width + x];
|
||||
}
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
dirty_buffers = 0;
|
||||
}
|
||||
|
||||
void Harness_GLRenderer_RenderCube(float col, float x, float y, float z) {
|
||||
|
||||
// // Enable depth test
|
||||
|
|
|
|||
|
|
@ -18,8 +18,9 @@ void GLRenderer_BeginScene(br_actor* camera, br_pixelmap* colour_buffer);
|
|||
void GLRenderer_EndScene();
|
||||
void GLRenderer_RenderFullScreenQuad(uint8_t* screen_buffer, int width, int height);
|
||||
void GLRenderer_Swap();
|
||||
void GLRenderer_RenderModel(br_model* model, br_matrix34 model_matrix);
|
||||
void GLRenderer_RenderModel(br_actor* actor, br_model* model, br_matrix34 model_matrix);
|
||||
void GLRenderer_BufferTexture(br_pixelmap* pm);
|
||||
void GLRenderer_BufferMaterial(br_material* mat);
|
||||
void GLRenderer_FlushBuffers(br_pixelmap* color_buffer, br_pixelmap* depth_buffer);
|
||||
|
||||
#endif
|
||||
|
|
@ -71,6 +71,9 @@ const char* fs_3d = "#version 330 core\n"
|
|||
" } else {\n"
|
||||
" palette_index = texelFetch(shade_table, ivec2(texel, light_value), 0).x;\n"
|
||||
" }\n"
|
||||
" if (palette_index == 0u) {\n"
|
||||
" discard;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" else {\n"
|
||||
" palette_index = uint(palette_index_override);\n"
|
||||
|
|
|
|||
Loading…
Reference in New Issue