|
|
|
|
@ -1,4 +1,7 @@
|
|
|
|
|
|
|
|
|
|
#include <cstdlib> |
|
|
|
|
#include <ctime> |
|
|
|
|
|
|
|
|
|
#include <glm/glm.hpp> |
|
|
|
|
|
|
|
|
|
#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); |
|
|
|
|
|
|
|
|
|
|