big rendering overhaul (cleaning and api abstraction)

This commit is contained in:
veclavtalica
2025-01-14 23:20:54 +03:00
parent b7cb37c06a
commit 5059802d09
25 changed files with 290 additions and 424 deletions

View File

@ -4,7 +4,6 @@
#include "twn_engine_context_c.h"
#include "twn_types.h"
#include "twn_deferred_commands.h"
#include "twn_gl_any_rendering_c.h"
#include <glad/glad.h>
#include <stb_ds.h>
@ -14,8 +13,49 @@ static TextureMode texture_mode_last_used = TEXTURE_MODE_UNKNOWN;
static Pipeline pipeline_last_used = PIPELINE_NO;
static void APIENTRY opengl_log(GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar* message,
const void* userParam)
{
(void)source;
(void)type;
(void)id;
(void)severity;
(void)userParam;
log_info("OpenGL: %.*s\n", length, message);
}
bool render_init(void) {
if (gladLoadGL() == 0) {
CRY("Init", "GLAD failed");
return false;
}
log_info("OpenGL context: %s\n", glGetString(GL_VERSION));
glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST);
glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
glHint(GL_FOG_HINT, GL_FASTEST);
/* hook up opengl debugging callback */
if (ctx.game.debug) {
glEnable(GL_DEBUG_OUTPUT);
glDebugMessageCallback(opengl_log, NULL);
}
return true;
}
void start_render_frame(void) {
clear_draw_buffer();
pipeline_last_used = PIPELINE_NO;
}
@ -38,10 +78,13 @@ void end_render_frame(void) {
}
void finally_use_space_pipeline(void) {
static void finally_use_space_pipeline(void) {
if (pipeline_last_used == PIPELINE_SPACE)
return;
depth_range_high = 1.0;
depth_range_low = 0.0;
static GLuint list = 0;
if (!list) {
list = glGenLists(1);
@ -54,9 +97,9 @@ void finally_use_space_pipeline(void) {
glDisable(GL_DEPTH_CLAMP);
glEnable(GL_CULL_FACE);
glDepthRange(0, 1);
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glEnable(GL_DEPTH_TEST);
/* solid white, no modulation */
glColor4ub(255, 255, 255, 255);
@ -76,7 +119,7 @@ void finally_use_space_pipeline(void) {
}
void finally_use_2d_pipeline(void) {
static void finally_use_2d_pipeline(void) {
if (pipeline_last_used == PIPELINE_SPACE) {
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glFlush();
@ -111,6 +154,7 @@ void finally_use_2d_pipeline(void) {
glOrtho(0, (double)ctx.base_render_width, (double)ctx.base_render_height, 0, 0, 1);
glMatrixMode(GL_MODELVIEW);
/* TODO: 2d camera */
glLoadIdentity();
texture_mode_last_used = -1;
@ -118,7 +162,7 @@ void finally_use_2d_pipeline(void) {
}
void finally_use_texture_mode(TextureMode mode) {
static void finally_use_texture_mode(TextureMode mode) {
if (texture_mode_last_used == mode)
return;
@ -248,6 +292,9 @@ void finally_render_skybox(DeferredCommandDrawSkybox command) {
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(&camera_look_at_matrix_solipsist.row[0].x);
glDepthRange(0.0f, 1.0f);
glDisable(GL_FOG);
glDisable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_CUBE_MAP);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap);
@ -370,38 +417,6 @@ void finally_render_skybox(DeferredCommandDrawSkybox command) {
}
void finally_apply_fog(DeferredCommandApplyFog command) {
if (command.density < 0.0f || command.density > 1.0f)
log_warn("Invalid fog density given, should be in range [0..1]");
/* TODO: cache it for constant parameters, which is a common case */
glEnable(GL_FOG);
glFogf(GL_FOG_DENSITY, command.density);
glFogf(GL_FOG_START, command.start);
glFogf(GL_FOG_END, command.end);
float color_conv[4];
color_conv[0] = (float)command.color.r / UINT8_MAX;
color_conv[1] = (float)command.color.g / UINT8_MAX;
color_conv[2] = (float)command.color.b / UINT8_MAX;
color_conv[3] = (float)command.color.a / UINT8_MAX;
glFogfv(GL_FOG_COLOR, color_conv);
}
void finally_pop_fog(void) {
glDisable(GL_FOG);
}
void finally_set_depth_range(DeferredCommandDepthRange command) {
glDepthRange(command.low, command.high);
}
void finally_clear_draw_buffer(DeferredCommandClear command) {
glClearColor((1.0f / 255) * command.color.r,
(1.0f / 255) * command.color.g,
@ -418,18 +433,64 @@ void finally_clear_draw_buffer(DeferredCommandClear command) {
}
static GLsizei to_gl_type_enum(int value) {
switch (value) {
case TWN_FLOAT: return GL_FLOAT;
case TWN_INT: return GL_INT;
case TWN_SHORT: return GL_SHORT;
case TWN_UNSIGNED_SHORT: return GL_UNSIGNED_SHORT;
case TWN_UNSIGNED_BYTE: return GL_UNSIGNED_BYTE;
case TWN_BYTE: return GL_BYTE;
default:
CRY("to_gl_type_enum", "Unknown primitive type");
return -1;
}
}
void finally_draw_command(DeferredCommandDraw command) {
/* TODO: don't assume a single vertex array ? */
SDL_assert(command.vertices.arity != 0);
SDL_assert(command.vertices.buffer);
SDL_assert((command.element_buffer && command.element_count != 0) || command.primitive_count != 0);
/* TODO: cache previous setting, don't recommit */
glDepthRange(command.depth_range_low, command.depth_range_high);
/* TODO: cache it for constant parameters, which is a common case */
if (fabsf(0.0f - ctx.game_copy.fog_density) >= 0.00001f) {
glEnable(GL_FOG);
/* clamp to valid range */
ctx.game_copy.fog_density = clampf(ctx.game_copy.fog_density, 0.0, 1.0);
glFogf(GL_FOG_DENSITY, ctx.game_copy.fog_density);
glFogf(GL_FOG_START, ctx.game_copy.fog_start);
glFogf(GL_FOG_END, ctx.game_copy.fog_end);
float color_conv[4];
color_conv[0] = (float)ctx.game_copy.fog_color.r / UINT8_MAX;
color_conv[1] = (float)ctx.game_copy.fog_color.g / UINT8_MAX;
color_conv[2] = (float)ctx.game_copy.fog_color.b / UINT8_MAX;
color_conv[3] = (float)ctx.game_copy.fog_color.a / UINT8_MAX;
glFogfv(GL_FOG_COLOR, color_conv);
} else
glDisable(GL_FOG);
if (command.pipeline == PIPELINE_SPACE)
finally_use_space_pipeline();
else
finally_use_2d_pipeline();
finally_use_texture_mode(command.texture_mode);
glBindBuffer(GL_ARRAY_BUFFER, command.vertices.buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, command.element_buffer);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(command.vertices.arity,
command.vertices.type,
to_gl_type_enum(command.vertices.type),
command.vertices.stride,
(void *)command.vertices.offset);
@ -439,7 +500,7 @@ void finally_draw_command(DeferredCommandDraw command) {
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0);
glTexCoordPointer(command.texcoords.arity,
command.texcoords.type,
to_gl_type_enum(command.texcoords.type),
command.texcoords.stride,
(void *)command.texcoords.offset);
}
@ -449,7 +510,7 @@ void finally_draw_command(DeferredCommandDraw command) {
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(command.colors.arity,
command.colors.type,
to_gl_type_enum(command.colors.type),
command.colors.stride,
(void *)command.colors.offset);