Skip to content

Commit

Permalink
even more garbage
Browse files Browse the repository at this point in the history
  • Loading branch information
dsvensson committed Jan 6, 2025
1 parent b826558 commit 74cbe2a
Show file tree
Hide file tree
Showing 17 changed files with 363 additions and 22 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ if(RENDERER_MODERN_OPENGL)
${MODERN_GLSL_DIR}/hud_draw_polygon.vertex.glsl
${MODERN_GLSL_DIR}/lighting.compute.glsl
${MODERN_GLSL_DIR}/lighting_copy.compute.glsl
${MODERN_GLSL_DIR}/wboit_compose.fragment.glsl
${MODERN_GLSL_DIR}/wboit_compose.vertex.glsl
${MODERN_GLSL_DIR}/post_process_screen.fragment.glsl
${MODERN_GLSL_DIR}/post_process_screen.vertex.glsl
${MODERN_GLSL_DIR}/simple.fragment.glsl
Expand Down
20 changes: 18 additions & 2 deletions src/cl_ents.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,15 @@ void CL_AddEntityToList(visentlist_t* list, visentlist_entrytype_t vistype, enti

ent = &list->list[cl_visents.count].ent;
list->list[cl_visents.count].type = type;
list->list[cl_visents.count].distance = VectorDistanceQuick(cl.simorg, ent->origin);
if (ent->alpha < 1.0f && ent->alpha > 0.0f) {
vec3_t center;
center[0] = (ent->model->mins[0] + ent->model->maxs[0]) / 2.0f;
center[1] = (ent->model->mins[1] + ent->model->maxs[1]) / 2.0f;
center[2] = (ent->model->mins[2] + ent->model->maxs[2]) / 2.0f;
list->list[cl_visents.count].distance = VectorDistance(cl.simorg, center);
} else {
list->list[cl_visents.count].distance = VectorDistanceQuick(cl.simorg, ent->origin);
}
list->list[cl_visents.count].draw[vistype] = true;

ent->outlineScale = 0.5f * (r_refdef2.outlineBase + DotProduct(ent->origin, r_refdef2.outline_vpn));
Expand Down Expand Up @@ -234,7 +242,15 @@ void CL_AddEntity(entity_t *ent)
ent->renderfx |= RF_NOSHADOW;
}
else {
vistype = visent_normal;
if (ent->alpha == 0.0f || ent->alpha == 1.0f)
{
vistype = visent_normal;
ent->alpha = 1.0f;
}
else
{
vistype = visent_alpha;
}
}

CL_AddEntityToList(&cl_visents, vistype, ent, type, shell);
Expand Down
111 changes: 111 additions & 0 deletions src/gl_framebuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ static const char* framebuffer_texture_names[] = {
"depth", // fbtex_depth
"env", // fbtex_bloom,
"norms", // fbtex_worldnormals,
"wboit-accum", // fbtex_oit_accumulate
"wboit-reveal", // fbtex_oit_reveal
};
static qbool framebuffer_depth_buffer[] = {
false, // framebuffer_none
Expand Down Expand Up @@ -195,6 +197,7 @@ GL_StaticProcedureDeclaration(glBlitNamedFramebuffer, "readFrameBuffer=%u, drawF
GL_StaticProcedureDeclaration(glDrawBuffers, "n=%d, bufs=%p", GLsizei n, const GLenum* bufs)
GL_StaticProcedureDeclaration(glClearBufferfv, "buffer=%u, drawbuffer=%d, value=%p", GLenum buffer, GLint drawbuffer, const GLfloat* value)
GL_StaticProcedureDeclaration(glClipControl, "origin=%u, depth=%u", GLenum origin, GLenum depth)
GL_StaticProcedureDeclaration(glBlendFunci, "attachment=%u, src=%u, dst=%u", GLenum attachment, GLenum src, GLenum dst)

// Multi-sampled
GL_StaticProcedureDeclaration(glRenderbufferStorageMultisample, "target=%x, samples=%d, internalformat=%x, width=%d, height=%d", GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
Expand Down Expand Up @@ -285,6 +288,8 @@ void GL_InitialiseFramebufferHandling(void)
GL_LoadOptionalFunction(glClipControl);
}

GL_LoadOptionalFunction(glBlendFunci);

memset(framebuffer_data, 0, sizeof(framebuffer_data));
}

Expand Down Expand Up @@ -585,6 +590,112 @@ qbool GL_FramebufferEndWorldNormals(framebuffer_id id)
return true;
}

