|
|
|
|
@ -27,33 +27,12 @@ bool compileAndLinkShader(shader_program* shader,
|
|
|
|
|
GLuint& vs_id, |
|
|
|
|
GLuint& fs_id); |
|
|
|
|
u32 getGLTypeSize(GLenum e); |
|
|
|
|
GLTexture* getFreeGLTexture(GLContext* gl_ctx); |
|
|
|
|
bool loadGLTexture(util_image* image, GLuint& tex_id); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// NOTE: interface
|
|
|
|
|
|
|
|
|
|
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 |
|
|
|
|
addShaderProgram(MemoryArena* arena, |
|
|
|
|
GLContext* gl_ctx, |
|
|
|
|
@ -103,6 +82,29 @@ addShaderProgram(MemoryArena* arena,
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
shader_program* |
|
|
|
|
getShaderByName(const char* name, GLContext* gl_ctx) |
|
|
|
|
{ |
|
|
|
|
@ -130,6 +132,33 @@ getShaderByID(GLContext* gl_ctx, GLuint prog_id)
|
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
GLTexture* |
|
|
|
|
getGLTexture(GLContext* gl_ctx, util_image* diffuse_img) |
|
|
|
|
{ |
|
|
|
|
u64 fp_hash = utilFNV64a_str(diffuse_img->file_path); |
|
|
|
|
|
|
|
|
|
for (u32 i = 0; i < gl_ctx->num_textures; i++) { |
|
|
|
|
GLTexture* glt = &gl_ctx->textures[i]; |
|
|
|
|
|
|
|
|
|
if (glt->filepath_hash == fp_hash) |
|
|
|
|
return glt; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
GLTexture* glt = getFreeGLTexture(gl_ctx); |
|
|
|
|
if (!glt) return nullptr; |
|
|
|
|
|
|
|
|
|
glt->pixel_format = (diffuse_img->num_channels == 3) ? GL_RGB : GL_RGBA; |
|
|
|
|
glt->width = diffuse_img->w; |
|
|
|
|
glt->height = diffuse_img->h; |
|
|
|
|
glt->filepath_hash = diffuse_img->filepath_hash; |
|
|
|
|
|
|
|
|
|
if (loadGLTexture(diffuse_img, glt->id)) |
|
|
|
|
return glt; |
|
|
|
|
|
|
|
|
|
printf("%s(), Error, unable to load texture\n", __FUNCTION__); |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
renderVAO(GLmesh* glmesh, glm::mat4* model_xform, shader_program* shader) |
|
|
|
|
{ |
|
|
|
|
@ -211,28 +240,12 @@ initGLAttribBuffer(gl_buffer* buf, GLenum target, GLVertexAttrib* attrib)
|
|
|
|
|
buf->name = utilAllocateCStr(attrib->name); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// FIXME: WIP
|
|
|
|
|
bool |
|
|
|
|
initGLTexture(const util_image image, GLuint& tex_id) |
|
|
|
|
{ |
|
|
|
|
glGenTextures(1, &tex_id); |
|
|
|
|
glBindTexture(GL_TEXTURE_2D, tex_id); |
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
|
|
|
|
GLenum pixel_format = (image.num_channels == 3) ? GL_RGB : GL_RGBA; |
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, pixel_format, image.w, image.h, 0, |
|
|
|
|
pixel_format, GL_UNSIGNED_BYTE, image.pixels); |
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
|
|
|
|
|
|
|
|
|
return (glGetError() == GL_NO_ERROR); |
|
|
|
|
} |
|
|
|
|
// FIXME: WIP
|
|
|
|
|
|
|
|
|
|
// FIXME: might as well pass in pointer to GLmesh, since that's how we're
|
|
|
|
|
// going to use this, can void copying GLmesh twice that way
|
|
|
|
|
GLmesh |
|
|
|
|
loadGLMesh(const mesh& m, |
|
|
|
|
GLenum draw_mode, |
|
|
|
|
GLuint diffuse_texture_id, |
|
|
|
|
const glm::vec3& pos, |
|
|
|
|
u32 num_mappings, |
|
|
|
|
GLBufferToAttribMapping mappings[]) |
|
|
|
|
@ -240,6 +253,7 @@ loadGLMesh(const mesh& m,
|
|
|
|
|
// NOTE: need to use freeGLMesh() when freeing because we're not storing
|
|
|
|
|
// the gl_buffers on a memory arean (yet)
|
|
|
|
|
GLmesh glm = initGLmesh(m, num_mappings, draw_mode, pos); |
|
|
|
|
glm.tex_id = diffuse_texture_id; |
|
|
|
|
glGenVertexArrays(1, &glm.vao_id); |
|
|
|
|
glBindVertexArray(glm.vao_id); |
|
|
|
|
|
|
|
|
|
@ -293,6 +307,31 @@ freeGLMesh(GLmesh* glm)
|
|
|
|
|
|
|
|
|
|
// NOTE: internal
|
|
|
|
|
|
|
|
|
|
GLTexture* |
|
|
|
|
getFreeGLTexture(GLContext* gl_ctx) |
|
|
|
|
{ |
|
|
|
|
if (gl_ctx->num_textures < gl_ctx->max_textures) |
|
|
|
|
return &gl_ctx->textures[gl_ctx->num_textures++]; |
|
|
|
|
|
|
|
|
|
printf("%s(), no free textures\n", __FUNCTION__); |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool |
|
|
|
|
loadGLTexture(util_image* image, GLuint& tex_id) |
|
|
|
|
{ |
|
|
|
|
glGenTextures(1, &tex_id); |
|
|
|
|
glBindTexture(GL_TEXTURE_2D, tex_id); |
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
|
|
|
|
GLenum pixel_format = (image->num_channels == 3) ? GL_RGB : GL_RGBA; |
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, pixel_format, image->w, image->h, 0, |
|
|
|
|
pixel_format, GL_UNSIGNED_BYTE, image->pixels); |
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
|
|
|
|
|
|
|
|
|
return (glGetError() == GL_NO_ERROR); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool |
|
|
|
|
compileAndLinkShader(shader_program* shader, |
|
|
|
|
const char* vert_src, |
|
|
|
|
|