From ab9fd0ac34f8107ff8067607fad229d08b1c3935 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Sun, 30 Oct 2016 04:10:30 +0200 Subject: [PATCH] foo --- src/app.cc | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/app.h | 16 +++++ src/main.cc | 168 +++++++++-------------------------------------- src/scene.h | 7 +- src/sceneload.cc | 49 ++++++++++---- 5 files changed, 280 insertions(+), 151 deletions(-) diff --git a/src/app.cc b/src/app.cc index 6125823..0869399 100644 --- a/src/app.cc +++ b/src/app.cc @@ -1,3 +1,194 @@ +#include +#include #include "app.h" +#include "opengl.h" +#include "sdr.h" +#include "texture.h" +#include "mesh.h" +#include "meshgen.h" +#include "scene.h" +static void draw_scene(); + +long time_msec; +int win_width, win_height; bool opt_gear_wireframe; + +static float cam_dist = 10.0; +static float cam_theta, cam_phi = 20; +static Vec3 cam_pos; +static int prev_mx, prev_my; +static bool bnstate[8]; +static bool keystate[256]; + +static Mat4 view_matrix; +static TextureSet texman; +static Scene *scn; + +static long prev_msec; + + +bool app_init() +{ + glEnable(GL_MULTISAMPLE); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + glEnable(GL_NORMALIZE); + + Mesh::use_custom_sdr_attr = false; + + float ambient[] = {0.1, 0.1, 0.1, 0.0}; + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient); + + unsigned int sflags = 0; + scn = new Scene; + if(!(scn->load("data/testscene/patoma.fbx", sflags)) || + !(scn->load("data/testscene/kolones.fbx", sflags))) { + fprintf(stderr, "failed to load test scene\n"); + return false; + } + + glUseProgram(0); + return true; +} + +void app_cleanup() +{ + texman.clear(); +} + +static void update(float dt) +{ + texman.update(); + + scn->update(dt); + + float walk_speed = 10.0 * dt; + Vec3 dir; + + if(keystate[(int)'w']) { + dir.z -= walk_speed; + } + if(keystate[(int)'s']) { + dir.z += walk_speed; + } + if(keystate[(int)'d']) { + dir.x += walk_speed; + } + if(keystate[(int)'a']) { + dir.x -= walk_speed; + } + + float theta = M_PI * cam_theta / 180.0f; + cam_pos.x += cos(theta) * dir.x - sin(theta) * dir.z; + cam_pos.z += sin(theta) * dir.x + cos(theta) * dir.z; +} + +static void set_light(int idx, const Vec3 &pos, const Vec3 &color) +{ + unsigned int lt = GL_LIGHT0 + idx; + float posv[] = { pos.x, pos.y, pos.z, 1 }; + float colv[] = { color.x, color.y, color.z, 1 }; + + glEnable(lt); + glLightfv(lt, GL_POSITION, posv); + glLightfv(lt, GL_DIFFUSE, colv); + glLightfv(lt, GL_SPECULAR, colv); +} + +void app_display() +{ + float dt = (float)(time_msec - prev_msec) / 1000.0f; + prev_msec = time_msec; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + view_matrix = Mat4::identity; + view_matrix.pre_translate(0, 0, -cam_dist); + view_matrix.pre_rotate(deg_to_rad(cam_phi), 1, 0, 0); + view_matrix.pre_rotate(deg_to_rad(cam_theta), 0, 1, 0); + view_matrix.pre_translate(-cam_pos.x, 0, -cam_pos.z); + + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(view_matrix[0]); + + static const Vec3 lpos[] = { Vec3(-50, 75, 100), Vec3(100, 0, 30), Vec3(-10, -10, 60) }; + set_light(0, lpos[0], Vec3(1.0, 0.8, 0.7) * 0.8); + set_light(1, lpos[1], Vec3(0.6, 0.7, 1.0) * 0.6); + set_light(2, lpos[2], Vec3(0.8, 1.0, 0.8) * 0.3); + + update(dt); + + draw_scene(); + + app_swap_buffers(); + assert(glGetError() == GL_NO_ERROR); +} + + +static void draw_scene() +{ + /* + glBegin(GL_QUADS); + glNormal3f(0, 1, 0); + glVertex3f(-30, -10, 30); + glVertex3f(30, -10, 30); + glVertex3f(30, -10, -30); + glVertex3f(-30, -10, -30); + glEnd(); + */ + scn->draw(); +} + + +void app_reshape(int x, int y) +{ + glViewport(0, 0, x, y); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(50.0, (float)x / (float)y, 0.5, 1000.0); +} + +void app_keyboard(int key, bool pressed) +{ + if(pressed) { + switch(key) { + case 27: + app_quit(); + break; + } + } + + keystate[key] = pressed; +} + +void app_mouse_button(int bn, bool pressed, int x, int y) +{ + prev_mx = x; + prev_my = y; + bnstate[bn] = pressed; +} + +void app_mouse_motion(int x, int y) +{ + int dx = x - prev_mx; + int dy = y - prev_my; + prev_mx = x; + prev_my = y; + + if(!dx && !dy) return; + + if(bnstate[0]) { + cam_theta += dx * 0.5; + cam_phi += dy * 0.5; + + if(cam_phi < -90) cam_phi = -90; + if(cam_phi > 90) cam_phi = 90; + } + if(bnstate[2]) { + cam_dist += dy * 0.1; + if(cam_dist < 0.0) cam_dist = 0.0; + } +} diff --git a/src/app.h b/src/app.h index 926c2d2..0532be1 100644 --- a/src/app.h +++ b/src/app.h @@ -1,6 +1,22 @@ #ifndef APP_H_ #define APP_H_ +extern long time_msec; +extern int win_width, win_height; extern bool opt_gear_wireframe; +bool app_init(); +void app_cleanup(); + +void app_display(); +void app_reshape(int x, int y); + +void app_keyboard(int key, bool pressed); +void app_mouse_button(int bn, bool pressed, int x, int y); +void app_mouse_motion(int x, int y); + +// the following functions are implemented by the backend (main.cc) +void app_quit(); +void app_swap_buffers(); + #endif // APP_H_ diff --git a/src/main.cc b/src/main.cc index b170095..f0ac037 100644 --- a/src/main.cc +++ b/src/main.cc @@ -8,36 +8,16 @@ #include #endif #include "app.h" -#include "sdr.h" -#include "shadow.h" -#include "texture.h" -#include "mesh.h" -#include "meshgen.h" static bool init(); -static void cleanup(); static void display(); static void idle(); -static void draw_scene(); static void reshape(int x, int y); -static void keyb(unsigned char key, int x, int y); +static void key_press(unsigned char key, int x, int y); +static void key_release(unsigned char key, int x, int y); static void mouse(int bn, int st, int x, int y); -static void motion(int x, int y); -static void passive_motion(int x, int y); - -static int win_width, win_height; - -static float cam_dist = 0.25; -static float cam_theta, cam_phi = 20; -static int prev_mx, prev_my; -static bool bnstate[8]; - -static Mat4 view_matrix; - -static unsigned int start_time, prev_msec; - -static TextureSet texman; +static unsigned int start_time; int main(int argc, char **argv) { @@ -49,90 +29,47 @@ int main(int argc, char **argv) glutDisplayFunc(display); glutIdleFunc(idle); glutReshapeFunc(reshape); - glutKeyboardFunc(keyb); + glutKeyboardFunc(key_press); + glutKeyboardUpFunc(key_release); glutMouseFunc(mouse); - glutMotionFunc(motion); - glutPassiveMotionFunc(passive_motion); + glutMotionFunc(app_mouse_motion); + glutPassiveMotionFunc(app_mouse_motion); if(!init()) { return 1; } - atexit(cleanup); + atexit(app_cleanup); glutMainLoop(); return 0; } -static bool init() +void app_swap_buffers() { - glewInit(); - - glEnable(GL_MULTISAMPLE); - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glEnable(GL_LIGHTING); - glEnable(GL_NORMALIZE); - - Mesh::use_custom_sdr_attr = false; - - float ambient[] = {0.1, 0.1, 0.1, 0.0}; - glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient); - - glUseProgram(0); - - start_time = glutGet(GLUT_ELAPSED_TIME); - return true; + glutSwapBuffers(); } -static void cleanup() +void app_quit() { - texman.clear(); + exit(0); } -static void update(float dt) +static bool init() { - texman.update(); -} + glewInit(); -static void set_light(int idx, const Vec3 &pos, const Vec3 &color) -{ - unsigned int lt = GL_LIGHT0 + idx; - float posv[] = { pos.x, pos.y, pos.z, 1 }; - float colv[] = { color.x, color.y, color.z, 1 }; - - glEnable(lt); - glLightfv(lt, GL_POSITION, posv); - glLightfv(lt, GL_DIFFUSE, colv); - glLightfv(lt, GL_SPECULAR, colv); + if(!app_init()) { + return false; + } + + start_time = glutGet(GLUT_ELAPSED_TIME); + return true; } static void display() { - unsigned int msec = glutGet(GLUT_ELAPSED_TIME) - start_time; - float dt = (float)(msec - prev_msec) / 1000.0f; - prev_msec = msec; - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - view_matrix = Mat4::identity; - view_matrix.pre_translate(0, 0, -cam_dist); - view_matrix.pre_rotate(deg_to_rad(cam_phi), 1, 0, 0); - view_matrix.pre_rotate(deg_to_rad(cam_theta), 0, 1, 0); - - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf(view_matrix[0]); - - static const Vec3 lpos[] = { Vec3(-50, 75, 100), Vec3(100, 0, 30), Vec3(-10, -10, 60) }; - set_light(0, lpos[0], Vec3(1.0, 0.8, 0.7) * 0.8); - set_light(1, lpos[1], Vec3(0.6, 0.7, 1.0) * 0.6); - set_light(2, lpos[2], Vec3(0.8, 1.0, 0.8) * 0.3); - - update(dt); - - draw_scene(); - - glutSwapBuffers(); - assert(glGetError() == GL_NO_ERROR); + time_msec = glutGet(GLUT_ELAPSED_TIME) - start_time; + app_display(); } static void idle() @@ -140,35 +77,22 @@ static void idle() glutPostRedisplay(); } -static void draw_scene() -{ - glBegin(GL_QUADS); - glNormal3f(0, 1, 0); - glVertex3f(-30, -10, 30); - glVertex3f(30, -10, 30); - glVertex3f(30, -10, -30); - glVertex3f(-30, -10, -30); - glEnd(); -} - static void reshape(int x, int y) { win_width = x; win_height = y; - glViewport(0, 0, x, y); + app_reshape(x, y); +} - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(50.0, (float)x / (float)y, 0.01, 50.0); +static void key_press(unsigned char key, int x, int y) +{ + app_keyboard(key, true); } -static void keyb(unsigned char key, int x, int y) +static void key_release(unsigned char key, int x, int y) { - switch(key) { - case 27: - exit(0); - } + app_keyboard(key, false); } static void mouse(int bn, int st, int x, int y) @@ -176,37 +100,5 @@ static void mouse(int bn, int st, int x, int y) int bidx = bn - GLUT_LEFT_BUTTON; bool down = st == GLUT_DOWN; - prev_mx = x; - prev_my = y; - bnstate[bidx] = down; -} - -static void motion(int x, int y) -{ - int dx = x - prev_mx; - int dy = y - prev_my; - prev_mx = x; - prev_my = y; - - if(!dx && !dy) return; - - if(bnstate[0]) { - cam_theta += dx * 0.5; - cam_phi += dy * 0.5; - - if(cam_phi < -90) cam_phi = -90; - if(cam_phi > 90) cam_phi = 90; - glutPostRedisplay(); - } - if(bnstate[2]) { - cam_dist += dy * 0.01; - if(cam_dist < 0.0) cam_dist = 0.0; - glutPostRedisplay(); - } -} - -static void passive_motion(int x, int y) -{ - prev_mx = x; - prev_my = y; + app_mouse_button(bidx, down, x, y); } diff --git a/src/scene.h b/src/scene.h index 7c30445..066d9dc 100644 --- a/src/scene.h +++ b/src/scene.h @@ -5,6 +5,11 @@ #include "mesh.h" #include "snode.h" +enum { + SCNLOAD_FLIPYZ = 1, + SCNLOAD_FLIPTEX = 2 +}; + class Scene { public: std::vector meshes; @@ -19,7 +24,7 @@ public: void destroy(); - bool load(const char *fname); + bool load(const char *fname, unsigned int flags = 0); void update(float dt); void draw() const; diff --git a/src/sceneload.cc b/src/sceneload.cc index b2b00eb..5179e4a 100644 --- a/src/sceneload.cc +++ b/src/sceneload.cc @@ -15,8 +15,8 @@ #include "objmesh.h" static bool load_material(Material *mat, const aiMaterial *aimat); -static SceneNode *load_node(const aiScene *aiscn, const aiNode *ainode); -static Mesh *load_mesh(const aiScene *aiscn, const aiMesh *aimesh); +static SceneNode *load_node(const aiScene *aiscn, unsigned int flags, const aiNode *ainode); +static Mesh *load_mesh(const aiScene *aiscn, unsigned int flags, const aiMesh *aimesh); /*static Vec3 assimp_vector(const aiVector3D &v); static Quat assimp_quat(const aiQuaternion &q); @@ -28,14 +28,18 @@ static void print_hierarchy(const aiNode *node); static std::map node_by_name; static std::map mesh_by_aimesh; -bool Scene::load(const char *fname) +bool Scene::load(const char *fname, unsigned int flags) { unsigned int ppflags = aiProcess_CalcTangentSpace | aiProcess_GenNormals | aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType | - aiProcess_TransformUVCoords; + aiProcess_TransformUVCoords | aiProcess_PreTransformVertices; + + if(flags & SCNLOAD_FLIPTEX) { + ppflags |= aiProcess_FlipUVs; + } const aiScene *aiscn = aiImportFile(fname, ppflags); if(!aiscn) { @@ -61,7 +65,7 @@ bool Scene::load(const char *fname) switch(aimesh->mPrimitiveTypes) { case aiPrimitiveType_TRIANGLE: - if((mesh = load_mesh(aiscn, aimesh))) { + if((mesh = load_mesh(aiscn, flags, aimesh))) { mesh_by_aimesh[aimesh] = mesh; meshes.push_back(mesh); } @@ -77,7 +81,7 @@ bool Scene::load(const char *fname) // load all the nodes recursively for(unsigned int i=0; imRootNode->mNumChildren; i++) { - SceneNode *node = load_node(aiscn, aiscn->mRootNode->mChildren[i]); + SceneNode *node = load_node(aiscn, flags, aiscn->mRootNode->mChildren[i]); if(node) { root->add_child(node); } @@ -154,7 +158,7 @@ static bool load_material(Material *mat, const aiMaterial *aimat) return true; } -static SceneNode *load_node(const aiScene *aiscn, const aiNode *ainode) +static SceneNode *load_node(const aiScene *aiscn, unsigned int flags, const aiNode *ainode) { SceneNode *node = new SceneNode; node->set_name(ainode->mName.data); @@ -175,7 +179,7 @@ static SceneNode *load_node(const aiScene *aiscn, const aiNode *ainode) /* recurse to all children */ for(unsigned int i=0; imNumChildren; i++) { - SceneNode *child = load_node(aiscn, ainode->mChildren[i]); + SceneNode *child = load_node(aiscn, flags, ainode->mChildren[i]); if(child) { node->add_child(child); } @@ -185,7 +189,7 @@ static SceneNode *load_node(const aiScene *aiscn, const aiNode *ainode) return node; } -static Mesh *load_mesh(const aiScene *aiscn, const aiMesh *aimesh) +static Mesh *load_mesh(const aiScene *aiscn, unsigned int flags, const aiMesh *aimesh) { Mesh *mesh = new Mesh; @@ -204,11 +208,32 @@ static Mesh *load_mesh(const aiScene *aiscn, const aiMesh *aimesh) mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 3, num_verts, (float*)aimesh->mTextureCoords[0]); } + if(flags & SCNLOAD_FLIPYZ) { + Vec3 *vptr = (Vec3*)mesh->get_attrib_data(MESH_ATTR_VERTEX); + for(int i=0; ixzy(); + ++vptr; + } + + Vec3 *nptr = (Vec3*)mesh->get_attrib_data(MESH_ATTR_NORMAL); + for(int i=0; ixzy(); + ++nptr; + } + + Vec3 *tptr = (Vec3*)mesh->get_attrib_data(MESH_ATTR_TANGENT); + for(int i=0; ixzy(); + ++tptr; + } + } + unsigned int *iptr = mesh->set_index_data(num_faces * 3); for(int i=0; imFaces[i].mIndices[j]; - } + iptr[0] = aimesh->mFaces[i].mIndices[0]; + iptr[1] = aimesh->mFaces[i].mIndices[flags & SCNLOAD_FLIPYZ ? 2 : 1]; + iptr[2] = aimesh->mFaces[i].mIndices[flags & SCNLOAD_FLIPYZ ? 1 : 2]; + iptr += 3; } return mesh; -- 1.7.10.4