diff --git a/src/entity.cpp b/src/entity.cpp index 0a73768..b819687 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -19,16 +19,19 @@ initEntity(Entity* e, e->model_xform = ARENA_ALLOC(arena, glm::mat4, 1); *e->model_xform = glm::mat4(1.f); e->name = arenaCopyCStr(arena, name); - e->diffuse_texture = getGLTexture(gl_ctx, mdl->diffuse_texture); - if (!e->diffuse_texture) - return false; + if (mdl->diffuse_texture) { + e->diffuse_texture = getGLTexture(gl_ctx, mdl->diffuse_texture); + + if (!e->diffuse_texture) + return false; + } for (u32 i = 0; i< e->num_meshes; i++) { GLMesh* glm = &e->meshes[i]; *glm = loadGLMesh(mdl->meshes[i], GL_TRIANGLES, - e->diffuse_texture->id, + e->diffuse_texture, num_attrib_mappings, attrib_mappings); diff --git a/src/main.cpp b/src/main.cpp index 3534bed..cb62320 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -56,40 +56,7 @@ loadLights(RenderState* rs) } bool -loadSpaceShip(RenderState* rs) -{ - Model* ship = getModelByPath(&rs->assets, "../data/spaceship.gltf"); - if (!ship) - return false; - - ShaderProgram* shader_lit = getShaderByName("full_lighting", rs->gl_ctx); - if (!shader_lit) - return false; - - // load model into gl - RenderGroup* rg = getFreeRenderGroup(rs); - assert(rs); - initRenderGroup(rg, rs->rg_arena, shader_lit, 256, "ships"); - Entity* e = getFreeEntity(rg); - assert(e); - - if (initEntity(e, rs->gl_ctx, - rs->rg_arena, - ship, - shader_lit->num_vertex_attribs, - shader_lit->attrib_mappings, - "ship 01")) - { - setEntityPosition(e, glm::vec3(0, -10, -15)); - } else { - return false; - } - - return true; -} - -bool -loadScene(RenderState* rs) +loadCubes(RenderState* rs) { // NOTE: load model Model* tex_cube = getModelByPath(&rs->assets, "../data/textured_cube.gltf"); @@ -124,7 +91,6 @@ loadScene(RenderState* rs) char cube_name[256] = {0}; snprintf(cube_name, 256, "textured_cube%d", i); - arenaCopyCStr(rs->rg_arena, cube_name); if (!initEntity(e, rs->gl_ctx, rs->rg_arena, @@ -140,8 +106,115 @@ loadScene(RenderState* rs) scaleEntity(e, 3); } - // NOTE: testing an entity with multiple meshes -#if 0 + return true; +} + +// NOTE: test an entity with multiple meshes +bool +loadSpaceShip(RenderState* rs) +{ + Model* ship = getModelByPath(&rs->assets, "../data/spaceship.gltf"); + if (!ship) + return false; + + ShaderProgram* shader_lit = getShaderByName("full_lighting", rs->gl_ctx); + if (!shader_lit) + return false; + + // load model into gl + RenderGroup* rg = getFreeRenderGroup(rs); + assert(rs); + initRenderGroup(rg, rs->rg_arena, shader_lit, 256, "ships"); + Entity* e = getFreeEntity(rg); + assert(e); + + if (initEntity(e, rs->gl_ctx, + rs->rg_arena, + ship, + shader_lit->num_vertex_attribs, + shader_lit->attrib_mappings, + "ship 01")) + { + setEntityPosition(e, glm::vec3(0, -10, -15)); + } else { + return false; + } + + return true; +} + +bool +testColoredVertices(RenderState* rs) +{ + Mesh m = {0}; + m.num_vertices = 5; + m.num_indices = 12; + + glm::vec3 vertices[m.num_vertices] = { + { 0, 1, 0 }, + { -1, -1, -1 }, + { -1, -1, 1 }, + { 1, -1, 0.5 }, + }; + + u16 indices[m.num_indices] = { + 0, 1, 2, + 0, 2, 3, + 0, 3, 1, + 1, 2, 3 + }; + + glm::vec3 colors[m.num_vertices] = { + { 1, 0, 0 }, + { 0, 1, 0 }, + { 0, 0, 1 }, + { 1, 1, 0 } + }; + + m.vertices = vertices; + m.colors = colors; + m.indices = indices; + glm::mat4 xform = glm::mat4(1); + m.xform = &xform; + Model mdl = {0}; + mdl.num_meshes = 1; + mdl.meshes = &m; + + ShaderProgram* shader = getShaderByName("colored_vertices", rs->gl_ctx); + RenderGroup* rg = getFreeRenderGroup(rs); + assert(shader && rg); + initRenderGroup(rg, rs->rg_arena, shader, 256, "colored_pyramids"); + Entity* e = getFreeEntity(rg); + assert(e); + + if (initEntity(e, rs->gl_ctx, + rs->rg_arena, + &mdl, + shader->num_vertex_attribs, + shader->attrib_mappings, + "colored pyramid 01")) + { + setEntityPosition(e, glm::vec3(0, -10, 15)); + } else { + return false; + } + + return true; +} + +bool +loadScene(RenderState* rs) +{ + if (!loadCubes(rs)) { + LOGF(Error, "Error loading cubes\n"); + return false; + } + + if (!testColoredVertices(rs)) { + LOGF(Error, "Error loading colored vertices\n"); + return false; + } +#if 1 if (!loadSpaceShip(rs)) return false; #endif diff --git a/src/shader.cpp b/src/shader.cpp index 1414564..ac5ece9 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -235,15 +235,15 @@ void renderVAO(GLMesh* glmesh, glm::mat4* node_xform, ShaderProgram* shader, - GLuint tex_id) + GLTexture* gl_tex) { glUseProgram(shader->prog_id); glBindVertexArray(glmesh->vao_id); glUniformMatrix4fv(shader->node_xform_id, 1, GL_FALSE, (float*) node_xform); - if (tex_id > 0) { - glBindTexture(GL_TEXTURE_2D, tex_id); + if (glmesh->has_texture) { + glBindTexture(GL_TEXTURE_2D, gl_tex->id); glUniform1i(shader->sampler_id, 0); } @@ -324,14 +324,19 @@ initGLAttribBuffer(GLBuffer* buf, GLenum target, GLVertexAttrib* attrib) GLMesh loadGLMesh(const Mesh& m, GLenum draw_mode, - GLuint diffuse_texture_id, + GLTexture* diffuse_texture, u32 num_mappings, GLBufferToAttribMapping mappings[]) { // NOTE: need to use freeGLMesh() when freeing because we're not storing // the GLBuffers on a memory arean (yet) GLMesh glm = initGLMesh(m, num_mappings, draw_mode); - glm.tex_id = diffuse_texture_id; + + if (diffuse_texture) { + glm.has_texture = true; + glm.tex_id = diffuse_texture->id; + } + glGenVertexArrays(1, &glm.vao_id); glBindVertexArray(glm.vao_id); diff --git a/src/shader.h b/src/shader.h index 7d552e9..8978003 100644 --- a/src/shader.h +++ b/src/shader.h @@ -129,6 +129,7 @@ struct GLMesh { u32 num_indices; GLuint vao_id; + bool has_texture; GLuint tex_id; GLenum draw_mode; // NOTE: GL_LINES, GL_TRIANGLES GLenum usage; // NOTE: GL_STATIC_DRAW, GL_DYNAMIC_DRAW @@ -188,13 +189,13 @@ void updateGLBuffer(GLBuffer* gl_buf, void* data); void renderVAO(GLMesh* glmesh, glm::mat4* node_xform, ShaderProgram* shader, - GLuint tex_id = 0); + GLTexture* gl_tex); GLVertexAttrib* getVertexAttribByName(ShaderProgram* shader, const char* name); GLMesh loadGLMesh(const Mesh& m, GLenum draw_mode, - GLuint diffuse_texture_id, + GLTexture* diffuse_texture, u32 num_mappings, GLBufferToAttribMapping mappings[]); diff --git a/src/tangerine.cpp b/src/tangerine.cpp index e6aaa91..763c094 100644 --- a/src/tangerine.cpp +++ b/src/tangerine.cpp @@ -196,7 +196,7 @@ renderFrame(RenderState* rs, const GLClearColor& clear_col) for (u32 k = 0; k < e->num_meshes; k++) { GLMesh& glm = e->meshes[k]; renderVAO(&glm, e->model_xform, rg->shader, - e->diffuse_texture->id); + e->diffuse_texture); } } } diff --git a/src/tangerine.h b/src/tangerine.h index 2a13627..b52e052 100644 --- a/src/tangerine.h +++ b/src/tangerine.h @@ -57,6 +57,7 @@ * - test complex entities * - need a separate GLBufferToAttribMapping for each mesh on an entity * - maybe fixed now with MeshBufferType enum and getMeshData() +* - allow entities to have an empty diffuse texture (see initEntity()) */