From 2f1bb4d47b4185a4b50dc6960a8ad049ee9728bc Mon Sep 17 00:00:00 2001 From: cinnaboot Date: Wed, 21 Jul 2021 12:33:29 -0400 Subject: [PATCH] add more entities to render_groups example --- examples/render_groups/main.cpp | 152 ++++++++++++++++++++++++-------- 1 file changed, 115 insertions(+), 37 deletions(-) diff --git a/examples/render_groups/main.cpp b/examples/render_groups/main.cpp index 34863dd..619d438 100644 --- a/examples/render_groups/main.cpp +++ b/examples/render_groups/main.cpp @@ -1,4 +1,7 @@ +#include +#include + #include #include "dumbLog.h" @@ -10,14 +13,15 @@ simple_mesh* makeSquareMesh() { + // NOTE: vertices arranged for GL_LINE_LOOP, non-indexed 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->vertices[0] = glm::vec3(-1000, 0, 1000); + sm->vertices[1] = glm::vec3(-1000, 0, -1000); + sm->vertices[2] = glm::vec3(1000, 0, -1000); + sm->vertices[3] = glm::vec3(1000, 0, 1000); 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); @@ -26,6 +30,49 @@ makeSquareMesh() return sm; } +int +getRand(int lower = 0, int upper = RAND_MAX) +{ + // NOTE: only need to seed prng once + static bool seeded = false; + + if (!seeded) { + srand(time(NULL)); + seeded = true; + } + + return (rand() % (upper - lower) + lower); +} + +bool +createModelEntities(render_group* rg, + const char* model_file, + uint item_count, + glm::vec3 min_pos, + glm::vec3 max_pos, + glm::vec3 scaling) +{ + assert(rg != nullptr); + + for (uint i = 0; i < item_count; i++) { + entity& e = rg->entities[i]; + + if (!entInitModel(e, model_file)) { + LOG(Error) << "Error initializing entity, exiting\n"; + return false; + } + + entSetWorldPosition(e, + glm::vec3(getRand(min_pos.x, max_pos.x), + getRand(min_pos.y, max_pos.y), + getRand(min_pos.z, max_pos.z)) + ); + entScale(e, glm::vec3(scaling.x, scaling.y, scaling.z)); + } + + return true; +} + void doFrameCallbackPre(render_state* rs) { @@ -38,16 +85,36 @@ doFrameCallbackPre(render_state* rs) } // 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 float angle = 1.2 / 60; // NOTE: 60 FPS 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); + for (uint i = 0; i < rs->render_group_count; i++) { + for (uint j = 0; j < rs->render_groups[i]->entity_count; j++) { + entity& e = rs->render_groups[i]->entities[j]; + entRotate(e, angle, axis); + } + } + + point_light& l1 = rs->lights->lights[0]; + point_light& l2 = rs->lights->lights[1]; + entity& square = rs->render_groups[2]->entities[0]; + + l1.position = glm::vec3( + square.world_transform * glm::vec4(10000, 0, 1000, 1)); + l2.position = glm::vec3( + square.world_transform * glm::vec4(10000, 0, -1000, 1)); + rs->lights->needs_update = true; + + // FIXME: looks like there's still a bug in the shader. This verifies that + // the light position is updating correctly, but the lights don't appear + // to be moving in the scene +#if 0 + LOG(Debug) << "l1.position: " + << l1.position.x << ", " + << l1.position.y << ", " + << l1.position.z + << "\n"; +#endif } int @@ -62,12 +129,13 @@ main() cameraInitPerspective( rs->cam, - glm::vec3(50, -100, 25), + glm::vec3(0, -2000, 0), glm::vec3(0, 0, 0), glm::vec3(0,0,1) ); - renAddLight(rs, glm::vec3(-20, -150, 150)); + renAddLight(rs, glm::vec3()); + renAddLight(rs, glm::vec3()); // FIXME: this introduces a potential buffer overrun. Need to implement // a memory manager for render_groups, eg: @@ -75,36 +143,46 @@ main() // rgPushEntity(rg, new_ent) rs->render_groups = UTIL_ALLOC(256, render_group*); - // TODO: this needs to be more convenient + // ship entities + const uint item_count = 20; + // 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 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; - } + rs->render_groups[0] = renAllocateGroup(item_count, sw); + rs->render_group_count++; + + bool ret = createModelEntities(rs->render_groups[0], + "../data/spaceship.glb", + item_count, + glm::vec3(-750, -750, -750), + glm::vec3(750, 750, 750), + glm::vec3(10, 10, 10) + ); + assert(ret == true); - entSetWorldPosition(spaceship, glm::vec3(-50, 0, 0)); - entScale(spaceship, glm::vec3(2, 2, 2)); - entScale(sphere, glm::vec3(20, 20, 20)); + // sphere entities + // NOTE: can also re-use the default shader already defined above + shader_wrapper sw2 = { DEFAULT_SHADER, rs->default_shader, nullptr }; + rs->render_groups[1] = renAllocateGroup(item_count, sw2); + rs->render_group_count++; + ret = createModelEntities(rs->render_groups[1], + "../data/icosphere.glb", + item_count, + glm::vec3(-750, -750, -750), + glm::vec3(750, 750, 750), + glm::vec3(100, 100, 100) + ); + assert(ret == true); - shader_wrapper sw2 = { SIMPLE_SHADER, nullptr, rs->simple_shader }; - rs->render_groups[1] = renAllocateGroup(1, sw2); + // simple_mesh/shader + shader_wrapper sw3 = { SIMPLE_SHADER, nullptr, rs->simple_shader }; + rs->render_groups[2] = renAllocateGroup(1, sw3); rs->render_group_count++; - entity& square = rs->render_groups[1]->entities[0]; + entity& square = rs->render_groups[2]->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);