diff --git a/examples/Makefile b/examples/Makefile index 11845d7..1198da8 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -14,9 +14,10 @@ ASSIMP_LIB := ../$(ASSIMP_DIR)/build/code/libassimp.a endif EXAMPLE_SOURCES = \ - hello_world/main.cpp \ - assimp_loading/main.cpp \ - simple_mesh/main.cpp + render_groups/main.cpp + #hello_world/main.cpp \ + #assimp_loading/main.cpp \ + #simple_mesh/main.cpp EXAMPLE_OBJECTS = $(patsubst %/, $(OBJDIR)/%.o, $(dir $(EXAMPLE_SOURCES))) all: mkdirs $(EXAMPLE_OBJECTS) diff --git a/examples/assimp_loading/main.cpp b/examples/assimp_loading/main.cpp index 39a13d4..5892f8f 100644 --- a/examples/assimp_loading/main.cpp +++ b/examples/assimp_loading/main.cpp @@ -29,7 +29,7 @@ doFrameCallback(render_state* rs) rotate_mod = 1; // NOTE: rotate mesh on z-axis every frame - entity& e = rs->render_groups[0].entities[0]; + entity& e = rs->render_groups[0]->entities[0]; static float angle = (float) M_PI_2 / 33; static glm::vec3 axis(0, 0, 1); entRotate(e, angle * rotate_mod, axis); @@ -42,6 +42,7 @@ int main() { render_state* rs = renInit("assimp loading"); + rs->render_groups = UTIL_ALLOC(256, render_group*); if (rs == nullptr) { LOG(Error) << "Error Initialzing renderer\n"; @@ -50,9 +51,9 @@ main() // TODO: this needs to be more convenient shader_wrapper sw = { DEFAULT_SHADER, rs->default_shader, nullptr }; - rs->render_groups = renAllocateGroup(1, sw); + rs->render_groups[0] = renAllocateGroup(1, sw); rs->render_group_count = 1; - entity& spaceship = rs->render_groups->entities[0]; + entity& spaceship = rs->render_groups[0]->entities[0]; cameraInitPerspective( rs->cam, diff --git a/examples/data/icosphere.glb b/examples/data/icosphere.glb new file mode 100644 index 0000000..73d3fe3 --- /dev/null +++ b/examples/data/icosphere.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50b0efdbf32acbf2d9191856dc882405430d5788e96059b27176c1c7c1ddec70 +size 606540 diff --git a/examples/render_groups/main.cpp b/examples/render_groups/main.cpp new file mode 100644 index 0000000..34863dd --- /dev/null +++ b/examples/render_groups/main.cpp @@ -0,0 +1,114 @@ + +#include + +#include "dumbLog.h" +#include "input.h" +#include "mesh.h" +#include "renderer.h" + + +simple_mesh* +makeSquareMesh() +{ + uint num_vertices = 4; + simple_mesh* sm = meInitMesh(num_vertices); + sm->num_vertices = num_vertices; + + sm->vertices[0] = glm::vec3(-200, 0, 200); + sm->vertices[1] = glm::vec3(-200, 0, -200); + sm->vertices[2] = glm::vec3(200, 0, -200); + sm->vertices[3] = glm::vec3(200, 0, 200); + sm->vert_colors[0] = glm::vec3(255, 0, 0); + sm->vert_colors[1] = glm::vec3(255, 0, 0); + sm->vert_colors[2] = glm::vec3(255, 0, 0); + sm->vert_colors[3] = glm::vec3(255, 0, 0); + + return sm; +} + +void +doFrameCallbackPre(render_state* rs) +{ + static input_state is = {}; + inputProcessEvents(&is); + + if (is.window_closed || is.escape) { + rs->running = false; + return; + } + + // NOTE: rotate meshes on z-axis every frame + const float deg_angle = 3; // NOTE: angle to rotate per frame in degrees + static float angle = (float) deg_angle * M_PI_2 / 360; + static glm::vec3 axis(0, 0, 1); + + entity& ship = rs->render_groups[0]->entities[0]; + entRotate(ship, angle , axis); + entity& sphere = rs->render_groups[0]->entities[1]; + entRotate(sphere, angle , axis); + entity& square = rs->render_groups[1]->entities[0]; + entRotate(square, -1 * angle , axis); +} + +int +main() +{ + render_state* rs = renInit("render group example"); + + if (rs == nullptr) { + LOG(Error) << "Error Initialzing renderer\n"; + return 1; + } + + cameraInitPerspective( + rs->cam, + glm::vec3(50, -100, 25), + glm::vec3(0, 0, 0), + glm::vec3(0,0,1) + ); + + renAddLight(rs, glm::vec3(-20, -150, 150)); + + // FIXME: this introduces a potential buffer overrun. Need to implement + // a memory manager for render_groups, eg: + // renPushGroup(rs, new_group) + // rgPushEntity(rg, new_ent) + rs->render_groups = UTIL_ALLOC(256, render_group*); + + // TODO: this needs to be more convenient + shader_wrapper sw = { DEFAULT_SHADER, rs->default_shader, nullptr }; + rs->render_groups[0] = renAllocateGroup(2, sw); + rs->render_group_count = 1; + entity& spaceship = rs->render_groups[0]->entities[0]; + entity& sphere = rs->render_groups[0]->entities[1]; + + if (!entInitModel(spaceship, "../data/spaceship.glb") || + !entInitModel(sphere, "../data/icosphere.glb")) + { + LOG(Error) << "Error initializing entity, exiting\n"; + return 1; + } + + entSetWorldPosition(spaceship, glm::vec3(-50, 0, 0)); + entScale(spaceship, glm::vec3(2, 2, 2)); + entScale(sphere, glm::vec3(20, 20, 20)); + + shader_wrapper sw2 = { SIMPLE_SHADER, nullptr, rs->simple_shader }; + rs->render_groups[1] = renAllocateGroup(1, sw2); + rs->render_group_count++; + + entity& square = rs->render_groups[1]->entities[0]; + simple_mesh* sm = makeSquareMesh(); + + // TODO: better usage would be: renPushEntity(rs->render_groups[0], e); + // would need to allocate a reasonable block size by default (~64), and + // double it if pushing to render_group would overflow + entInitMesh(square, sm, GL_LINE_LOOP); + entScale(square, glm::vec3(0.2, 0.2, 0.2)); + + renDoRenderLoop(rs, 60, doFrameCallbackPre); + + renShutdown(rs); + return 0; +} + diff --git a/examples/simple_mesh/main.cpp b/examples/simple_mesh/main.cpp index e4cd0e3..fd67b6d 100644 --- a/examples/simple_mesh/main.cpp +++ b/examples/simple_mesh/main.cpp @@ -26,7 +26,7 @@ doFrameCallbackPre(render_state* rs) rotate_mod = 1; // NOTE: rotate mesh on z-axis every frame - entity& e = rs->render_groups[0].entities[0]; + entity& e = rs->render_groups[0]->entities[0]; static float angle = (float) M_PI_2 / 33; static glm::vec3 axis(0, 0, 1); entRotate(e, angle * rotate_mod, axis); @@ -55,6 +55,7 @@ int main() { render_state* rs = renInit("simple mesh"); + rs->render_groups = UTIL_ALLOC(256, render_group*); if (rs == nullptr) { LOG(Error) << "Error Initialzing renderer\n"; @@ -63,10 +64,10 @@ main() // TODO: this needs to be more convenient shader_wrapper sw = { SIMPLE_SHADER, nullptr, rs->simple_shader }; - rs->render_groups = renAllocateGroup(1, sw); + rs->render_groups[0] = renAllocateGroup(1, sw); rs->render_group_count = 1; - entity& e = rs->render_groups[0].entities[0]; + entity& e = rs->render_groups[0]->entities[0]; simple_mesh* sm = makeSquareMesh(); // TODO: better usage would be: renPushEntity(rs->render_groups[0], e); diff --git a/include/renderer.h b/include/renderer.h index 52b3388..0329e6c 100644 --- a/include/renderer.h +++ b/include/renderer.h @@ -51,7 +51,7 @@ struct render_state // TODO: this really needs to be a resizable array, or linked list, or // ...gasp, std::vector - render_group* render_groups; + render_group** render_groups; uint render_group_count; // TODO: hide shaders behind a better abstraction than 'shader_wrapper' diff --git a/src/renderer.cpp b/src/renderer.cpp index 064f243..8430bcc 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -62,10 +62,10 @@ void renShutdown(render_state* rs) { for (uint i = 0; i < rs->render_group_count; i++) { - for (uint j = 0; j < rs->render_groups[i].entity_count; j++) - entFree(rs->render_groups[i].entities[j]); + for (uint j = 0; j < rs->render_groups[i]->entity_count; j++) + entFree(rs->render_groups[i]->entities[j]); - utilSafeFree(rs->render_groups[i].entities); + utilSafeFree(rs->render_groups[i]->entities); } shaderFree(rs->default_shader->program_id); @@ -140,14 +140,14 @@ renRenderFrame(render_state* rs) glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); for (uint i = 0; i < rs->render_group_count; i++) { - render_group& rg = rs->render_groups[i]; + render_group* rg = rs->render_groups[i]; - for (uint j = 0; j < rg.entity_count; j++) { - entity& e = rg.entities[j]; + for (uint j = 0; j < rg->entity_count; j++) { + entity& e = rg->entities[j]; roDraw(e.render_objs, e.world_transform, rs->cam, - rg.shader, + rg->shader, rs->lights); } }