mirror of https://github.com/sm64pc/sm64pc.git
Implemented noise effects in OpenGL. (#6)
This commit is contained in:
parent
8d05d2b7e2
commit
fbbb3cba5c
|
@ -23,3 +23,4 @@ enum {
|
||||||
#define SHADER_OPT_ALPHA (1 << 24)
|
#define SHADER_OPT_ALPHA (1 << 24)
|
||||||
#define SHADER_OPT_FOG (1 << 25)
|
#define SHADER_OPT_FOG (1 << 25)
|
||||||
#define SHADER_OPT_TEXTURE_EDGE (1 << 26)
|
#define SHADER_OPT_TEXTURE_EDGE (1 << 26)
|
||||||
|
#define SHADER_OPT_NOISE (1 << 27)
|
||||||
|
|
|
@ -46,12 +46,18 @@ struct ShaderProgram {
|
||||||
GLint attrib_locations[7];
|
GLint attrib_locations[7];
|
||||||
uint8_t attrib_sizes[7];
|
uint8_t attrib_sizes[7];
|
||||||
uint8_t num_attribs;
|
uint8_t num_attribs;
|
||||||
|
bool used_noise;
|
||||||
|
GLint frame_count_location;
|
||||||
|
GLint window_height_location;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ShaderProgram shader_program_pool[64];
|
static struct ShaderProgram shader_program_pool[64];
|
||||||
static uint8_t shader_program_pool_size;
|
static uint8_t shader_program_pool_size;
|
||||||
static GLuint opengl_vbo;
|
static GLuint opengl_vbo;
|
||||||
|
|
||||||
|
static uint32_t frame_count;
|
||||||
|
static uint32_t current_height;
|
||||||
|
|
||||||
static bool gfx_opengl_z_is_from_0_to_1(void) {
|
static bool gfx_opengl_z_is_from_0_to_1(void) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -62,11 +68,18 @@ static void gfx_opengl_vertex_array_set_attribs(struct ShaderProgram *prg) {
|
||||||
|
|
||||||
for (int i = 0; i < prg->num_attribs; i++) {
|
for (int i = 0; i < prg->num_attribs; i++) {
|
||||||
glEnableVertexAttribArray(prg->attrib_locations[i]);
|
glEnableVertexAttribArray(prg->attrib_locations[i]);
|
||||||
glVertexAttribPointer(prg->attrib_locations[i], prg->attrib_sizes[i], GL_FLOAT, GL_FALSE, num_floats * sizeof(float), (void *)(pos * sizeof(float)));
|
glVertexAttribPointer(prg->attrib_locations[i], prg->attrib_sizes[i], GL_FLOAT, GL_FALSE, num_floats * sizeof(float), (void *) (pos * sizeof(float)));
|
||||||
pos += prg->attrib_sizes[i];
|
pos += prg->attrib_sizes[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gfx_opengl_set_uniforms(struct ShaderProgram *prg) {
|
||||||
|
if (prg->used_noise) {
|
||||||
|
glUniform1i(prg->frame_count_location, frame_count);
|
||||||
|
glUniform1i(prg->window_height_location, current_height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void gfx_opengl_unload_shader(struct ShaderProgram *old_prg) {
|
static void gfx_opengl_unload_shader(struct ShaderProgram *old_prg) {
|
||||||
if (old_prg != NULL) {
|
if (old_prg != NULL) {
|
||||||
for (int i = 0; i < old_prg->num_attribs; i++) {
|
for (int i = 0; i < old_prg->num_attribs; i++) {
|
||||||
|
@ -78,6 +91,7 @@ static void gfx_opengl_unload_shader(struct ShaderProgram *old_prg) {
|
||||||
static void gfx_opengl_load_shader(struct ShaderProgram *new_prg) {
|
static void gfx_opengl_load_shader(struct ShaderProgram *new_prg) {
|
||||||
glUseProgram(new_prg->opengl_program_id);
|
glUseProgram(new_prg->opengl_program_id);
|
||||||
gfx_opengl_vertex_array_set_attribs(new_prg);
|
gfx_opengl_vertex_array_set_attribs(new_prg);
|
||||||
|
gfx_opengl_set_uniforms(new_prg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void append_str(char *buf, size_t *len, const char *str) {
|
static void append_str(char *buf, size_t *len, const char *str) {
|
||||||
|
@ -168,7 +182,9 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(uint32_t shad
|
||||||
bool opt_alpha = (shader_id & SHADER_OPT_ALPHA) != 0;
|
bool opt_alpha = (shader_id & SHADER_OPT_ALPHA) != 0;
|
||||||
bool opt_fog = (shader_id & SHADER_OPT_FOG) != 0;
|
bool opt_fog = (shader_id & SHADER_OPT_FOG) != 0;
|
||||||
bool opt_texture_edge = (shader_id & SHADER_OPT_TEXTURE_EDGE) != 0;
|
bool opt_texture_edge = (shader_id & SHADER_OPT_TEXTURE_EDGE) != 0;
|
||||||
bool used_textures[2] = {0, 0};
|
bool opt_noise = (shader_id & SHADER_OPT_NOISE) != 0;
|
||||||
|
|
||||||
|
bool used_textures[2] = { 0, 0 };
|
||||||
int num_inputs = 0;
|
int num_inputs = 0;
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
|
@ -185,9 +201,9 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(uint32_t shad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool do_single[2] = {c[0][2] == 0, c[1][2] == 0};
|
bool do_single[2] = { c[0][2] == 0, c[1][2] == 0 };
|
||||||
bool do_multiply[2] = {c[0][1] == 0 && c[0][3] == 0, c[1][1] == 0 && c[1][3] == 0};
|
bool do_multiply[2] = { c[0][1] == 0 && c[0][3] == 0, c[1][1] == 0 && c[1][3] == 0 };
|
||||||
bool do_mix[2] = {c[0][1] == c[0][3], c[1][1] == c[1][3]};
|
bool do_mix[2] = { c[0][1] == c[0][3], c[1][1] == c[1][3] };
|
||||||
bool color_alpha_same = (shader_id & 0xfff) == ((shader_id >> 12) & 0xfff);
|
bool color_alpha_same = (shader_id & 0xfff) == ((shader_id >> 12) & 0xfff);
|
||||||
|
|
||||||
char vs_buf[1024];
|
char vs_buf[1024];
|
||||||
|
@ -254,6 +270,17 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(uint32_t shad
|
||||||
if (used_textures[1]) {
|
if (used_textures[1]) {
|
||||||
append_line(fs_buf, &fs_len, "uniform sampler2D uTex1;");
|
append_line(fs_buf, &fs_len, "uniform sampler2D uTex1;");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opt_alpha && opt_noise) {
|
||||||
|
append_line(fs_buf, &fs_len, "uniform int frame_count;");
|
||||||
|
append_line(fs_buf, &fs_len, "uniform int window_height;");
|
||||||
|
|
||||||
|
append_line(fs_buf, &fs_len, "float random(in vec3 value) {");
|
||||||
|
append_line(fs_buf, &fs_len, " float random = dot(sin(value), vec3(12.9898, 78.233, 37.719));");
|
||||||
|
append_line(fs_buf, &fs_len, " return fract(sin(random) * 143758.5453);");
|
||||||
|
append_line(fs_buf, &fs_len, "}");
|
||||||
|
}
|
||||||
|
|
||||||
append_line(fs_buf, &fs_len, "void main() {");
|
append_line(fs_buf, &fs_len, "void main() {");
|
||||||
|
|
||||||
if (used_textures[0]) {
|
if (used_textures[0]) {
|
||||||
|
@ -287,6 +314,10 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(uint32_t shad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opt_alpha && opt_noise) {
|
||||||
|
append_line(fs_buf, &fs_len, "texel.a *= floor(random(vec3(floor(gl_FragCoord.xy * (240.0 / float(window_height))), float(frame_count))) + 0.5);");
|
||||||
|
}
|
||||||
|
|
||||||
if (opt_alpha) {
|
if (opt_alpha) {
|
||||||
append_line(fs_buf, &fs_len, "gl_FragColor = texel;");
|
append_line(fs_buf, &fs_len, "gl_FragColor = texel;");
|
||||||
} else {
|
} else {
|
||||||
|
@ -303,8 +334,8 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(uint32_t shad
|
||||||
puts(fs_buf);
|
puts(fs_buf);
|
||||||
puts("End");*/
|
puts("End");*/
|
||||||
|
|
||||||
const GLchar *sources[2] = {vs_buf, fs_buf};
|
const GLchar *sources[2] = { vs_buf, fs_buf };
|
||||||
const GLint lengths[2] = {vs_len, fs_len};
|
const GLint lengths[2] = { vs_len, fs_len };
|
||||||
GLint success;
|
GLint success;
|
||||||
|
|
||||||
GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
@ -378,12 +409,20 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(uint32_t shad
|
||||||
gfx_opengl_load_shader(prg);
|
gfx_opengl_load_shader(prg);
|
||||||
|
|
||||||
if (used_textures[0]) {
|
if (used_textures[0]) {
|
||||||
GLint sampler_attrib = glGetUniformLocation(shader_program, "uTex0");
|
GLint sampler_location = glGetUniformLocation(shader_program, "uTex0");
|
||||||
glUniform1i(sampler_attrib, 0);
|
glUniform1i(sampler_location, 0);
|
||||||
}
|
}
|
||||||
if (used_textures[1]) {
|
if (used_textures[1]) {
|
||||||
GLint sampler_attrib = glGetUniformLocation(shader_program, "uTex1");
|
GLint sampler_location = glGetUniformLocation(shader_program, "uTex1");
|
||||||
glUniform1i(sampler_attrib, 1);
|
glUniform1i(sampler_location, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt_alpha && opt_noise) {
|
||||||
|
prg->frame_count_location = glGetUniformLocation(shader_program, "frame_count");
|
||||||
|
prg->window_height_location = glGetUniformLocation(shader_program, "window_height");
|
||||||
|
prg->used_noise = true;
|
||||||
|
} else {
|
||||||
|
prg->used_noise = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return prg;
|
return prg;
|
||||||
|
@ -459,6 +498,7 @@ static void gfx_opengl_set_zmode_decal(bool zmode_decal) {
|
||||||
|
|
||||||
static void gfx_opengl_set_viewport(int x, int y, int width, int height) {
|
static void gfx_opengl_set_viewport(int x, int y, int width, int height) {
|
||||||
glViewport(x, y, width, height);
|
glViewport(x, y, width, height);
|
||||||
|
current_height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gfx_opengl_set_scissor(int x, int y, int width, int height) {
|
static void gfx_opengl_set_scissor(int x, int y, int width, int height) {
|
||||||
|
@ -517,6 +557,8 @@ static void gfx_opengl_init(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gfx_opengl_start_frame(void) {
|
static void gfx_opengl_start_frame(void) {
|
||||||
|
frame_count++;
|
||||||
|
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
glDepthMask(GL_TRUE); // Must be set to clear Z-buffer
|
glDepthMask(GL_TRUE); // Must be set to clear Z-buffer
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
|
@ -934,6 +934,7 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx) {
|
||||||
bool use_alpha = (rdp.other_mode_l & (G_BL_A_MEM << 18)) == 0;
|
bool use_alpha = (rdp.other_mode_l & (G_BL_A_MEM << 18)) == 0;
|
||||||
bool use_fog = (rdp.other_mode_l >> 30) == G_BL_CLR_FOG;
|
bool use_fog = (rdp.other_mode_l >> 30) == G_BL_CLR_FOG;
|
||||||
bool texture_edge = (rdp.other_mode_l & CVG_X_ALPHA) == CVG_X_ALPHA;
|
bool texture_edge = (rdp.other_mode_l & CVG_X_ALPHA) == CVG_X_ALPHA;
|
||||||
|
bool use_noise = (rdp.other_mode_l & G_AC_DITHER) == G_AC_DITHER;
|
||||||
|
|
||||||
if (texture_edge) {
|
if (texture_edge) {
|
||||||
use_alpha = true;
|
use_alpha = true;
|
||||||
|
@ -942,6 +943,7 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx) {
|
||||||
if (use_alpha) cc_id |= SHADER_OPT_ALPHA;
|
if (use_alpha) cc_id |= SHADER_OPT_ALPHA;
|
||||||
if (use_fog) cc_id |= SHADER_OPT_FOG;
|
if (use_fog) cc_id |= SHADER_OPT_FOG;
|
||||||
if (texture_edge) cc_id |= SHADER_OPT_TEXTURE_EDGE;
|
if (texture_edge) cc_id |= SHADER_OPT_TEXTURE_EDGE;
|
||||||
|
if (use_noise) cc_id |= SHADER_OPT_NOISE;
|
||||||
|
|
||||||
if (!use_alpha) {
|
if (!use_alpha) {
|
||||||
cc_id &= ~0xfff000;
|
cc_id &= ~0xfff000;
|
||||||
|
|
Loading…
Reference in New Issue