qbool GL_FrameBufferStartOrderIndependentTransparency(framebuffer_id id)
{
struct oit_s {
fbtex_id id;
GLenum fmt;
GLenum attachment;
};
framebuffer_data_t* fb = NULL;
GLenum buffers[2] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
float accumClearValue[] = { 0.0f, 0.0f, 0.0f, 0.0f };
float revealClearValue[] = { 1.0f, 1.0f, 1.0f, 1.0f };
int i;

struct oit_s textures[] = {
{
.id = fbtex_oit_accumulate,
.fmt = GL_RGBA16F,
.attachment = GL_COLOR_ATTACHMENT0,
},
{
.id = fbtex_oit_reveal,
.fmt = GL_R16F,
.attachment = GL_COLOR_ATTACHMENT1,
},
};

if (!GL_Supported(R_SUPPORT_FRAMEBUFFERS)) {
return false;
}

id = VID_MultisampledAlternateId(id);
fb = &framebuffer_data[id];
if (!fb->glref) {
return false;
}

for (i = 0; i < sizeof(textures) / sizeof(textures[0]); i++) {
struct oit_s tex = textures[i];

if (!R_TextureReferenceIsValid(fb->texture[tex.id])) {
char label[128];

strlcpy(label, framebuffer_names[id], sizeof(label));
strlcat(label, "/", sizeof(label));
strlcat(label, framebuffer_texture_names[tex.id], sizeof(label));

if (fb->samples) {
GL_CreateTexturesWithIdentifier(texture_type_2d_multisampled, 1, &fb->texture[tex.id], label);
if (!R_TextureReferenceIsValid(fb->texture[tex.id])) {
return false;
}
GL_TexStorage2DMultisample(fb->texture[tex.id], fb->samples, tex.fmt, fb->width, fb->height, EZ_USE_FIXED_SAMPLE_LOCATIONS);
}
else {
GL_CreateTexturesWithIdentifier(texture_type_2d, 1, &fb->texture[tex.id], label);
if (!R_TextureReferenceIsValid(fb->texture[tex.id])) {
return false;
}
GL_TexStorage2D(fb->texture[tex.id], 1, tex.fmt, fb->width, fb->height, false);
renderer.TextureSetFiltering(fb->texture[tex.id], texture_minification_nearest, texture_magnification_nearest);
renderer.TextureWrapModeClamp(fb->texture[tex.id]);
}
R_TextureSetFlag(fb->texture[tex.id], R_TextureGetFlag(fb->texture[tex.id]) | TEX_NO_TEXTUREMODE);
}

GL_FramebufferTexture(fb->glref, tex.attachment, GL_TextureNameFromReference(fb->texture[tex.id]), 0);
}
GL_Procedure(glDrawBuffers, 2, buffers);
GL_Procedure(glClearBufferfv, GL_COLOR, 0, accumClearValue);
GL_Procedure(glClearBufferfv, GL_COLOR, 1, revealClearValue);

return true;
}

void GL_OitBlend(void) {
GL_Procedure(glBlendFunci, 0, GL_ONE, GL_ONE);
GL_Procedure(glBlendFunci, 1, GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
}

qbool GL_FrameBufferEndOrderIndependentTransparency(framebuffer_id id)
{
framebuffer_data_t* fb = NULL;
GLenum buffer = GL_COLOR_ATTACHMENT0;

if (!GL_Supported(R_SUPPORT_FRAMEBUFFERS)) {
return false;
}

id = VID_MultisampledAlternateId(id);
fb = &framebuffer_data[id];
if (!fb->glref) {
return false;
}

GL_FramebufferTexture(fb->glref, GL_COLOR_ATTACHMENT0, GL_TextureNameFromReference(fb->texture[fbtex_standard]), 0);
GL_FramebufferTexture(fb->glref, GL_COLOR_ATTACHMENT1, 0, 0);
GL_Procedure(glDrawBuffers, 1, &buffer);

if (fb->samples && id == framebuffer_std_ms) {
// Resolve multi-samples
GL_MultiSamplingResolve(framebuffer_std_ms, framebuffer_std, fbtex_oit_reveal, framebuffer_std_blit_ms, framebuffer_std_blit);
}
return true;
}


void GL_FramebufferDelete(framebuffer_id id)
{
int i;
Expand Down
5 changes: 5 additions & 0 deletions src/gl_framebuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ typedef enum {
fbtex_depth,
fbtex_bloom,
fbtex_worldnormals,
fbtex_oit_accumulate,
fbtex_oit_reveal,
fbtex_count
} fbtex_id;

Expand All @@ -61,6 +63,9 @@ qbool GL_FramebufferEnabled3D(void);
qbool GL_FramebufferStartWorldNormals(framebuffer_id id);
qbool GL_FramebufferEndWorldNormals(framebuffer_id id);

qbool GL_FrameBufferStartOrderIndependentTransparency(framebuffer_id id);
qbool GL_FrameBufferEndOrderIndependentTransparency(framebuffer_id id);

int GL_FramebufferMultisamples(framebuffer_id framebuffer);
void GL_FramebufferDeleteAll(void);
int GL_FramebufferFxaaPreset(void);
Expand Down
2 changes: 2 additions & 0 deletions src/gl_program.c
Original file line number Diff line number Diff line change
Expand Up @@ -1364,6 +1364,7 @@ static void GL_BuildCoreDefinitions(void)
GL_DefineProgram_VF(r_program_aliasmodel, "aliasmodel", true, draw_aliasmodel, renderer_modern, GLM_CompileAliasModelProgram, STDOPTIONS_FOG);
GL_DefineProgram_VF(r_program_brushmodel, "brushmodel", true, draw_world, renderer_modern, GLM_CompileDrawWorldProgram, STDOPTIONS_FOG);
GL_DefineProgram_VF(r_program_brushmodel_alphatested, "brushmodel-alphatested", true, draw_world, renderer_modern, GLM_CompileDrawWorldProgramAlphaTested, STDOPTIONS_FOG);
GL_DefineProgram_VF(r_program_brushmodel_translucent, "brushmodel-translucent", true, draw_world, renderer_modern, GLM_CompileDrawWorldProgramTranslucent, STDOPTIONS_FOG);
GL_DefineProgram_VF(r_program_sprite3d, "3d-sprites", false, draw_sprites, renderer_modern, GLM_Compile3DSpriteProgram, STDOPTIONS_FOG);
GL_DefineProgram_VF(r_program_hud_images, "image-draw", true, hud_draw_image, renderer_modern, GLM_CreateMultiImageProgram, STDOPTIONS_NONE);
GL_DefineProgram_VF(r_program_hud_circles, "circle-draw", false, hud_draw_circle, renderer_modern, GLM_CompileHudCircleProgram, STDOPTIONS_NONE);
Expand All @@ -1372,6 +1373,7 @@ static void GL_BuildCoreDefinitions(void)
GL_DefineProgram_VF(r_program_fx_world_geometry, "world-geometry", true, fx_world_geometry, renderer_modern, GLM_CompileWorldGeometryProgram, STDOPTIONS_NONE);
GL_DefineProgram_VF(r_program_simple, "simple", false, simple, renderer_modern, GLM_CompileSimpleProgram, STDOPTIONS_NONE);
GL_DefineProgram_VF(r_program_simple3d, "simple3d", false, simple3d, renderer_modern, GLM_CompileSimple3dProgram, STDOPTIONS_NONE);
GL_DefineProgram_VF(r_program_wboit_compose, "wboit-compose", true, wboit_compose, renderer_modern, GLM_CompileWorldGeometryProgram, STDOPTIONS_NONE);
#endif

#ifdef RENDERER_OPTION_CLASSIC_OPENGL
Expand Down
13 changes: 13 additions & 0 deletions src/gl_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ static GLenum glBlendFuncValuesSource[] = {
GL_ONE, // r_blendfunc_src_one_dest_zero,
GL_ZERO, // r_blendfunc_src_zero_dest_one,
GL_ONE, // r_blendfunc_src_one_dest_one_minus_src_color,
GL_ONE, // r_blendfunc_src_one_dest_one
GL_SRC_ALPHA, // r_blendfunc_src_alpha_dest_one_minus_src_alpha
};
static GLenum glBlendFuncValuesDestination[] = {
GL_ZERO, // r_blendfunc_overwrite,
Expand All @@ -166,6 +168,8 @@ static GLenum glBlendFuncValuesDestination[] = {
GL_ZERO, // r_blendfunc_src_one_dest_zero,
GL_ONE, // r_blendfunc_src_zero_dest_one,
GL_ONE_MINUS_SRC_COLOR, // r_blendfunc_src_one_dest_one_minus_src_color,
GL_ONE, // r_blendfunc_src_one_dest_one
GL_ONE_MINUS_SRC_ALPHA, // r_blendfunc_src_alpha_dest_one_minus_src_alpha
};
static GLenum glPolygonModeValues[] = {
GL_FILL, // r_polygonmode_fill,
Expand Down Expand Up @@ -217,6 +221,8 @@ static const char* txtBlendFuncNames[] = {
"src_one_dest_zero", // r_blendfunc_src_one_dest_zero
"src_zero_dest_one", // r_blendfunc_src_zero_dest_one
"src_one_dest_one_minus_src_color", // "r_blendfunc_src_one_dest_one_minus_src_color"
"src_one_dest_one", // "r_blendfunc_src_one_dest_one"
"src_alpha_dest_one_minus_src_alpha", // "r_blendfunc_src_alpha_dest_one_minus_src_alpha"
};
static const char* txtPolygonModeValues[] = {
"fill", // r_polygonmode_fill,
Expand Down Expand Up @@ -359,6 +365,9 @@ rendering_state_t* R_Init3DSpriteRenderingState(r_state_id id, const char* name)
current->field = state->field; \
}

// TODO
void GL_OitBlend(void);

void GL_ApplyRenderingState(r_state_id id)
{
rendering_state_t* state = &states[id];
Expand Down Expand Up @@ -397,6 +406,10 @@ void GL_ApplyRenderingState(r_state_id id)
);
R_TraceLogAPICall("glBlendFunc(%s)", txtBlendFuncNames[state->blendFunc]);
}
if (state->blendFunc == r_blendfunc_src_one_dest_one)
{
GL_OitBlend();
}
if (state->line.width != current->line.width) {
glLineWidth(current->line.width = state->line.width);
R_TraceLogAPICall("glLineWidth(%f)", current->line.width);
Expand Down
27 changes: 25 additions & 2 deletions src/gl_texture_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,31 @@ void GL_TexStorage2D(
int level;
GLsizei level_width = width;
GLsizei level_height = height;
GLenum format = (internalformat == GL_RGBA8 || internalformat == GL_SRGB8_ALPHA8 || internalformat == GL_RGBA16F ? GL_RGBA : GL_RGB);
GLenum type = (internalformat == GL_RGBA16F || internalformat == GL_RGB16F ? GL_FLOAT : GL_UNSIGNED_BYTE);
GLenum format;
GLenum type;

switch (internalformat) {
case GL_RGBA8:
case GL_RGB16F:
case GL_SRGB8_ALPHA8:
format = GL_RGBA;
break;
case GL_R32F:
format = GL_RED;
default:
format = GL_RGB;
break;
}
switch (internalformat) {
case GL_RGBA16F:
case GL_RGB16F:
case GL_R32F:
type = GL_FLOAT;
break;
default:
type = GL_UNSIGNED_BYTE;
break;
}

// this might be completely useless (we don't upload data anyway) but just to keep all calls to the texture consistent
format = ((is_lightmap && GL_Supported(R_SUPPORT_BGRA_LIGHTMAPS)) ? GL_BGRA : format);
Expand Down
3 changes: 2 additions & 1 deletion src/glm_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ void GLM_StateBeginImageDraw(void);

typedef enum {
opaque_world, // also contains alpha-tested
alpha_surfaces
alpha_surfaces,
translucent_surfaces,
} glm_brushmodel_drawcall_type;

void GLM_DrawWorldModelBatch(glm_brushmodel_drawcall_type type);
Expand Down
62 changes: 62 additions & 0 deletions src/glm_rmain.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,21 @@ qbool GLM_CompileWorldGeometryProgram(void)
return R_ProgramReady(r_program_fx_world_geometry) && GLM_CompilePostProcessVAO();
}

// If this returns false then the framebuffer will be blitted instead
qbool GLM_CompileWboitComposeProgram(void)
{
int post_process_flags = 0;

if (R_ProgramRecompileNeeded(r_program_wboit_compose, post_process_flags)) {
// Initialise program for drawing image
R_ProgramCompile(r_program_wboit_compose);

R_ProgramSetCustomOptions(r_program_wboit_compose, post_process_flags);
}

return R_ProgramReady(r_program_wboit_compose) && GLM_CompilePostProcessVAO();
}

static void GLM_DrawWorldOutlines(void)
{
texture_ref normals = GL_FramebufferTextureReference(framebuffer_std, fbtex_worldnormals);
Expand Down Expand Up @@ -99,6 +114,44 @@ static void GLM_DrawWorldOutlines(void)
}
}

static void GLM_DrawOrderIndependentTransparency(void)
{
texture_ref accum = GL_FramebufferTextureReference(framebuffer_std, fbtex_oit_accumulate);
texture_ref reveal = GL_FramebufferTextureReference(framebuffer_std, fbtex_oit_reveal);

if (R_TextureReferenceIsValid(accum) && R_TextureReferenceIsValid(reveal) && GLM_CompileWboitComposeProgram()) {
int viewport[4];
int fullscreen_viewport[4];

R_GetViewport(viewport);

// If we are only rendering to a section of the screen then that is the only part of the texture that will be filled in
if (CL_MultiviewEnabled()) {
R_GetFullScreenViewport(fullscreen_viewport);
R_Viewport(fullscreen_viewport[0], fullscreen_viewport[1], fullscreen_viewport[2], fullscreen_viewport[3]);
R_EnableScissorTest(viewport[0], viewport[1], viewport[2], viewport[3]);
} else {
// ignore viewsize and allat crap and set the viewport size to the whole window.
// previously the viewport was already resized, and then resized again later, making the outlines not align.
R_Viewport(0, 0, VID_ScaledWidth3D(), VID_ScaledHeight3D());
}

renderer.TextureUnitBind(0, accum);
renderer.TextureUnitBind(1, reveal);

R_ProgramUse(r_program_wboit_compose);
R_ApplyRenderingState(r_state_oit_compose);

GL_DrawArrays(GL_TRIANGLE_STRIP, 0, 4);

// Restore viewport
R_Viewport(viewport[0], viewport[1], viewport[2], viewport[3]);
if (CL_MultiviewEnabled()) {
R_DisableScissorTest();
}
}
}

void GLM_RenderView(void)
{
GLM_UploadFrameConstants();
Expand All @@ -124,7 +177,16 @@ void GLM_RenderView(void)

GLM_DrawWorldModelBatch(alpha_surfaces);

/*
GL_FrameBufferStartOrderIndependentTransparency(framebuffer_std);
GLM_DrawWorldModelBatch(translucent_surfaces);
GL_FrameBufferEndOrderIndependentTransparency(framebuffer_std);
*/

GLM_DrawOrderIndependentTransparency();

GLM_DrawAliasModelPostSceneBatches();

}

void GLM_PrepareModelRendering(qbool vid_restart)
Expand Down
Loading

0 comments on commit 74cbe2a

Please sign in to comment.