Implement transparency (blend tables) (#280)
* support for index_blend materials * blended materials should not write to zbuffer * remove reliance on glsl layout qualifiers * tidy StripBlendedFaces
This commit is contained in:
parent
716b98c25a
commit
acd403f183
|
|
@ -6,9 +6,9 @@
|
|||
#include "globvrbm.h"
|
||||
#include "harness/trace.h"
|
||||
#include "init.h"
|
||||
#include "pd/sys.h"
|
||||
#include "utility.h"
|
||||
#include "world.h"
|
||||
#include "pd/sys.h"
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
@ -98,9 +98,10 @@ void StripBlendedFaces(br_actor* pActor, br_model* pModel) {
|
|||
LOG_TRACE("(%p, %p)", pActor, pModel);
|
||||
|
||||
changed_one = 0;
|
||||
face = &pModel->faces[0];
|
||||
for (i = 0; i < pModel->nfaces; i++, face++) {
|
||||
if (face->material != NULL && face->material->identifier != NULL && ((face->material->identifier[0] == '!' && face->material->identifier[1] == '!' && gDefault_blend_pc != 0) || face->material->identifier[1] == '\\' )) {
|
||||
|
||||
for (i = 0; i < pModel->nfaces; i++) {
|
||||
face = &pModel->faces[i];
|
||||
if (face->material != NULL && face->material->identifier != NULL && ((face->material->identifier[0] == '!' && face->material->identifier[1] != '!' && gDefault_blend_pc != 0) || face->material->identifier[1] == '\\')) {
|
||||
if (gMr_blendy == NULL) {
|
||||
gMr_blendy = BrActorAllocate(BR_ACTOR_MODEL, NULL);
|
||||
gMr_blendy->render_style = BR_RSTYLE_NONE;
|
||||
|
|
@ -119,8 +120,10 @@ void StripBlendedFaces(br_actor* pActor, br_model* pModel) {
|
|||
} else {
|
||||
BlendifyMaterial(face->material, 50);
|
||||
}
|
||||
BrMaterialUpdate(face->material, BR_MATU_ALL);
|
||||
} else {
|
||||
BlendifyMaterial(face->material, gDefault_blend_pc);
|
||||
}
|
||||
BrMaterialUpdate(face->material, BR_MATU_ALL);
|
||||
}
|
||||
if (nfaces_allocated <= gMr_blendy->model->nfaces) {
|
||||
PDFatalError("Perfectly understandable error by Batwick, thank you very much Bruce.");
|
||||
|
|
@ -133,7 +136,6 @@ void StripBlendedFaces(br_actor* pActor, br_model* pModel) {
|
|||
pModel->nfaces--;
|
||||
changed_one = 1;
|
||||
i--;
|
||||
face = &pModel->faces[i];
|
||||
}
|
||||
}
|
||||
if (changed_one) {
|
||||
|
|
|
|||
|
|
@ -176,16 +176,16 @@ int gArrows[2][4][60] =
|
|||
{ 11, 0, 0, -1, 0, 1, 0, 0, -1, 1, -1, 1, -2, -2, 1, -1, 1, 0, 1, 1, 1, 1, 2, },
|
||||
{ 9, 0, 0, -2, 0, -1, 0, 1, 0, 0, -1, 1, -1, 2, -2, 0, 1, 0, 2, },
|
||||
{ 11, 0, 0, -1, 0, 1, 0, -2, -1, -1, -1, 0, -1, 1, -1, 2, -1, -1, 1, 0, 1, -1, 2, },
|
||||
},
|
||||
},
|
||||
{
|
||||
// outer arrow (=border)
|
||||
{ 26, 1, -3, 1, -2, 1, -1, 2, -1, 2, 0, 2, 1, 3, 1, 3, 2, 3, 3, 2, 3, 1, 3, 1, 2, 0, 2, -1, 2,
|
||||
{ 26, 1, -3, 1, -2, 1, -1, 2, -1, 2, 0, 2, 1, 3, 1, 3, 2, 3, 3, 2, 3, 1, 3, 1, 2, 0, 2, -1, 2,
|
||||
-1, 3, -2, 3, -3, 3, -3, 2, -3, 1, -2, 1, -2, 0, -2, -1, -1, -1, -1, -2, -1, -3, 0, -3, },
|
||||
{ 22, 0, -3, 1, -3, 2, -3, 2, -2, 2, -1, 2, 0, 2, 1, 2, 2, 2, 3, 1, 3, 0, 3, 0, 2, -1, 2, -2, 2,
|
||||
-3, 2, -3, 1, -3, 0, -2, 0, -2, -1, -1, -1, -1, -2, 0, -2, },
|
||||
{ 24, 1, -3, 2, -3, 3, -3, 3, -2, 3, -1, 2, -1, 2, 0, 2, 1, 1, 1, 1, 2, 1, 3, 0, 3, -1, 3, -1, 2,
|
||||
-1, 1, -2, 1, -3, 1, -3, 0, -3, -1, -2, -1, -1, -1, -1, -2, 0, -2, 1, -2, },
|
||||
{ 22, -3, -2, -2, -2, -1, -2, 0, -2, 1, -2, 2, -2, 3, -2, 3, -1, 3, 0, 2, 0, 2, 1, 1, 1, 1, 2, 0, 2,
|
||||
-1, 1, -2, 1, -3, 1, -3, 0, -3, -1, -2, -1, -1, -1, -1, -2, 0, -2, 1, -2, },
|
||||
{ 22, -3, -2, -2, -2, -1, -2, 0, -2, 1, -2, 2, -2, 3, -2, 3, -1, 3, 0, 2, 0, 2, 1, 1, 1, 1, 2, 0, 2,
|
||||
0, 3, -1, 3, -2, 3, -2, 2, -2, 1, -2, 0, -3, 0, -3, -1, },
|
||||
},
|
||||
};
|
||||
|
|
@ -1616,7 +1616,7 @@ void RenderAFrame(int pDepth_mask_on) {
|
|||
ProcessTrack(gUniverse_actor, &gProgram_state.track_spec, gCamera, &gCamera_to_world, 1);
|
||||
}
|
||||
RenderSplashes();
|
||||
Harness_Hook_FlushRenderer(); /* Dethrace. Flush buffers into memory. */
|
||||
Harness_Hook_FlushRenderer(); /* Dethrace. Flush buffers into memory. */
|
||||
RenderSmoke(gRender_screen, gDepth_buffer, gCamera, &gCamera_to_world, gFrame_period);
|
||||
RenderSparks(gRender_screen, gDepth_buffer, gCamera, &gCamera_to_world, gFrame_period);
|
||||
RenderProximityRays(gRender_screen, gDepth_buffer, gCamera, &gCamera_to_world, gFrame_period);
|
||||
|
|
|
|||
|
|
@ -376,10 +376,10 @@ int BurstPedestrian(tPedestrian_data* pPedestrian, float pSplattitudinalitude, i
|
|||
tU32 the_time;
|
||||
LOG_TRACE("(%p, %f, %d)", pPedestrian, pSplattitudinalitude, pAllow_explosion);
|
||||
|
||||
#if defined(DETHRACE_FIX_BUGS)
|
||||
min_speed = 0;
|
||||
max_speed = 0;
|
||||
#endif
|
||||
#if defined(DETHRACE_FIX_BUGS)
|
||||
min_speed = 0;
|
||||
max_speed = 0;
|
||||
#endif
|
||||
exploded = 0;
|
||||
for (i = 0; i < COUNT_OF(gPed_gib_counts); i++) {
|
||||
for (j = 0; j < gPed_size_counts[i]; j++) {
|
||||
|
|
@ -3400,11 +3400,11 @@ void DropPedPoint() {
|
|||
void DropInitPedPoint() {
|
||||
LOG_TRACE("()");
|
||||
|
||||
#if defined(DETHRACE_FIX_BUGS)
|
||||
if (gPath_actor == NULL) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined(DETHRACE_FIX_BUGS)
|
||||
if (gPath_actor == NULL) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
gInit_ped_instruc = gPed_instruc_count;
|
||||
DropPedPoint2();
|
||||
NewTextHeadupSlot(4, 0, 2000, -1, "Dropped initial pedestrian point");
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@ harness_br_renderer* renderer_state;
|
|||
br_pixelmap* last_dst = NULL;
|
||||
br_pixelmap* last_src = NULL;
|
||||
|
||||
br_pixelmap *last_colour_buffer, *last_depth_buffer;
|
||||
|
||||
unsigned int last_frame_time = 0;
|
||||
int force_nullrenderer = 0;
|
||||
|
||||
|
|
@ -371,9 +369,7 @@ int Harness_CalculateFrameDelay() {
|
|||
|
||||
// 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;
|
||||
renderer->BeginScene(camera, colour_buffer);
|
||||
renderer->BeginScene(camera, colour_buffer, depth_buffer);
|
||||
}
|
||||
|
||||
void Harness_Hook_BrZbSceneRenderAdd(br_actor* tree) {
|
||||
|
|
@ -384,7 +380,7 @@ void Harness_Hook_renderFaces(br_actor* actor, br_model* model, br_material* mat
|
|||
}
|
||||
|
||||
void Harness_Hook_BrZbSceneRenderEnd() {
|
||||
renderer->FlushBuffers(last_colour_buffer, last_depth_buffer);
|
||||
renderer->FlushBuffers();
|
||||
renderer->EndScene();
|
||||
}
|
||||
|
||||
|
|
@ -415,7 +411,7 @@ void Harness_Hook_PDSetKeyArray() {
|
|||
}
|
||||
|
||||
void Harness_Hook_FlushRenderer() {
|
||||
renderer->FlushBuffers(last_colour_buffer, last_depth_buffer);
|
||||
renderer->FlushBuffers();
|
||||
}
|
||||
|
||||
void Harness_Hook_BrMaterialUpdate(br_material* mat, br_uint_16 flags) {
|
||||
|
|
|
|||
|
|
@ -12,11 +12,8 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
extern float gCamera_hither;
|
||||
extern float gCamera_yon;
|
||||
|
||||
static GLuint screen_buffer_vao, screen_buffer_ebo;
|
||||
static GLuint screen_texture, palette_texture, depth_texture;
|
||||
static GLuint fullscreen_quad_texture, palette_texture, depth_texture;
|
||||
|
||||
static GLuint shader_program_2d;
|
||||
static GLuint shader_program_3d;
|
||||
|
|
@ -28,29 +25,33 @@ static uint16_t* depth_buffer_flip_pixels;
|
|||
static int window_width, window_height, render_width, render_height;
|
||||
static int vp_x, vp_y, vp_width, vp_height;
|
||||
|
||||
static br_pixelmap* last_shade_table = NULL;
|
||||
static br_pixelmap *last_colour_buffer, *last_depth_buffer, *last_shade_table;
|
||||
static int dirty_buffers = 0;
|
||||
|
||||
tStored_material* current_material;
|
||||
static GLuint current_framebuffer_texture;
|
||||
static int generated_current_framebuffer_for_this_frame = 0;
|
||||
|
||||
static tStored_material* current_material;
|
||||
|
||||
struct {
|
||||
GLuint pixels, uv_transform;
|
||||
GLuint texture_pixelmap;
|
||||
GLuint uv_transform;
|
||||
GLuint shade_table;
|
||||
GLuint blend_table;
|
||||
GLuint blend_enabled;
|
||||
GLuint current_framebuffer;
|
||||
GLuint model, view, projection;
|
||||
GLuint palette_index_override;
|
||||
GLuint clip_plane_count;
|
||||
GLuint clip_planes[6];
|
||||
GLuint light_value;
|
||||
GLuint viewport_height;
|
||||
} uniforms_3d;
|
||||
|
||||
struct {
|
||||
GLuint pixels, palette;
|
||||
} uniforms_2d;
|
||||
|
||||
struct {
|
||||
GLuint pixels, palette;
|
||||
} uniforms_2dpp;
|
||||
|
||||
GLuint CreateShaderProgram(char* name, const char* vertex_shader, const int vertex_shader_len, const char* fragment_shader, const int fragment_shader_len) {
|
||||
int success;
|
||||
char log_buffer[1024];
|
||||
|
|
@ -122,17 +123,23 @@ void LoadShaders() {
|
|||
uniforms_3d.clip_planes[i] = GetValidatedUniformLocation(shader_program_3d, name);
|
||||
}
|
||||
uniforms_3d.model = GetValidatedUniformLocation(shader_program_3d, "u_model");
|
||||
uniforms_3d.pixels = GetValidatedUniformLocation(shader_program_3d, "u_pixels");
|
||||
uniforms_3d.texture_pixelmap = GetValidatedUniformLocation(shader_program_3d, "u_texture_pixelmap");
|
||||
uniforms_3d.uv_transform = GetValidatedUniformLocation(shader_program_3d, "u_texture_coords_transform");
|
||||
uniforms_3d.shade_table = GetValidatedUniformLocation(shader_program_3d, "u_shade_table");
|
||||
uniforms_3d.blend_table = GetValidatedUniformLocation(shader_program_3d, "u_blend_table");
|
||||
uniforms_3d.blend_enabled = GetValidatedUniformLocation(shader_program_3d, "u_blend_enabled");
|
||||
uniforms_3d.current_framebuffer = GetValidatedUniformLocation(shader_program_3d, "u_current_framebuffer");
|
||||
uniforms_3d.projection = GetValidatedUniformLocation(shader_program_3d, "u_projection");
|
||||
uniforms_3d.palette_index_override = GetValidatedUniformLocation(shader_program_3d, "u_palette_index_override");
|
||||
uniforms_3d.view = GetValidatedUniformLocation(shader_program_3d, "u_view");
|
||||
uniforms_3d.light_value = GetValidatedUniformLocation(shader_program_3d, "u_light_value");
|
||||
uniforms_3d.viewport_height = GetValidatedUniformLocation(shader_program_3d, "u_viewport_height");
|
||||
|
||||
// bind the uniform samplers to texture units. palette=1, shadetable=2
|
||||
glUniform1i(uniforms_3d.pixels, 0);
|
||||
// bind the uniform samplers to texture units
|
||||
glUniform1i(uniforms_3d.texture_pixelmap, 0);
|
||||
glUniform1i(uniforms_3d.shade_table, 2);
|
||||
glUniform1i(uniforms_3d.blend_table, 3);
|
||||
glUniform1i(uniforms_3d.current_framebuffer, 4);
|
||||
}
|
||||
|
||||
void SetupFullScreenRectGeometry() {
|
||||
|
|
@ -221,10 +228,11 @@ void GLRenderer_Init(int width, int height, int pRender_width, int pRender_heigh
|
|||
glCullFace(GL_BACK);
|
||||
|
||||
// textures
|
||||
glGenTextures(1, &screen_texture);
|
||||
glGenTextures(1, &fullscreen_quad_texture);
|
||||
glGenTextures(1, &palette_texture);
|
||||
glGenTextures(1, &framebuffer_texture);
|
||||
glGenTextures(1, &depth_texture);
|
||||
glGenTextures(1, ¤t_framebuffer_texture);
|
||||
|
||||
// setup framebuffer
|
||||
glGenFramebuffers(1, &framebuffer_id);
|
||||
|
|
@ -234,15 +242,25 @@ void GLRenderer_Init(int width, int height, int pRender_width, int pRender_heigh
|
|||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, fullscreen_quad_texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, palette_texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, framebuffer_texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, render_width, render_height, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebuffer_texture, 0);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, depth_texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glBindTexture(GL_TEXTURE_2D, current_framebuffer_texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, depth_texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, render_width, render_height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_texture, 0);
|
||||
|
||||
|
|
@ -272,8 +290,6 @@ void GLRenderer_SetPalette(uint8_t* rgba_colors) {
|
|||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, palette_texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, gl_palette);
|
||||
|
||||
// reset active texture back to default
|
||||
|
|
@ -283,30 +299,48 @@ void GLRenderer_SetPalette(uint8_t* rgba_colors) {
|
|||
}
|
||||
|
||||
void GLRenderer_SetShadeTable(br_pixelmap* table) {
|
||||
|
||||
if (last_shade_table == table) {
|
||||
return;
|
||||
}
|
||||
|
||||
// shade table uses texture unit 2
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
tStored_pixelmap* stored = table->stored;
|
||||
glBindTexture(GL_TEXTURE_2D, stored->id);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
// reset active texture back to default
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
last_shade_table = table;
|
||||
}
|
||||
|
||||
void GLRenderer_SetBlendTable(br_pixelmap* table) {
|
||||
|
||||
if (!generated_current_framebuffer_for_this_frame) {
|
||||
glActiveTexture(GL_TEXTURE4);
|
||||
glBindTexture(GL_TEXTURE_2D, current_framebuffer_texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, render_width, render_height, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, last_colour_buffer->pixels);
|
||||
generated_current_framebuffer_for_this_frame = 1;
|
||||
}
|
||||
|
||||
// blend table uses texture unit 3
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
tStored_pixelmap* stored = table->stored;
|
||||
glBindTexture(GL_TEXTURE_2D, stored->id);
|
||||
|
||||
// reset active texture back to default
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
extern br_v1db_state v1db;
|
||||
|
||||
void GLRenderer_BeginScene(br_actor* camera, br_pixelmap* colour_buffer) {
|
||||
glViewport(colour_buffer->base_x, render_height - colour_buffer->height - colour_buffer->base_y, colour_buffer->width, colour_buffer->height);
|
||||
void GLRenderer_BeginScene(br_actor* camera, br_pixelmap* colour_buffer, br_pixelmap* depth_buffer) {
|
||||
last_colour_buffer = colour_buffer;
|
||||
last_depth_buffer = depth_buffer;
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glViewport(colour_buffer->base_x, render_height - colour_buffer->height - colour_buffer->base_y, colour_buffer->width, colour_buffer->height);
|
||||
glUseProgram(shader_program_3d);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glUniform1i(uniforms_3d.viewport_height, colour_buffer->height);
|
||||
|
||||
int enabled_clip_planes = 0;
|
||||
for (int i = 0; i < v1db.enabled_clip_planes.max; i++) {
|
||||
|
|
@ -344,34 +378,34 @@ void GLRenderer_BeginScene(br_actor* camera, br_pixelmap* colour_buffer) {
|
|||
p.m[2][2] *= -1;
|
||||
glUniformMatrix4fv(uniforms_3d.projection, 1, GL_FALSE, &p.m[0][0]);
|
||||
|
||||
// DebugCamera_Update();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id);
|
||||
}
|
||||
|
||||
void GLRenderer_EndScene() {
|
||||
|
||||
// switch back to default fb
|
||||
// switch back to default fb and reset
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
CHECK_GL_ERROR("GLRenderer_RenderFullScreenQuad");
|
||||
generated_current_framebuffer_for_this_frame = 0;
|
||||
CHECK_GL_ERROR("GLRenderer_EndScene");
|
||||
}
|
||||
|
||||
void GLRenderer_FullScreenQuad(uint8_t* screen_buffer) {
|
||||
|
||||
glViewport(vp_x, vp_y, vp_width, vp_height);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glUseProgram(shader_program_2d);
|
||||
glBindTexture(GL_TEXTURE_2D, screen_texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, fullscreen_quad_texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, render_width, render_height, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, screen_buffer);
|
||||
|
||||
glBindVertexArray(screen_buffer_vao);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, screen_buffer_ebo);
|
||||
glUseProgram(shader_program_2d);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
CHECK_GL_ERROR("GLRenderer_RenderFullScreenQuad");
|
||||
}
|
||||
|
||||
|
|
@ -383,6 +417,7 @@ void GLRenderer_ClearBuffers() {
|
|||
// clear real framebuffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
CHECK_GL_ERROR("GLRenderer_ClearBuffers");
|
||||
}
|
||||
|
||||
|
|
@ -494,6 +529,16 @@ void setActiveMaterial(tStored_material* material) {
|
|||
GLRenderer_SetShadeTable(material->shade_table);
|
||||
}
|
||||
|
||||
if (material->index_blend) {
|
||||
glUniform1i(uniforms_3d.blend_enabled, 1);
|
||||
GLRenderer_SetBlendTable(material->index_blend);
|
||||
// materials with index_blend do not write to depth buffer (https://www.cwaboard.co.uk/viewtopic.php?p=105846&sid=58ad8910238000ca14b01dad85117175#p105846)
|
||||
glDepthMask(GL_FALSE);
|
||||
} else {
|
||||
glUniform1i(uniforms_3d.blend_enabled, 0);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
|
||||
if ((material->flags & BR_MATF_LIGHT) && !(material->flags & BR_MATF_PRELIT) && 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);
|
||||
|
|
@ -585,6 +630,7 @@ void GLRenderer_BufferMaterial(br_material* mat) {
|
|||
stored->flags = mat->flags;
|
||||
stored->shade_table = mat->index_shade;
|
||||
stored->index_base = mat->index_base;
|
||||
stored->index_blend = mat->index_blend;
|
||||
}
|
||||
|
||||
void GLRenderer_BufferTexture(br_pixelmap* pm) {
|
||||
|
|
@ -614,7 +660,7 @@ void GLRenderer_BufferTexture(br_pixelmap* pm) {
|
|||
CHECK_GL_ERROR("GLRenderer_BufferTexture");
|
||||
}
|
||||
|
||||
void GLRenderer_FlushBuffers(br_pixelmap* color_buffer, br_pixelmap* depth_buffer) {
|
||||
void GLRenderer_FlushBuffers() {
|
||||
|
||||
if (!dirty_buffers) {
|
||||
return;
|
||||
|
|
@ -626,7 +672,7 @@ void GLRenderer_FlushBuffers(br_pixelmap* color_buffer, br_pixelmap* depth_buffe
|
|||
|
||||
// flip texture to match the expected orientation
|
||||
int dest_y = render_height;
|
||||
uint8_t* pm_pixels = color_buffer->pixels;
|
||||
uint8_t* pm_pixels = last_colour_buffer->pixels;
|
||||
uint8_t new_pixel;
|
||||
for (int y = 0; y < render_height; y++) {
|
||||
dest_y--;
|
||||
|
|
@ -642,13 +688,13 @@ void GLRenderer_FlushBuffers(br_pixelmap* color_buffer, br_pixelmap* depth_buffe
|
|||
glBindTexture(GL_TEXTURE_2D, depth_texture);
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, depth_buffer_flip_pixels);
|
||||
|
||||
dest_y = color_buffer->height;
|
||||
int src_y = render_height - color_buffer->base_y - color_buffer->height;
|
||||
uint16_t* depth_pixels = depth_buffer->pixels;
|
||||
for (int y = 0; y < color_buffer->height; y++) {
|
||||
dest_y = last_depth_buffer->height;
|
||||
int src_y = render_height - last_depth_buffer->base_y - last_depth_buffer->height;
|
||||
uint16_t* depth_pixels = last_depth_buffer->pixels;
|
||||
for (int y = 0; y < last_depth_buffer->height; y++) {
|
||||
dest_y--;
|
||||
for (int x = 0; x < color_buffer->width; x++) {
|
||||
depth_pixels[dest_y * render_width + x] = depth_buffer_flip_pixels[src_y * render_width + color_buffer->base_x + x];
|
||||
for (int x = 0; x < last_depth_buffer->width; x++) {
|
||||
depth_pixels[dest_y * render_width + x] = depth_buffer_flip_pixels[src_y * render_width + last_depth_buffer->base_x + x];
|
||||
}
|
||||
src_y++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
void GLRenderer_Init(int width, int height, int render_width, int render_height);
|
||||
void GLRenderer_SetPalette(uint8_t* rgba_colors);
|
||||
void GLRenderer_BeginScene(br_actor* camera, br_pixelmap* colour_buffer);
|
||||
void GLRenderer_BeginScene(br_actor* camera, br_pixelmap* colour_buffer, br_pixelmap* depth_buffer);
|
||||
void GLRenderer_EndScene();
|
||||
void GLRenderer_FullScreenQuad(uint8_t* screen_buffer);
|
||||
void GLRenderer_Model(br_actor* actor, br_model* model, br_matrix34 model_matrix);
|
||||
|
|
@ -51,7 +51,7 @@ void GLRenderer_BufferTexture(br_pixelmap* pm);
|
|||
void GLRenderer_BufferMaterial(br_material* mat);
|
||||
void GLRenderer_BufferModel(br_model* model);
|
||||
void GLRenderer_ClearBuffers();
|
||||
void GLRenderer_FlushBuffers(br_pixelmap* color_buffer, br_pixelmap* depth_buffer);
|
||||
void GLRenderer_FlushBuffers();
|
||||
void GLRenderer_GetRenderSize(int* width, int* height);
|
||||
void GLRenderer_GetWindowSize(int* width, int* height);
|
||||
void GLRenderer_SetWindowSize(int width, int height);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ tStored_material* NewStoredMaterial() {
|
|||
ctx->index_base = -1;
|
||||
ctx->pixelmap = NULL;
|
||||
ctx->shade_table = NULL;
|
||||
ctx->index_blend = NULL;
|
||||
ctx->identifier[0] = '\0';
|
||||
return ctx;
|
||||
}
|
||||
|
|
@ -49,4 +50,4 @@ tStored_pixelmap* NewStoredPixelmap() {
|
|||
tStored_pixelmap* ctx = malloc(sizeof(tStored_pixelmap));
|
||||
ctx->id = 0;
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ typedef struct tStored_material {
|
|||
br_uint_32 flags;
|
||||
br_pixelmap* shade_table;
|
||||
br_pixelmap* pixelmap;
|
||||
br_pixelmap* index_blend;
|
||||
br_matrix23 map_transform;
|
||||
char identifier[200];
|
||||
} tStored_material;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "renderer.h"
|
||||
|
||||
void Null_Init() {}
|
||||
void Null_BeginFrame(br_actor* camera, br_pixelmap* colour_buffer) {}
|
||||
void Null_BeginFrame(br_actor* camera, br_pixelmap* colour_buffer, br_pixelmap* depth_buffer) {}
|
||||
void Null_EndFrame() {}
|
||||
void Null_SetPalette(uint8_t* palette) {}
|
||||
void Null_RenderFullScreenQuad(uint8_t* src) {}
|
||||
|
|
@ -11,7 +11,7 @@ void Null_ClearBuffers() {}
|
|||
void Null_BufferTexture(br_pixelmap* pm) {}
|
||||
void Null_BufferMaterial(br_material* mat) {}
|
||||
void Null_BufferModel(br_model* model) {}
|
||||
void Null_FlushBuffers(br_pixelmap* color_buffer, br_pixelmap* depth_buffer) {}
|
||||
void Null_FlushBuffers() {}
|
||||
void Null_GetRenderSize(int* width, int* height) {
|
||||
*width = 640;
|
||||
*height = 480;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
typedef struct tRenderer {
|
||||
void (*Init)(int width, int height, int pRender_width, int pRender_height);
|
||||
void (*BeginScene)(br_actor* camera, br_pixelmap* colour_buffer);
|
||||
void (*BeginScene)(br_actor* camera, br_pixelmap* colour_buffer, br_pixelmap* depth_buffer);
|
||||
void (*EndScene)();
|
||||
void (*SetPalette)(uint8_t* palette);
|
||||
void (*FullScreenQuad)(uint8_t* src);
|
||||
|
|
@ -14,7 +14,7 @@ typedef struct tRenderer {
|
|||
void (*BufferTexture)(br_pixelmap* pm);
|
||||
void (*BufferMaterial)(br_material* mat);
|
||||
void (*BufferModel)(br_model* model);
|
||||
void (*FlushBuffers)(br_pixelmap* color_buffer, br_pixelmap* depth_buffer);
|
||||
void (*FlushBuffers)();
|
||||
void (*GetRenderSize)(int* width, int* height);
|
||||
void (*GetWindowSize)(int* width, int* height);
|
||||
void (*SetWindowSize)(int width, int height);
|
||||
|
|
|
|||
|
|
@ -8,12 +8,16 @@ in vec2 v_tex_coord;
|
|||
out uint out_palette_index;
|
||||
|
||||
uniform mat2x3 u_texture_coords_transform;
|
||||
uniform usampler2D u_pixels;
|
||||
uniform usampler2D u_texture_pixelmap;
|
||||
uniform usampler2D u_shade_table;
|
||||
uniform usampler2D u_blend_table;
|
||||
uniform usampler2D u_current_framebuffer;
|
||||
uniform int u_palette_index_override = -1;
|
||||
uniform int u_light_value = -1;
|
||||
uniform vec4 u_clip_planes[6];
|
||||
uniform int u_clip_plane_count = 0;
|
||||
uniform int u_blend_enabled = 0;
|
||||
uniform int u_viewport_height;
|
||||
|
||||
void main() {
|
||||
|
||||
|
|
@ -21,7 +25,7 @@ void main() {
|
|||
// calculate signed plane-vertex distance
|
||||
vec4 v4 = vec4(v_frag_pos.x, v_frag_pos.y, v_frag_pos.z, 1);
|
||||
float d = dot(u_clip_planes[i], v4);
|
||||
if(d < 0.0) discard;
|
||||
if (d < 0.0) discard;
|
||||
}
|
||||
|
||||
if (u_palette_index_override >= 0) {
|
||||
|
|
@ -30,14 +34,22 @@ void main() {
|
|||
} else {
|
||||
// calculate texture uv coordinates
|
||||
vec2 sample_coord = vec3(v_tex_coord.xy, 1) * u_texture_coords_transform;
|
||||
uint texel = texture(u_pixels, sample_coord.xy).r;
|
||||
uint texel = texture(u_texture_pixelmap, sample_coord.xy).r;
|
||||
if (u_light_value >= 0) {
|
||||
// shadetable is a 256x256 image which encodes 256 shades for each color
|
||||
// shade_table is a 256x256 image which encodes 256 lit shades for each color
|
||||
out_palette_index = texelFetch(u_shade_table, ivec2(texel, u_light_value), 0).r;
|
||||
} else {
|
||||
// no shadetable
|
||||
out_palette_index = texel;
|
||||
}
|
||||
|
||||
if (u_blend_enabled == 1 && out_palette_index != 0u) {
|
||||
// blend_table is a 256x256 image which encodes 256 values of blending between texture and existing screen pixel for each color
|
||||
// current_framebuffer is upside down from opengl perspective. We need to sample it upside down.
|
||||
uint fb_color = texelFetch(u_current_framebuffer, ivec2(gl_FragCoord.x, u_viewport_height - gl_FragCoord.y), 0).r;
|
||||
uint blended_color = texelFetch(u_blend_table, ivec2(out_palette_index, fb_color), 0).r;
|
||||
out_palette_index = blended_color;
|
||||
}
|
||||
}
|
||||
// color 0 is always transparent
|
||||
if (out_palette_index == 0u) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue