Skip to content

Fix camera2D flipping textures #31

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions gs.h
Original file line number Diff line number Diff line change
Expand Up @@ -4493,6 +4493,7 @@ gs_enum_decl(gs_graphics_shader_language_type,

/* Uniform Type */
gs_enum_decl(gs_graphics_uniform_type,
GS_GRAPHICS_UNIFORM_BOOL,
GS_GRAPHICS_UNIFORM_FLOAT,
GS_GRAPHICS_UNIFORM_INT,
GS_GRAPHICS_UNIFORM_VEC2,
Expand Down
11 changes: 11 additions & 0 deletions impl/gs_graphics_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ gs_graphics_info_t* gs_graphics_info()

typedef enum gsgl_uniform_type
{
GSGL_UNIFORMTYPE_BOOL,
GSGL_UNIFORMTYPE_FLOAT,
GSGL_UNIFORMTYPE_INT,
GSGL_UNIFORMTYPE_VEC2,
Expand Down Expand Up @@ -420,6 +421,7 @@ gsgl_uniform_type gsgl_uniform_type_to_gl_uniform_type(gs_graphics_uniform_type
gsgl_uniform_type type = GSGL_UNIFORMTYPE_FLOAT;
switch (gstype) {
default:
case GS_GRAPHICS_UNIFORM_BOOL: type = GSGL_UNIFORMTYPE_BOOL; break;
case GS_GRAPHICS_UNIFORM_FLOAT: type = GSGL_UNIFORMTYPE_FLOAT; break;
case GS_GRAPHICS_UNIFORM_INT: type = GSGL_UNIFORMTYPE_INT; break;
case GS_GRAPHICS_UNIFORM_VEC2: type = GSGL_UNIFORMTYPE_VEC2; break;
Expand Down Expand Up @@ -499,6 +501,7 @@ size_t gsgl_uniform_data_size_in_bytes(gs_graphics_uniform_type type)
{
size_t sz = 0;
switch (type) {
case GS_GRAPHICS_UNIFORM_BOOL: sz = sizeof(bool); break;
case GS_GRAPHICS_UNIFORM_FLOAT: sz = sizeof(float); break;
case GS_GRAPHICS_UNIFORM_INT: sz = sizeof(int32_t); break;
case GS_GRAPHICS_UNIFORM_VEC2: sz = 2 * sizeof(float); break;
Expand Down Expand Up @@ -1571,6 +1574,14 @@ void gs_graphics_submit_command_buffer(gs_command_buffer_t* cb)
// Switch on uniform type to upload data
switch (u->type)
{

case GSGL_UNIFORMTYPE_BOOL: //GSGL size of bool is uint32, which is fine for a normally one byte bool in C
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will it be ok if someone will try to compile it using c++ compiller?

{
gs_assert(u->size == sizeof(bool));
gs_byte_buffer_read_bulkc(&cb->commands, bool, v, u->size);
glUniform1f(u->location, v);
} break;

case GSGL_UNIFORMTYPE_FLOAT:
{
gs_assert(u->size == sizeof(float));
Expand Down
4 changes: 3 additions & 1 deletion util/gs_gfxt.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ gs_gfxt_uniform_block_t gs_gfxt_uniform_block_create(gs_gfxt_uniform_block_desc_
// Add to data offset based on type
switch (ud->type) {
default:
case GS_GRAPHICS_UNIFORM_BOOL: offset += sizeof(bool); break;
case GS_GRAPHICS_UNIFORM_FLOAT: offset += sizeof(float); break;
case GS_GRAPHICS_UNIFORM_INT: offset += sizeof(int32_t); break;
case GS_GRAPHICS_UNIFORM_VEC2: offset += sizeof(gs_vec2); break;
Expand Down Expand Up @@ -367,7 +368,8 @@ void gs_gfxt_material_set_uniform(gs_gfxt_material_t* mat, const char* name, voi

switch (u->type)
{
case GS_GRAPHICS_UNIFORM_FLOAT: gs_byte_buffer_write(&mat->uniform_data, float, *(float*)data); break;
case GS_GRAPHICS_UNIFORM_BOOL: gs_byte_buffer_write(&mat->uniform_data, bool, *(bool*)data); break;
case GS_GRAPHICS_UNIFORM_FLOAT: gs_byte_buffer_write(&mat->uniform_data, float, *(float*)data); break;
case GS_GRAPHICS_UNIFORM_INT: gs_byte_buffer_write(&mat->uniform_data, int32_t, *(int32_t*)data); break;
case GS_GRAPHICS_UNIFORM_VEC2: gs_byte_buffer_write(&mat->uniform_data, gs_vec2, *(gs_vec2*)data); break;
case GS_GRAPHICS_UNIFORM_VEC3: gs_byte_buffer_write(&mat->uniform_data, gs_vec3, *(gs_vec3*)data); break;
Expand Down
30 changes: 25 additions & 5 deletions util/gs_idraw.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ typedef struct gs_immediate_cache_t
gs_dyn_array(gs_mat4) projection;
/* Mode stack*/
gs_dyn_array(gsi_matrix_type) modes;
/* Flip texture in fragment shader in case y axis is reversed by projection matrix*/
bool flip_tex;
/* UV */
gs_vec2 uv;
/* Color */
Expand All @@ -109,6 +111,8 @@ typedef struct gs_immediate_draw_t
gs_hash_table(gsi_pipeline_state_attr_t, gs_handle(gs_graphics_pipeline_t)) pipeline_table;
/* Uniform buffer */
gs_handle(gs_graphics_uniform_t) uniform;
/* Uniform flip texture flag */
gs_handle(gs_graphics_uniform_t) flip_tex;
/* Uniform sampler */
gs_handle(gs_graphics_uniform_t) sampler;
/* Dynamic array of vertex data to update */
Expand Down Expand Up @@ -234,11 +238,12 @@ GSI_GL_VERSION_STR
"layout(location = 1) in vec2 a_uv;\n"
"layout(location = 2) in vec4 a_color;\n"
"uniform mat4 u_mvp;\n"
"uniform bool flip_tex;\n"
"out vec2 uv;\n"
"out vec4 color;\n"
"void main() {\n"
" gl_Position = u_mvp * vec4(a_position, 1.0);\n"
" uv = a_uv;\n"
" uv = flip_tex ? vec2(a_uv.s, 1.0 - a_uv.t) : a_uv;\n"
" color = a_color;\n"
"}\n";

Expand Down Expand Up @@ -278,6 +283,7 @@ void gsi_reset(gs_immediate_draw_t* gsi)
gs_dyn_array_push(gsi->cache.projection, gs_mat4_identity());
gs_dyn_array_push(gsi->cache.modes, GSI_MATRIX_MODELVIEW);

gsi->cache.flip_tex = false;
gsi->cache.texture = gsi->tex_default;
gsi->cache.pipeline = gsi_pipeline_state_default();
gsi->cache.pipeline.prim_type = 0x00;
Expand Down Expand Up @@ -305,6 +311,14 @@ gs_immediate_draw_t gs_immediate_draw_new()
udesc.layout = &uldesc;
gsi.uniform = gs_graphics_uniform_create(&udesc);

// Flip texture flag
gs_graphics_uniform_layout_desc_t fldesc = gs_default_val();
fldesc.type = GS_GRAPHICS_UNIFORM_BOOL;
gs_graphics_uniform_desc_t fdesc = gs_default_val();
fdesc.name = "flip_tex";
fdesc.layout = &fldesc;
gsi.flip_tex = gs_graphics_uniform_create(&fdesc);

// Create sampler buffer
gs_graphics_uniform_layout_desc_t sldesc = gs_default_val();
sldesc.type = GS_GRAPHICS_UNIFORM_SAMPLER2D;
Expand Down Expand Up @@ -530,9 +544,10 @@ void gsi_flush(gs_immediate_draw_t* gsi)
gs_graphics_bind_vertex_buffer_desc_t vbuffer = gs_default_val();
vbuffer.buffer = gsi->vbo;

gs_graphics_bind_uniform_desc_t ubinds[2] = gs_default_val();
gs_graphics_bind_uniform_desc_t ubinds[3] = gs_default_val();
ubinds[0].uniform = gsi->uniform; ubinds[0].data = &mvp;
ubinds[1].uniform = gsi->sampler; ubinds[1].data = &gsi->cache.texture; ubinds[1].binding = 0;
ubinds[1].uniform = gsi->flip_tex; ubinds[1].data = &gsi->cache.flip_tex;
ubinds[2].uniform = gsi->sampler; ubinds[2].data = &gsi->cache.texture; ubinds[2].binding = 0;

// Bindings for all buffers: vertex, uniform, sampler
gs_graphics_bind_desc_t binds = gs_default_val();
Expand Down Expand Up @@ -642,6 +657,7 @@ void gsi_defaults(gs_immediate_draw_t* gsi)
gsi_flush(gsi);

// Set defaults for cache
gsi->cache.flip_tex = false;
gsi->cache.texture = gsi->tex_default;
gsi->cache.pipeline = gsi_pipeline_state_default();
gsi->cache.pipeline.prim_type = 0x00;
Expand Down Expand Up @@ -821,26 +837,29 @@ void gsi_camera(gs_immediate_draw_t* gsi, gs_camera_t* cam)
// Just grab main window for now. Will need to grab top of viewport stack in future
gs_vec2 ws = gs_platform_window_sizev(gs_platform_main_window());
gsi_load_matrix(gsi, gs_camera_get_view_projection(cam, (s32)ws.x, (s32)ws.y));
gsi->cache.flip_tex = false;
}

void gsi_camera2D(gs_immediate_draw_t* gsi)
{
// Flush previous
gsi_flush(gsi);
// Puts the camera in center of screen, 0,0 is bottom left corner
// Puts the camera from center of screen where (-1,-1) is bottom left to screen coordinates (pixels with origin at top left, means y axis is flipped)
gs_vec2 ws = gs_platform_window_sizev(gs_platform_main_window());
gs_vec2 hws = gs_vec2_scale(ws, 0.5f);
gs_camera_t c = gs_camera_default();
c.transform.position = gs_vec3_add(c.transform.position, gs_v3(hws.x, hws.y, -1.f));
f32 l = -ws.x / 2.f;
f32 r = ws.x / 2.f;
f32 b = ws.y / 2.f;
f32 b = ws.y / 2.f; // The sign of this line with the below line's sign flip y axis
f32 tp = -ws.y / 2.f;
gs_mat4 ortho = gs_mat4_transpose(gs_mat4_ortho(
l, r, b, tp, 0.1f, 100.f
));
ortho = gs_mat4_mul(ortho, gs_camera_get_view(&c));
gsi_load_matrix(gsi, ortho);
// Need to flip texture as y axis is now inverted with the above matrix
gsi->cache.flip_tex = true;
}

void gsi_camera3D(gs_immediate_draw_t* gsi)
Expand All @@ -849,6 +868,7 @@ void gsi_camera3D(gs_immediate_draw_t* gsi)
gsi_flush(gsi);
gs_camera_t c = gs_camera_perspective();
gsi_camera(gsi, &c);
gsi->cache.flip_tex = false;
}

// Shape Drawing Utils
Expand Down