|
|
|
@ -18,8 +18,13 @@ |
|
|
|
// NOTE: forward declarations
|
|
|
|
// NOTE: forward declarations
|
|
|
|
|
|
|
|
|
|
|
|
const std::string dumpTextFile(const char* filepath); |
|
|
|
const std::string dumpTextFile(const char* filepath); |
|
|
|
void |
|
|
|
bool |
|
|
|
parseShaderUniforms(memory_arena* arena, shader_program* s, GLContext* gl_ctx); |
|
|
|
parseShaderUniforms(memory_arena* arena, shader_program* s, GLContext* gl_ctx); |
|
|
|
|
|
|
|
bool |
|
|
|
|
|
|
|
parseUniformBlocks(memory_arena* arena, shader_program* s, GLContext* gl_ctx); |
|
|
|
|
|
|
|
bool |
|
|
|
|
|
|
|
parseAttributes(memory_arena* arena, shader_program* s, GLContext* gl_ctx); |
|
|
|
|
|
|
|
void initCTXSizes(GLContext* gl_ctx); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// NOTE: interface
|
|
|
|
// NOTE: interface
|
|
|
|
@ -78,24 +83,21 @@ addShaderProgram(memory_arena* arena, |
|
|
|
initCTXSizes(gl_ctx); |
|
|
|
initCTXSizes(gl_ctx); |
|
|
|
dumpShader(s->prog_id); |
|
|
|
dumpShader(s->prog_id); |
|
|
|
s->model_xform_id = glGetUniformLocation(s->prog_id, "model_xform"); |
|
|
|
s->model_xform_id = glGetUniformLocation(s->prog_id, "model_xform"); |
|
|
|
|
|
|
|
|
|
|
|
// FIXME: testing
|
|
|
|
|
|
|
|
// NOTE: set block binding for shader xforms uniform block
|
|
|
|
|
|
|
|
GLuint block_idx = glGetUniformBlockIndex(s->prog_id, "matrices"); |
|
|
|
|
|
|
|
glUniformBlockBinding(s->prog_id, |
|
|
|
|
|
|
|
block_idx, |
|
|
|
|
|
|
|
gl_ctx->xform_ubo.binding_idx); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//dumpShader(s->prog_id);
|
|
|
|
|
|
|
|
parseShaderUniforms(arena, s, gl_ctx); |
|
|
|
|
|
|
|
///
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
glDetachShader(s->prog_id, vs_id); |
|
|
|
glDetachShader(s->prog_id, vs_id); |
|
|
|
glDetachShader(s->prog_id, fs_id); |
|
|
|
glDetachShader(s->prog_id, fs_id); |
|
|
|
glDeleteShader(vs_id); |
|
|
|
glDeleteShader(vs_id); |
|
|
|
glDeleteShader(fs_id); |
|
|
|
glDeleteShader(fs_id); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (parseShaderUniforms(arena, s, gl_ctx) |
|
|
|
|
|
|
|
&& parseUniformBlocks(arena, s, gl_ctx) |
|
|
|
|
|
|
|
&& parseAttributes(arena, s, gl_ctx)) |
|
|
|
|
|
|
|
{ |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
printf("%s(), Error parsing shader component\n", __FUNCTION__); |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
printf("%s(), Error linking shader\n", __FUNCTION__); |
|
|
|
printf("%s(), Error linking shader\n", __FUNCTION__); |
|
|
|
@ -144,37 +146,35 @@ getGLTypeSize(GLenum e) |
|
|
|
case 0x8b51: return 4 * sizeof(GLfloat); // GL_FLOAT_VEC3
|
|
|
|
case 0x8b51: return 4 * sizeof(GLfloat); // GL_FLOAT_VEC3
|
|
|
|
case 0x8b52: return 4 * sizeof(GLfloat); // GL_FLOAT_VEC4
|
|
|
|
case 0x8b52: return 4 * sizeof(GLfloat); // GL_FLOAT_VEC4
|
|
|
|
case 0x8b5c: return 16 * sizeof(GLfloat); // GL_FLOAT_MAT4
|
|
|
|
case 0x8b5c: return 16 * sizeof(GLfloat); // GL_FLOAT_MAT4
|
|
|
|
default: return 0; |
|
|
|
default: |
|
|
|
|
|
|
|
printf("%s(), unknown GLenum\n", __FUNCTION__); |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
gl_uniform |
|
|
|
const gl_uniform |
|
|
|
parseUniform(memory_arena* arena, shader_program* s, u32 uniform_idx) |
|
|
|
parseUniform(memory_arena* arena, shader_program* s, u32 uniform_idx) |
|
|
|
{ |
|
|
|
{ |
|
|
|
assert(uniform_idx < s->num_uniforms); |
|
|
|
gl_uniform unif = {0}; |
|
|
|
gl_uniform& unif = s->uniforms[uniform_idx]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GLchar unif_name[256] = {0}; |
|
|
|
GLchar unif_name[256] = {0}; |
|
|
|
GLsizei length; |
|
|
|
|
|
|
|
GLint size; |
|
|
|
|
|
|
|
GLenum type; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
glGetActiveUniform(s->prog_id, uniform_idx, sizeof(unif_name), |
|
|
|
|
|
|
|
&length, &size, &type, unif_name); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unif.data_type = type; |
|
|
|
glGetActiveUniform(s->prog_id, |
|
|
|
unif.name = (char*) arenaAllocateBlock( |
|
|
|
uniform_idx, |
|
|
|
arena, (length + 1) * sizeof(char)); |
|
|
|
sizeof(unif_name), |
|
|
|
std::strncpy(unif.name, unif_name, length); |
|
|
|
&unif.name_len, |
|
|
|
|
|
|
|
&unif.num_elements, |
|
|
|
|
|
|
|
&unif.data_type, |
|
|
|
|
|
|
|
unif_name); |
|
|
|
|
|
|
|
glGetActiveUniformsiv(s->prog_id, 1, &uniform_idx, |
|
|
|
|
|
|
|
GL_UNIFORM_BLOCK_INDEX, &unif.block_idx); |
|
|
|
|
|
|
|
|
|
|
|
// FIXME: testing idx == unif location
|
|
|
|
|
|
|
|
unif.idx = uniform_idx; |
|
|
|
unif.idx = uniform_idx; |
|
|
|
#if 1 |
|
|
|
|
|
|
|
GLuint location = glGetUniformLocation(s->prog_id, unif.name); |
|
|
|
|
|
|
|
printf("uniform idx: %d, loc: %d, block idx: %d \n", |
|
|
|
|
|
|
|
unif.idx, location, unif.block_idx); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
unif.data_size = getGLTypeSize(unif.data_type); |
|
|
|
unif.data_size = getGLTypeSize(unif.data_type); |
|
|
|
|
|
|
|
unif.name_len += 1; // NOTE: gl param dosen't account for null terminator
|
|
|
|
|
|
|
|
unif.name = |
|
|
|
|
|
|
|
(char*) arenaAllocateBlock(arena, (unif.name_len) * sizeof(char)); |
|
|
|
|
|
|
|
std::strncpy(unif.name, unif_name, unif.name_len); |
|
|
|
|
|
|
|
unif.location = glGetUniformLocation(s->prog_id, unif.name); |
|
|
|
|
|
|
|
|
|
|
|
if (unif.data_size == 0) |
|
|
|
if (unif.data_size == 0) |
|
|
|
printf("%s(), error getting data_size\n", __FUNCTION__); |
|
|
|
printf("%s(), error getting data_size\n", __FUNCTION__); |
|
|
|
@ -182,21 +182,94 @@ parseUniform(memory_arena* arena, shader_program* s, u32 uniform_idx) |
|
|
|
return unif; |
|
|
|
return unif; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
bool |
|
|
|
parseShaderUniforms(memory_arena* arena, shader_program* s, GLContext* gl_ctx) |
|
|
|
parseShaderUniforms(memory_arena* arena, shader_program* s, GLContext* gl_ctx) |
|
|
|
{ |
|
|
|
{ |
|
|
|
GLint unif_count; |
|
|
|
// NOTE: only add uniforms in the default block to the base uniform array
|
|
|
|
glGetProgramiv(s->prog_id, GL_ACTIVE_UNIFORMS, &unif_count); |
|
|
|
GLint num_uniforms_total = 0; |
|
|
|
s->num_uniforms = unif_count; |
|
|
|
glGetProgramiv(s->prog_id, GL_ACTIVE_UNIFORMS, &num_uniforms_total); |
|
|
|
|
|
|
|
GLint indices[num_uniforms_total]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (u32 i = 0; i < (u32) num_uniforms_total; i++) { |
|
|
|
|
|
|
|
GLint block_idx = 0; |
|
|
|
|
|
|
|
glGetActiveUniformsiv(s->prog_id, 1, &i, |
|
|
|
|
|
|
|
GL_UNIFORM_BLOCK_INDEX, &block_idx); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (block_idx == -1) { |
|
|
|
|
|
|
|
indices[s->num_uniforms] = i; |
|
|
|
|
|
|
|
s->num_uniforms++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
s->uniforms = (gl_uniform*) arenaAllocateBlock( |
|
|
|
s->uniforms = (gl_uniform*) arenaAllocateBlock( |
|
|
|
arena, s->num_uniforms * sizeof(gl_uniform)); |
|
|
|
arena, s->num_uniforms * sizeof(gl_uniform)); |
|
|
|
|
|
|
|
|
|
|
|
for (u32 i = 0; i < s->num_uniforms; i++) { |
|
|
|
for (u32 i = 0; i < s->num_uniforms; i++) { |
|
|
|
glGetActiveUniformsiv(s->prog_id, 1, &i, |
|
|
|
const gl_uniform unif = parseUniform(arena, s, indices[i]); |
|
|
|
GL_UNIFORM_BLOCK_INDEX, &s->uniforms[i].block_idx); |
|
|
|
std::memcpy(&s->uniforms[i], &unif, sizeof(unif)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
parseUniform(arena, s, i); |
|
|
|
i32 |
|
|
|
|
|
|
|
ctxGetUniformBlockBinding(GLContext* gl_ctx, const char* name) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
for (u32 i = 0; i < gl_ctx->num_ubos; i++) { |
|
|
|
|
|
|
|
gl_buffer& ubo = gl_ctx->uniform_buffers[i]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (std::strstr(ubo.name, name)) |
|
|
|
|
|
|
|
return ubo.binding_idx; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf("%s(), no buffer found with name: %s\n", __FUNCTION__, name); |
|
|
|
|
|
|
|
return -1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool |
|
|
|
|
|
|
|
parseUniformBlocks(memory_arena* arena, shader_program* s, GLContext* gl_ctx) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
glGetProgramiv(s->prog_id, GL_ACTIVE_UNIFORM_BLOCKS, |
|
|
|
|
|
|
|
(GLint*) &s->num_blocks); |
|
|
|
|
|
|
|
s->uniform_blocks = (GLUniformBlock*) arenaAllocateBlock(arena, |
|
|
|
|
|
|
|
s->num_blocks * sizeof(GLUniformBlock)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (u32 i = 0; i < s->num_blocks; i++) { |
|
|
|
|
|
|
|
GLUniformBlock& ub = s->uniform_blocks[i]; |
|
|
|
|
|
|
|
ub.block_id = i; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GLchar block_name[256] = {0}; |
|
|
|
|
|
|
|
glGetActiveUniformBlockName( |
|
|
|
|
|
|
|
s->prog_id, i, 256, &ub.name_len, block_name); |
|
|
|
|
|
|
|
ub.name_len++; // NOTE: space for null term
|
|
|
|
|
|
|
|
ub.name = (char*) arenaAllocateBlock(arena, ub.name_len * sizeof(char)); |
|
|
|
|
|
|
|
std::strncpy(ub.name, block_name, ub.name_len); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
glGetActiveUniformBlockiv(s->prog_id, i, |
|
|
|
|
|
|
|
GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, (GLint*) &ub.num_uniforms); |
|
|
|
|
|
|
|
ub.uniforms = (gl_uniform*) |
|
|
|
|
|
|
|
arenaAllocateBlock(arena, ub.num_uniforms * sizeof(gl_uniform)); |
|
|
|
|
|
|
|
GLint indices[ub.num_uniforms] = {0}; |
|
|
|
|
|
|
|
glGetActiveUniformBlockiv(s->prog_id, i, |
|
|
|
|
|
|
|
GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, (GLint*) &indices); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (u32 j = 0; j < ub.num_uniforms; j++) { |
|
|
|
|
|
|
|
const gl_uniform unif = parseUniform(arena, s, indices[j]); |
|
|
|
|
|
|
|
std::memcpy(&ub.uniforms[j], &unif, sizeof(unif)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ub.binding_idx = ctxGetUniformBlockBinding(gl_ctx, ub.name); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
|
|
|
if (ub.binding_idx < 0) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
glUniformBlockBinding(s->prog_id, i, ub.binding_idx); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool |
|
|
|
bool |
|
|
|
|