Browse Source

break up addShader() into logical helper functions

main
cinnaboot 5 years ago
parent
commit
001190fc73
  1. 149
      src/shader.cpp
  2. 2
      src/shader.h

149
src/shader.cpp

@ -19,18 +19,40 @@
// NOTE: forward declarations // NOTE: forward declarations
const std::string dumpTextFile(const char* filepath); const std::string dumpTextFile(const char* filepath);
bool bool parseShader(memory_arena* arena, GLContext* gl_ctx, shader_program* s);
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); void initCTXSizes(GLContext* gl_ctx);
bool compileAndLinkShader(shader_program* shader,
const char* vert_src,
const char* frag_src,
GLuint& vs_id,
GLuint& fs_id);
// NOTE: interface // NOTE: interface
// TODO: clean up this function shader_program*
getFreeShader(GLContext* gl_ctx)
{
if (gl_ctx->num_shaders >= gl_ctx->max_shaders) {
printf("%s(), GLContext->shaders full\n", __FUNCTION__);
return nullptr;
}
shader_program* s = &gl_ctx->shaders[gl_ctx->num_shaders++];
return s;
}
shader_program*
getShaderByHash(GLContext* gl_ctx, u64 hash)
{
for (u32 i; i < gl_ctx->num_shaders; i++) {
if (gl_ctx->shaders[i].hash == hash)
return &gl_ctx->shaders[i];
}
return nullptr;
}
bool bool
addShaderProgram(memory_arena* arena, addShaderProgram(memory_arena* arena,
GLContext* gl_ctx, GLContext* gl_ctx,
@ -38,72 +60,45 @@ addShaderProgram(memory_arena* arena,
const char* fs, const char* fs,
const char* name) const char* name)
{ {
if (gl_ctx->num_shaders >= gl_ctx->max_shaders) { // TODO: replace std::string w/ utilAllocCStr() ?
printf("%s(), GLContext->shaders full\n", __FUNCTION__); std::string hash_str = std::string(vs) + std::string(fs);
const u32 max_len = 256;
u64 hash = utilFNV64a_str(hash_str.substr(0, max_len).c_str());
if (getShaderByHash(gl_ctx, hash)) {
printf("%s(), shader is already loaded\n", __FUNCTION__);
return false; return false;
} }
shader_program* s = &gl_ctx->shaders[gl_ctx->num_shaders]; shader_program* s = getFreeShader(gl_ctx);
gl_ctx->num_shaders++;
s->name = arenaCopyCStr(arena, name);
const u32 max_len = 256; if (s) {
std::string hash_str = vs; s->name = arenaCopyCStr(arena, name);
hash_str += fs; s->hash = hash;
s->hash = utilFNV64a_str(hash_str.substr(0, max_len).c_str());
// FIXME: should probably check the hash here against other shaders loaded
// TODO: replace std::string w/ utilAllocCStr() ?
std::string vert = dumpTextFile(vs); std::string vert = dumpTextFile(vs);
std::string frag = dumpTextFile(fs); std::string frag = dumpTextFile(fs);
GLuint vs_id, fs_id;
if (vert.size() > 0 && frag.size() > 0) { if (compileAndLinkShader(s, vert.c_str(), frag.c_str(), vs_id, fs_id)) {
const char* vert_c = vert.c_str(); // NOTE: we call this here because we can only make the GL_MAX*
const char* frag_c = frag.c_str(); // queries after at least one shader has been linked
GLuint vs_id = glCreateShader(GL_VERTEX_SHADER);
GLuint fs_id = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vs_id, 1, &vert_c, NULL);
glShaderSource(fs_id, 1, &frag_c, NULL);
// TODO: both of these can fail
glCompileShader(vs_id);
glCompileShader(fs_id);
s->prog_id = glCreateProgram();
glAttachShader(s->prog_id, vs_id);
glAttachShader(s->prog_id, fs_id);
glLinkProgram(s->prog_id);
GLint is_linked = 0;
glGetProgramiv(s->prog_id, GL_LINK_STATUS, &is_linked);
if (is_linked) {
// NOTE: need to set context maximums after at least one shader has
// been linked
initCTXSizes(gl_ctx); initCTXSizes(gl_ctx);
#if 0
dumpShader(s->prog_id);
#endif
s->model_xform_id = glGetUniformLocation(s->prog_id, "model_xform"); s->model_xform_id = glGetUniformLocation(s->prog_id, "model_xform");
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) return parseShader(arena, gl_ctx, s);
&& parseUniformBlocks(arena, s, gl_ctx)
&& parseAttributes(arena, s, gl_ctx))
{
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__);
return false; return false;
} }
printf("%s(), error loading shader\n", __FUNCTION__);
return false; return false;
} }
@ -231,8 +226,44 @@ loadGLMesh(shader_program* s,
return gm; return gm;
} }
// NOTE: internal // NOTE: internal
bool
compileAndLinkShader(shader_program* shader,
const char* vert_src,
const char* frag_src,
GLuint& vs_id,
GLuint& fs_id)
{
if (strlen(vert_src) > 0 && strlen(frag_src) > 0) {
vs_id = glCreateShader(GL_VERTEX_SHADER);
fs_id = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vs_id, 1, &vert_src, NULL);
glShaderSource(fs_id, 1, &frag_src, NULL);
// TODO: add a glError to string function in GLDebug.h
glCompileShader(vs_id);
assert(glGetError() == GL_NO_ERROR);
glCompileShader(fs_id);
assert(glGetError() == GL_NO_ERROR);
shader->prog_id = glCreateProgram();
glAttachShader(shader->prog_id, vs_id);
glAttachShader(shader->prog_id, fs_id);
glLinkProgram(shader->prog_id);
GLint is_linked = 0;
glGetProgramiv(shader->prog_id, GL_LINK_STATUS, &is_linked);
return (is_linked == GL_TRUE);
}
// TODO: make another logging macro for printf style logging
printf("%s(), empty shader source\n", __FUNCTION__);
return false;
}
const std::string const std::string
dumpTextFile(const char* filepath) dumpTextFile(const char* filepath)
{ {
@ -412,3 +443,17 @@ parseAttributes(memory_arena* arena, shader_program* s, GLContext* gl_ctx)
return true; return true;
} }
bool
parseShader(memory_arena* arena, GLContext* gl_ctx, shader_program* s)
{
if (parseShaderUniforms(arena, s, gl_ctx)
&& parseUniformBlocks(arena, s, gl_ctx)
&& parseAttributes(arena, s, gl_ctx))
{
return true;
}
printf("%s(), Error parsing shader\n", __FUNCTION__);
return false;
}

2
src/shader.h

@ -139,6 +139,8 @@ bool addShaderProgram(memory_arena* arena,
const char* name); const char* name);
shader_program* getShaderByName(const char* name, GLContext* gl_ctx); shader_program* getShaderByName(const char* name, GLContext* gl_ctx);
shader_program* getShaderByID(GLContext* gl_ctx, GLuint prog_id); shader_program* getShaderByID(GLContext* gl_ctx, GLuint prog_id);
shader_program* getShaderByHash(GLContext* gl_ctx, u64 hash);
shader_program* getFreeShader(GLContext* gl_ctx);
void renderVAO(GLmesh* glmesh); void renderVAO(GLmesh* glmesh);
GLmesh loadGLMesh(shader_program* s, GLmesh loadGLMesh(shader_program* s,
const mesh& m, const mesh& m,

Loading…
Cancel
Save