mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2026-07-12 17:31:06 +00:00
Add support for qualifiers like noperspective, do some rewriting on framepasses
This commit is contained in:
parent
0f4fa7a664
commit
14fdb5187c
9 changed files with 99 additions and 44 deletions
|
|
@ -88,6 +88,7 @@ struct CombineMode {
|
|||
uint8_t use_dither : 1;
|
||||
uint8_t use_2cycle : 1;
|
||||
uint8_t light_map : 1;
|
||||
uint8_t tex_persp : 1;
|
||||
uint8_t world_geometry : 1;
|
||||
};
|
||||
u32 flags;
|
||||
|
|
|
|||
|
|
@ -621,13 +621,13 @@ static void gfx_d3d11_shader_get_info(struct ShaderProgram *prg, uint8_t *num_in
|
|||
used_textures[1] = p->used_textures[1];
|
||||
}
|
||||
|
||||
static void gfx_d3d11_create_framebuffer(UNUSED u32 *fbo, UNUSED u32 *depthBuffer, UNUSED u32 *tex, UNUSED u32 width, UNUSED u32 height) {
|
||||
static void gfx_d3d11_create_framebuffer(UNUSED struct FramePass *framePass) {
|
||||
}
|
||||
|
||||
static void gfx_d3d11_delete_framebuffer(UNUSED u32 fbo, UNUSED u32 depthBuffer, UNUSED u32 tex) {
|
||||
static void gfx_d3d11_delete_framebuffer(UNUSED struct FramePass *framePass) {
|
||||
}
|
||||
|
||||
static void gfx_d3d11_set_framebuffer(UNUSED u32 fbo, UNUSED u32 width, UNUSED u32 height) {
|
||||
static void gfx_d3d11_set_framebuffer(UNUSED struct FramePass *framePass) {
|
||||
}
|
||||
|
||||
static void gfx_d3d11_reset_framebuffer(void) {
|
||||
|
|
@ -950,7 +950,13 @@ static void gfx_d3d11_start_frame(void) {
|
|||
d3d.context->OMSetRenderTargets(1, d3d.backbuffer_view.GetAddressOf(), d3d.depth_stencil_view.Get());
|
||||
|
||||
// Clear render targets
|
||||
const float clearColor[] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
struct FramePass *framePass = gfx_get_current_frame_pass();
|
||||
const float clearColor[] = {
|
||||
framePass->clearColor[0] / 255.0f,
|
||||
framePass->clearColor[1] / 255.0f,
|
||||
framePass->clearColor[2] / 255.0f,
|
||||
framePass->clearColor[3] / 255.0f
|
||||
};
|
||||
d3d.context->ClearRenderTargetView(d3d.backbuffer_view.Get(), clearColor);
|
||||
d3d.context->ClearDepthStencilView(d3d.depth_stencil_view.Get(), D3D11_CLEAR_DEPTH, 1.0f, 0);
|
||||
|
||||
|
|
|
|||
|
|
@ -154,13 +154,13 @@ static void gfx_dummy_renderer_shader_get_info(UNUSED struct ShaderProgram *prg,
|
|||
used_textures[1] = false;
|
||||
}
|
||||
|
||||
static void gfx_dummy_renderer_create_framebuffer(UNUSED u32 *fbo, UNUSED u32 *depthBuffer, UNUSED u32 *tex, UNUSED u32 width, UNUSED u32 height) {
|
||||
static void gfx_dummy_renderer_create_framebuffer(UNUSED struct FramePass *framePass) {
|
||||
}
|
||||
|
||||
static void gfx_dummy_renderer_delete_framebuffer(UNUSED u32 fbo, UNUSED u32 depthBuffer, UNUSED u32 tex) {
|
||||
static void gfx_dummy_renderer_delete_framebuffer(UNUSED struct FramePass *framePass) {
|
||||
}
|
||||
|
||||
static void gfx_dummy_renderer_set_framebuffer(UNUSED u32 fbo, UNUSED u32 width, UNUSED u32 height) {
|
||||
static void gfx_dummy_renderer_set_framebuffer(UNUSED struct FramePass *framePass) {
|
||||
}
|
||||
|
||||
static void gfx_dummy_renderer_reset_framebuffer(void) {
|
||||
|
|
|
|||
|
|
@ -561,24 +561,24 @@ static void gfx_opengl_shader_get_info(struct ShaderProgram *prg, uint8_t *num_i
|
|||
used_textures[1] = prg->used_textures[1];
|
||||
}
|
||||
|
||||
static void gfx_opengl_create_framebuffer(u32 *fbo, u32 *depthBuffer, u32 *tex, u32 width, u32 height) {
|
||||
glGenFramebuffers(1, fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, *fbo);
|
||||
static void gfx_opengl_create_framebuffer(struct FramePass *framePass) {
|
||||
glGenFramebuffers(1, &framePass->fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framePass->fbo);
|
||||
|
||||
glGenTextures(1, tex);
|
||||
glBindTexture(GL_TEXTURE_2D, *tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
glGenTextures(1, &framePass->passTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, framePass->passTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, framePass->width, framePass->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *tex, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framePass->passTexture, 0);
|
||||
|
||||
// create depth buffer
|
||||
glGenRenderbuffers(1, depthBuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, *depthBuffer);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, *depthBuffer);
|
||||
glGenRenderbuffers(1, &framePass->depthBuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, framePass->depthBuffer);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, framePass->width, framePass->height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, framePass->depthBuffer);
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
LOG_ERROR("Framebuffer is not complete!");
|
||||
|
|
@ -587,15 +587,15 @@ static void gfx_opengl_create_framebuffer(u32 *fbo, u32 *depthBuffer, u32 *tex,
|
|||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
static void gfx_opengl_delete_framebuffer(u32 fbo, u32 depthBuffer, u32 tex) {
|
||||
if (fbo > 0) glDeleteFramebuffers(1, &fbo);
|
||||
if (depthBuffer > 0) glDeleteRenderbuffers(1, &depthBuffer);
|
||||
if (tex > 0) glDeleteTextures(1, &tex);
|
||||
static void gfx_opengl_delete_framebuffer(struct FramePass *framePass) {
|
||||
if (framePass->fbo > 0) { glDeleteFramebuffers(1, &framePass->fbo); }
|
||||
if (framePass->depthBuffer > 0) { glDeleteRenderbuffers(1, &framePass->depthBuffer); }
|
||||
if (framePass->passTexture > 0) { glDeleteTextures(1, &framePass->passTexture); }
|
||||
}
|
||||
|
||||
static void gfx_opengl_set_framebuffer(u32 fbo, u32 width, u32 height) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glViewport(0, 0, width, height);
|
||||
static void gfx_opengl_set_framebuffer(struct FramePass *framePass) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framePass->fbo);
|
||||
glViewport(0, 0, framePass->width, framePass->height);
|
||||
}
|
||||
|
||||
static void gfx_opengl_reset_framebuffer(void) {
|
||||
|
|
@ -777,7 +777,15 @@ static void gfx_opengl_start_frame(void) {
|
|||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDepthMask(GL_TRUE); // Must be set to clear Z-buffer
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
struct FramePass *framePass = gfx_get_current_frame_pass();
|
||||
glClearColor(
|
||||
framePass->clearColor[0] / 255.0f,
|
||||
framePass->clearColor[1] / 255.0f,
|
||||
framePass->clearColor[2] / 255.0f,
|
||||
framePass->clearColor[3] / 255.0f
|
||||
);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1108,12 +1108,13 @@ static void OPTIMIZE_O3 gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t
|
|||
|
||||
struct CombineMode* cm = &rdp.combine_mode;
|
||||
|
||||
cm->use_alpha = (rdp.other_mode_l & (G_BL_A_MEM << 18)) == 0;
|
||||
cm->texture_edge = (rdp.other_mode_l & CVG_X_ALPHA) == CVG_X_ALPHA;
|
||||
cm->use_dither = (rdp.other_mode_l & G_AC_DITHER) == G_AC_DITHER;
|
||||
cm->use_2cycle = (rdp.other_mode_h & (3U << G_MDSFT_CYCLETYPE)) == G_CYC_2CYCLE;
|
||||
cm->use_fog = (rdp.other_mode_l >> 30) == G_BL_CLR_FOG;
|
||||
cm->light_map = (rsp.geometry_mode & G_LIGHT_MAP_EXT) == G_LIGHT_MAP_EXT;
|
||||
cm->use_alpha = (rdp.other_mode_l & (G_BL_A_MEM << 18)) == 0;
|
||||
cm->texture_edge = (rdp.other_mode_l & CVG_X_ALPHA) == CVG_X_ALPHA;
|
||||
cm->use_dither = (rdp.other_mode_l & G_AC_DITHER) == G_AC_DITHER;
|
||||
cm->use_2cycle = (rdp.other_mode_h & (3U << G_MDSFT_CYCLETYPE)) == G_CYC_2CYCLE;
|
||||
cm->use_fog = (rdp.other_mode_l >> 30) == G_BL_CLR_FOG;
|
||||
cm->light_map = (rsp.geometry_mode & G_LIGHT_MAP_EXT) == G_LIGHT_MAP_EXT;
|
||||
cm->tex_persp = (rdp.other_mode_h & G_TP_PERSP) == G_TP_PERSP;
|
||||
cm->world_geometry = gShaderFlagsEnabled && (v1->world_geometry && v2->world_geometry && v3->world_geometry);
|
||||
|
||||
if (cm->texture_edge) {
|
||||
|
|
@ -2095,6 +2096,14 @@ void gfx_start_frame(void) {
|
|||
gfx_current_dimensions.x_adjust_ratio = (4.0f / 3.0f) / gfx_current_dimensions.aspect_ratio;
|
||||
}
|
||||
|
||||
struct FramePass *gfx_get_current_frame_pass(void) {
|
||||
if (gCurrentFramePassIndex < 0) {
|
||||
return &gDefaultGeoFramePass;
|
||||
} else {
|
||||
return &gFramePasses[gCurrentFramePassIndex];
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_process_lua_passes(Gfx *commands, bool *isLuaPassesActive) {
|
||||
for (int i = 0; i < MAX_CUSTOM_FRAME_PASSES; i++) {
|
||||
struct FramePass *framePass = &gFramePasses[i];
|
||||
|
|
@ -2103,7 +2112,7 @@ static void gfx_process_lua_passes(Gfx *commands, bool *isLuaPassesActive) {
|
|||
|
||||
// remove default frame pass if we have lua frame pass
|
||||
if (gDefaultGeoFramePass.active) {
|
||||
gfx_rapi->delete_framebuffer(gDefaultGeoFramePass.fbo, gDefaultGeoFramePass.depthBuffer, gDefaultGeoFramePass.passTexture);
|
||||
gfx_rapi->delete_framebuffer(&gDefaultGeoFramePass);
|
||||
memset(&gDefaultGeoFramePass, 0, sizeof(struct FramePass));
|
||||
}
|
||||
|
||||
|
|
@ -2111,9 +2120,9 @@ static void gfx_process_lua_passes(Gfx *commands, bool *isLuaPassesActive) {
|
|||
|
||||
// setup framebuffer
|
||||
if (framePass->fbo == 0) {
|
||||
gfx_rapi->create_framebuffer(&framePass->fbo, &framePass->depthBuffer, &framePass->passTexture, framePass->width, framePass->height);
|
||||
gfx_rapi->create_framebuffer(framePass);
|
||||
}
|
||||
gfx_rapi->set_framebuffer(framePass->fbo, framePass->width, framePass->height);
|
||||
gfx_rapi->set_framebuffer(framePass);
|
||||
|
||||
gfx_rapi->start_frame(); // resets color and depth
|
||||
|
||||
|
|
@ -2167,6 +2176,7 @@ void gfx_run_basic(Gfx *commands) { // for dummy frames we don't want to do a mu
|
|||
}
|
||||
|
||||
void gfx_run(Gfx *commands) {
|
||||
// Shader TODO: Give directx support for frame passes
|
||||
if (gRenderApi == &gfx_direct3d11_api) {
|
||||
gfx_run_basic(commands);
|
||||
return;
|
||||
|
|
@ -2189,16 +2199,17 @@ void gfx_run(Gfx *commands) {
|
|||
memset(&gDefaultGeoFramePass, 0, sizeof(struct FramePass));
|
||||
gDefaultGeoFramePass.active = true;
|
||||
gDefaultGeoFramePass.drawWorldGeometry = true;
|
||||
gDefaultGeoFramePass.clearColor[3] = 255;
|
||||
}
|
||||
|
||||
// create/update fbo
|
||||
if (gDefaultGeoFramePass.fbo == 0 || gDefaultGeoFramePass.width != gfx_current_dimensions.width || gDefaultGeoFramePass.height != gfx_current_dimensions.height) {
|
||||
gfx_rapi->delete_framebuffer(gDefaultGeoFramePass.fbo, gDefaultGeoFramePass.depthBuffer, gDefaultGeoFramePass.passTexture);
|
||||
gfx_rapi->delete_framebuffer(&gDefaultGeoFramePass);
|
||||
gfx_get_dimensions(&gDefaultGeoFramePass.width, &gDefaultGeoFramePass.height);
|
||||
gfx_rapi->create_framebuffer(&gDefaultGeoFramePass.fbo, &gDefaultGeoFramePass.depthBuffer, &gDefaultGeoFramePass.passTexture, gDefaultGeoFramePass.width, gDefaultGeoFramePass.height);
|
||||
gfx_rapi->create_framebuffer(&gDefaultGeoFramePass);
|
||||
}
|
||||
|
||||
gfx_rapi->set_framebuffer(gDefaultGeoFramePass.fbo, gDefaultGeoFramePass.width, gDefaultGeoFramePass.height);
|
||||
gfx_rapi->set_framebuffer(&gDefaultGeoFramePass);
|
||||
|
||||
gfx_rapi->start_frame(); // resets color and depth
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ struct FramePass {
|
|||
u32 height;
|
||||
bool active;
|
||||
bool drawWorldGeometry;
|
||||
u8 clearColor[4];
|
||||
};
|
||||
|
||||
extern struct RSP rsp;
|
||||
|
|
@ -84,6 +85,7 @@ extern "C" {
|
|||
void gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi, const char *window_title);
|
||||
struct GfxRenderingAPI *gfx_get_current_rendering_api(void);
|
||||
void gfx_start_frame(void);
|
||||
struct FramePass *gfx_get_current_frame_pass(void);
|
||||
void gfx_run_basic(Gfx *commands);
|
||||
void gfx_run(Gfx *commands);
|
||||
void gfx_end_frame_render(void);
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ struct GfxRenderingAPI {
|
|||
struct ShaderProgram *(*lookup_shader)(struct ColorCombiner* cc);
|
||||
struct ShaderProgram *(*lookup_shader_using_index)(uint8_t shaderIndex, uint8_t framePassIndex);
|
||||
void (*shader_get_info)(struct ShaderProgram *prg, uint8_t *num_inputs, bool used_textures[2]);
|
||||
void (*create_framebuffer)(uint32_t *fbo, uint32_t *depthBuffer, uint32_t *tex, uint32_t width, uint32_t height);
|
||||
void (*delete_framebuffer)(uint32_t fbo, uint32_t depthBuffer, uint32_t tex);
|
||||
void (*set_framebuffer)(uint32_t fbo, uint32_t width, uint32_t height);
|
||||
void (*create_framebuffer)(struct FramePass *framePass);
|
||||
void (*delete_framebuffer)(struct FramePass *framePass);
|
||||
void (*set_framebuffer)(struct FramePass *framePass);
|
||||
void (*reset_framebuffer)(void);
|
||||
void (*set_uniform)(struct ShaderProgram *prg, const char *name, ShaderUniformType type, const void *data, uint32_t numElements);
|
||||
uint32_t (*new_texture)(void);
|
||||
|
|
|
|||
|
|
@ -210,6 +210,7 @@ char *gfx_generate_default_fragment_shader_from_cc(struct ColorCombiner *cc) {
|
|||
bool opt_texture_edge = cc->cm.texture_edge;
|
||||
bool opt_2cycle = cc->cm.use_2cycle;
|
||||
bool opt_light_map = cc->cm.light_map;
|
||||
bool opt_tex_persp = cc->cm.tex_persp;
|
||||
bool world_geometry = cc->cm.world_geometry;
|
||||
bool opt_dither = cc->cm.use_dither;
|
||||
|
||||
|
|
@ -219,6 +220,7 @@ char *gfx_generate_default_fragment_shader_from_cc(struct ColorCombiner *cc) {
|
|||
append_line(fs_buf, &fs_len, "#version 410 core");
|
||||
append_line(fs_buf, &fs_len, "out vec4 fragColor;");
|
||||
for (int t = 0; t < 2; t++) {
|
||||
if (!opt_tex_persp) { append_str(fs_buf, &fs_len, "noperspective "); }
|
||||
fs_len += sprintf(fs_buf + fs_len, "in vec2 vTexCoord%d;\n", t);
|
||||
}
|
||||
append_line(fs_buf, &fs_len, "in vec4 vFog;");
|
||||
|
|
@ -549,9 +551,20 @@ void gfx_init_shaders() {
|
|||
}
|
||||
|
||||
static void process_shader_line(struct Shader *shader, struct ShaderInput *referenceInputs, char *output, const char *line) {
|
||||
char type[32], name[MAX_SHADER_VARIABLE_NAME];
|
||||
char qualifier[32] = { 0 }, type[32] = { 0 }, name[MAX_SHADER_VARIABLE_NAME] = { 0 };
|
||||
|
||||
// parse inputs for inputs equivalent to reference inputs
|
||||
if (sscanf(line, "%31s in %31s %31[^; \t\n]", qualifier, type, name) == 3) {
|
||||
for (int i = 0; i < MAX_SHADER_INPUTS; i++) {
|
||||
if (referenceInputs[i].name[0] != '\0' && strcmp(referenceInputs[i].name, name) == 0) {
|
||||
char layoutLine[sizeof(type) + MAX_SHADER_VARIABLE_NAME + 64];
|
||||
snprintf(layoutLine, sizeof(layoutLine), "%s layout(location=%d) in %s %s", qualifier, referenceInputs[i].location, type, name);
|
||||
strncat(output, layoutLine, MAX_SHADER_CODE - strlen(output) - 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sscanf(line, " in %31s %31[^; \t\n]", type, name) == 2) {
|
||||
for (int i = 0; i < MAX_SHADER_INPUTS; i++) {
|
||||
if (referenceInputs[i].name[0] != '\0' && strcmp(referenceInputs[i].name, name) == 0) {
|
||||
|
|
@ -564,6 +577,19 @@ static void process_shader_line(struct Shader *shader, struct ShaderInput *refer
|
|||
}
|
||||
|
||||
// look for and parse outputs
|
||||
if (sscanf(line, "%31s out %31s %31[^; \t\n]", qualifier, type, name) == 3) {
|
||||
// add name to our shader outputs
|
||||
if (shader) {
|
||||
snprintf(shader->shaderOutputs[sShaderOutputCount].name, MAX_SHADER_VARIABLE_NAME, "%s", name);
|
||||
shader->shaderOutputs[sShaderOutputCount].location = sShaderOutputCount;
|
||||
}
|
||||
char layoutLine[sizeof(type) + MAX_SHADER_VARIABLE_NAME + 64];
|
||||
snprintf(layoutLine, sizeof(layoutLine), "%s layout(location=%d) out %s %s", qualifier, sShaderOutputCount, type, name);
|
||||
strncat(output, layoutLine, MAX_SHADER_CODE - strlen(output) - 1);
|
||||
if (sShaderOutputCount < MAX_SHADER_OUTPUTS - 1) { sShaderOutputCount++; }
|
||||
return;
|
||||
}
|
||||
|
||||
if (sscanf(line, " out %31s %31[^; \t\n]", type, name) == 2) {
|
||||
// add name to our shader outputs
|
||||
if (shader) {
|
||||
|
|
|
|||
|
|
@ -460,6 +460,7 @@ int gfx_shader_create_frame_pass() {
|
|||
// set default values
|
||||
framePass->active = true;
|
||||
gfx_get_dimensions(&framePass->width, &framePass->height);
|
||||
framePass->clearColor[3] = 255; // clear color is black from memset, set alpha to 255
|
||||
|
||||
return i;
|
||||
}
|
||||
|
|
@ -474,7 +475,7 @@ void gfx_shader_remove_frame_pass(int framePassIndex) {
|
|||
struct FramePass *framePass = &gFramePasses[framePassIndex];
|
||||
if (!framePass->active) return;
|
||||
|
||||
gfx_get_current_rendering_api()->delete_framebuffer(framePass->fbo, framePass->depthBuffer, framePass->passTexture);
|
||||
gfx_get_current_rendering_api()->delete_framebuffer(framePass);
|
||||
memset(framePass, 0, sizeof(struct FramePass));
|
||||
}
|
||||
|
||||
|
|
@ -488,7 +489,7 @@ void gfx_shader_set_frame_pass_viewport(int framePassIndex, int width, int heigh
|
|||
framePass->height = height;
|
||||
|
||||
// needs to be recreated
|
||||
gfx_get_current_rendering_api()->delete_framebuffer(framePass->fbo, framePass->depthBuffer, framePass->passTexture);
|
||||
gfx_get_current_rendering_api()->delete_framebuffer(framePass);
|
||||
framePass->fbo = 0;
|
||||
framePass->depthBuffer = 0;
|
||||
framePass->passTexture = 0;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue