#include #include #include #include "asset.h" #include "dumbLog.h" #include "input.h" #include "mesh.h" #include "renderer.h" 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(-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); sm->vert_colors[3] = glm::vec3(255, 0, 0); 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) { static input_state is = {}; inputProcessEvents(&is); if (is.window_closed || is.escape) { rs->running = false; return; } // NOTE: rotate meshes on z-axis every frame static float angle = 1.2 / 60; // NOTE: 60 FPS static glm::vec3 axis(0, 0, 1); 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; } 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(0, -2000, 0), glm::vec3(0, 0, 0), glm::vec3(0,0,1) ); renAddLight(rs, glm::vec3()); renAddLight(rs, glm::vec3()); #if 0 // 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*); // 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(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); // 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); // 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[2]->entities[0]; simple_mesh* sm = makeSquareMesh(); entInitMesh(square, sm, GL_LINE_LOOP); renDoRenderLoop(rs, 60, doFrameCallbackPre); #endif rs->arena = arenaInit(); rs->asset_list = (render_asset*) arenaAllocateBlock(rs->arena, sizeof(render_asset)); //mesh_group mg; //meLoadFromFile(mg, "../data/blender/icosphere.gltf"); render_asset* rass = assetLoadFromFile("../data/blender/icosphere.gltf"); renShutdown(rs); return 0; }