void clear_window(v3 color) { glClearColor(color.x, color.y, color.z, 1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); } void begin3d(prge_window_t window, shader_t shader, camera_t camera) { f32 aspect_ratio = (f32)window.width/(f32)window.height; mat4 projection = perspective(camera, aspect_ratio); mat4 view = camera_get_view_mat(camera); glUseProgram(shader.id); shader_set_mat4(shader, SHADER_PROJECTION_MATRIX, projection); shader_set_mat4(shader, SHADER_VIEW_MATRIX, view); } void end3d(void) { glUseProgram(0); } void begin3d_alpha(prge_window_t window, shader_t shader, camera_t camera) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); begin3d(window, shader, camera); } void end3d_alpha(void) { end3d(); glDisable(GL_BLEND); } void draw_mesh(mesh_t mesh) { if (!mesh.vao) { printf("warning: trying to draw mesh that doesn't have vao\n"); return; } glBindVertexArray(mesh.vao); for (i32 i = 0; i < mesh.ntextures; i++) { glActiveTexture(GL_TEXTURE0+i); glBindTexture(GL_TEXTURE_2D, mesh.textures[i].id); } if (mesh.ebo) glDrawElements(GL_TRIANGLES, mesh.nindices, GL_UNSIGNED_INT, 0); else glDrawArrays(GL_TRIANGLES, 0, mesh.nvertices); glBindTexture(GL_TEXTURE_2D, 0); glBindVertexArray(0); } void draw_model(shader_t shader, model_t model) { mat4 modelmat = apply_transform(model.transform); for (i32 i = 0; i < model.nmeshes; ++i) { mat4 meshmat = apply_transform(model.meshes[i].transform); mat4 resultmat = mat4_mul(modelmat, meshmat); shader_set_mat4(shader, SHADER_MODEL_MATRIX, resultmat); draw_mesh(model.meshes[i]); } } void draw_entity(shader_t shader, entity_t entity) { v3 position = entity.model.transform.position; position = v3_add(position, entity.position); entity.model.transform.position = position; draw_model(shader, entity.model); } void draw_entities(elist_t entities, shader_t shader) { for (enode_t *node = entities.first; node; node = node->next) if (!(node->entity.flags & ENTITY_ALPHA)) draw_entity(shader, node->entity); } void draw_entities_alpha(elist_t entities, shader_t shader) { for (enode_t *node = entities.first; node; node = node->next) if (node->entity.flags & ENTITY_ALPHA) draw_entity(shader, node->entity); }