Browse Source

(re-)implement texture loading

main
cinnaboot 5 years ago
parent
commit
16e90d6790
  1. 32
      src/asset.cpp
  2. 13
      src/entity.cpp
  3. 1
      src/entity.h
  4. 8
      src/main.cpp
  5. 119
      src/shader.cpp
  6. 2
      src/shader.h

32
src/asset.cpp

@ -21,7 +21,6 @@ bool parseMeshNode(mesh* m,
model* getCachedModel(Assets* assets, u64 path_hash); model* getCachedModel(Assets* assets, u64 path_hash);
model* loadModelFile(Assets* assets, const char* filename); model* loadModelFile(Assets* assets, const char* filename);
util_image* getCachedTexture(Assets* assets, u64 path_hash); util_image* getCachedTexture(Assets* assets, u64 path_hash);
util_image* loadTextureFile(Assets* assets, const char* filename);
// interface // interface
@ -43,8 +42,12 @@ getTextureByPath(Assets* assets, const char* filepath)
util_image* texture = util_image* texture =
getCachedTexture(assets, utilFNV64a_str(filepath)); getCachedTexture(assets, utilFNV64a_str(filepath));
if (!texture) // NOTE: the texture should be loaded when the model is loaded, so it's an
texture = loadTextureFile(assets, filepath); // error if we don't find it in cache
if (!texture) {
LOG(Error) << "texture file, " << filepath << " not loaded\n";
return nullptr;
}
return texture; return texture;
} }
@ -90,9 +93,13 @@ copyDiffuseTexture(Assets* assets, const tinygltf::Model& t_mdl)
&& t_mdl.images.size() == 1 && t_mdl.images.size() == 1
&& t_mdl.images[0].image.size() > 0); && t_mdl.images[0].image.size() > 0);
tinygltf::Image t_img = t_mdl.images[0]; tinygltf::Image t_img = t_mdl.images[0];
util_image* dtex = getFreeTexture(assets); util_image* dtex = getFreeTexture(assets);
if (!dtex) return nullptr;
if (!dtex) {
LOG(Error) << "Error Loading diffuse texture\n";
// TODO: reclaim arena memory
return nullptr;
}
dtex->w = t_img.width; dtex->w = t_img.width;
dtex->h = t_img.height; dtex->h = t_img.height;
@ -122,19 +129,16 @@ loadModelFile(Assets* assets, const char* filename)
<< " , msg: " << err << "\n"; << " , msg: " << err << "\n";
return nullptr; return nullptr;
} }
#if 0 #if 0
dumpNodes(t_mdl); dumpNodes(t_mdl);
#endif #endif
// NOTE: assume we're working with a single buffer // NOTE: assume we're working with a single buffer
assert(t_mdl.buffers.size() == 1); assert(t_mdl.buffers.size() == 1);
model* mdl = initModel(assets, t_mdl, filename); model* mdl = initModel(assets, t_mdl, filename);
mdl->diffuse_texture = copyDiffuseTexture(assets, t_mdl); mdl->diffuse_texture = copyDiffuseTexture(assets, t_mdl);
if (mdl->diffuse_texture == nullptr) return nullptr;
if (mdl->diffuse_texture == nullptr) {
LOG(Error) << "Error Loading diffuse texture\n";
// TODO: reclaim arena memory
return nullptr;
}
uint mesh_idx = 0; uint mesh_idx = 0;
@ -166,12 +170,6 @@ getCachedModel(Assets* assets, u64 path_hash)
return nullptr; return nullptr;
} }
util_image*
loadTextureFile(Assets* assets, const char* filename)
{
return nullptr;
}
util_image* util_image*
getCachedTexture(Assets* assets, u64 path_hash) getCachedTexture(Assets* assets, u64 path_hash)
{ {

13
src/entity.cpp

@ -6,6 +6,7 @@
bool bool
initEntity(Entity* e, initEntity(Entity* e,
GLContext* gl_ctx,
MemoryArena* arena, MemoryArena* arena,
model* mdl, model* mdl,
u32 num_attrib_mappings, u32 num_attrib_mappings,
@ -17,11 +18,19 @@ initEntity(Entity* e,
e->xform = ARENA_ALLOC(arena, glm::mat4, 1); e->xform = ARENA_ALLOC(arena, glm::mat4, 1);
*e->xform = glm::mat4(1.f); *e->xform = glm::mat4(1.f);
e->name = arenaCopyCStr(arena, name); e->name = arenaCopyCStr(arena, name);
e->diffuse_texture = getGLTexture(gl_ctx, mdl->diffuse_texture);
if (!e->diffuse_texture)
return false;
for (u32 i = 0; i< e->num_meshes; i++) { for (u32 i = 0; i< e->num_meshes; i++) {
GLmesh* glm = &e->meshes[i]; GLmesh* glm = &e->meshes[i];
*glm = loadGLMesh(mdl->meshes[i], GL_TRIANGLES, glm::vec3(0, 0, 0), *glm = loadGLMesh(mdl->meshes[i],
num_attrib_mappings, attrib_mappings); GL_TRIANGLES,
e->diffuse_texture->id,
glm::vec3(0, 0, 0),
num_attrib_mappings,
attrib_mappings);
if (glm->vao_id == 0) { if (glm->vao_id == 0) {
printf("%s(), error initializing entity\n", __FUNCTION__); printf("%s(), error initializing entity\n", __FUNCTION__);

1
src/entity.h

@ -18,6 +18,7 @@ struct Entity
bool initEntity(Entity* e, bool initEntity(Entity* e,
GLContext* gl_ctx,
MemoryArena* arena, MemoryArena* arena,
model* mdl, model* mdl,
u32 num_attrib_mappings, u32 num_attrib_mappings,

8
src/main.cpp

@ -279,9 +279,8 @@ loadScene(RenderState* rs)
Entity* e = getFreeEntity(orange_cubes); Entity* e = getFreeEntity(orange_cubes);
assert(e != nullptr); assert(e != nullptr);
// FIXME: check if mesh texture is cached here? if (!initEntity(e, rs->gl_ctx, rs->rg_arena, tex_cube,
if (!initEntity(e, rs->rg_arena, tex_cube, 2, attrib_mappings, 2, attrib_mappings, "debug_box"))
"debug_box"))
{ {
// FIXME: this doesn't actually do anything // FIXME: this doesn't actually do anything
freeRenderGroup(orange_cubes, rs->rg_arena); freeRenderGroup(orange_cubes, rs->rg_arena);
@ -299,7 +298,8 @@ loadScene(RenderState* rs)
assert(e != nullptr); assert(e != nullptr);
// FIXME: this a bug, we're reusing the attrib_mappings from the debug // FIXME: this a bug, we're reusing the attrib_mappings from the debug
// shader for the default shader, which could have different attributes // shader for the default shader, which could have different attributes
initEntity(e, rs->rg_arena, tex_cube, 2, attrib_mappings, "orange_box"); initEntity(e, rs->gl_ctx, rs->rg_arena, tex_cube,
2, attrib_mappings, "orange_box");
return true; return true;
} }

119
src/shader.cpp

@ -27,33 +27,12 @@ bool compileAndLinkShader(shader_program* shader,
GLuint& vs_id, GLuint& vs_id,
GLuint& fs_id); GLuint& fs_id);
u32 getGLTypeSize(GLenum e); u32 getGLTypeSize(GLenum e);
GLTexture* getFreeGLTexture(GLContext* gl_ctx);
bool loadGLTexture(util_image* image, GLuint& tex_id);
// NOTE: interface // 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 bool
addShaderProgram(MemoryArena* arena, addShaderProgram(MemoryArena* arena,
GLContext* gl_ctx, GLContext* gl_ctx,
@ -103,6 +82,29 @@ addShaderProgram(MemoryArena* arena,
return false; 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* shader_program*
getShaderByName(const char* name, GLContext* gl_ctx) getShaderByName(const char* name, GLContext* gl_ctx)
{ {
@ -130,6 +132,33 @@ getShaderByID(GLContext* gl_ctx, GLuint prog_id)
return nullptr; 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 void
renderVAO(GLmesh* glmesh, glm::mat4* model_xform, shader_program* shader) 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); 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 // 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 // going to use this, can void copying GLmesh twice that way
GLmesh GLmesh
loadGLMesh(const mesh& m, loadGLMesh(const mesh& m,
GLenum draw_mode, GLenum draw_mode,
GLuint diffuse_texture_id,
const glm::vec3& pos, const glm::vec3& pos,
u32 num_mappings, u32 num_mappings,
GLBufferToAttribMapping mappings[]) GLBufferToAttribMapping mappings[])
@ -240,6 +253,7 @@ loadGLMesh(const mesh& m,
// NOTE: need to use freeGLMesh() when freeing because we're not storing // NOTE: need to use freeGLMesh() when freeing because we're not storing
// the gl_buffers on a memory arean (yet) // the gl_buffers on a memory arean (yet)
GLmesh glm = initGLmesh(m, num_mappings, draw_mode, pos); GLmesh glm = initGLmesh(m, num_mappings, draw_mode, pos);
glm.tex_id = diffuse_texture_id;
glGenVertexArrays(1, &glm.vao_id); glGenVertexArrays(1, &glm.vao_id);
glBindVertexArray(glm.vao_id); glBindVertexArray(glm.vao_id);
@ -293,6 +307,31 @@ freeGLMesh(GLmesh* glm)
// NOTE: internal // 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 bool
compileAndLinkShader(shader_program* shader, compileAndLinkShader(shader_program* shader,
const char* vert_src, const char* vert_src,

2
src/shader.h

@ -164,10 +164,12 @@ 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* getShaderByHash(GLContext* gl_ctx, u64 hash);
shader_program* getFreeShader(GLContext* gl_ctx); shader_program* getFreeShader(GLContext* gl_ctx);
GLTexture* getGLTexture(GLContext* gl_ctx, util_image* diffuse_img);
void renderVAO(GLmesh* glmesh, glm::mat4* model_xform, shader_program* shader); void renderVAO(GLmesh* glmesh, glm::mat4* model_xform, shader_program* shader);
GLVertexAttrib* getVertexAttribByName(shader_program* shader, const char* name); GLVertexAttrib* getVertexAttribByName(shader_program* shader, const char* name);
GLmesh loadGLMesh(const mesh& m, GLmesh loadGLMesh(const mesh& m,
GLenum draw_mode, GLenum draw_mode,
GLuint diffuse_texture_id,
const glm::vec3& pos, const glm::vec3& pos,
u32 num_mappings, u32 num_mappings,
GLBufferToAttribMapping mappings[]); GLBufferToAttribMapping mappings[]);

Loading…
Cancel
Save