vrheights
changeset 8:3f221bdc9bab
mesh loading
walk polys
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 03 Oct 2014 04:16:16 +0300 |
parents | 0eca023ed909 |
children | df3a70664a7d |
files | src/game.cc src/game_var.cc src/material.cc src/material.h src/mesh.cc src/mesh.h src/object.cc src/object.h src/scenefile.cc src/scenefile.h src/texman.cc src/texman.h |
diffstat | 12 files changed, 806 insertions(+), 15 deletions(-) [+] |
line diff
1.1 --- a/src/game.cc Wed Oct 01 01:06:55 2014 +0300 1.2 +++ b/src/game.cc Fri Oct 03 04:16:16 2014 +0300 1.3 @@ -10,6 +10,7 @@ 1.4 #include "console.h" 1.5 #include "drawtext.h" 1.6 #include "game_var.h" 1.7 +#include "scenefile.h" 1.8 1.9 static void draw_scene(); 1.10 static void material(float r, float g, float b, float roughness); 1.11 @@ -26,19 +27,33 @@ 1.12 1.13 static unsigned int chess_tex; 1.14 1.15 -static float cam_theta, cam_phi; 1.16 -static Vector3 cam_pos; 1.17 +static float cam_theta = -90, cam_phi; 1.18 +static Vector3 cam_pos = {15.4, 0, 0}; 1.19 static bool keystate[256]; 1.20 1.21 static Console con; 1.22 static dtx_font *con_font; 1.23 1.24 -#define OPT_LOOK_WALK "look-walk" 1.25 +static SceneFile scn; 1.26 + 1.27 +#define GVAR_LOOK_WALK "look-walk" 1.28 +#define GVAR_MAX_STEP "max-step" 1.29 1.30 bool game_init() 1.31 { 1.32 init_opengl(); 1.33 1.34 + if(!(con_font = dtx_open_font_glyphmap("data/mono14.glyphmap"))) { 1.35 + fprintf(stderr, "failed to open console font\n"); 1.36 + return false; 1.37 + } 1.38 + con.set_font(con_font, 14); 1.39 + con.set_size(7, 52); 1.40 + con.set_position(0, 0, Console::CENTER); 1.41 + con.set_command_func(con_handle); 1.42 + con.set_echo(false); 1.43 + 1.44 + 1.45 if(vr_init() == -1) { 1.46 return false; 1.47 } 1.48 @@ -57,18 +72,14 @@ 1.49 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1.50 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 4, 4, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, chess_pixels); 1.51 1.52 - if(!(con_font = dtx_open_font_glyphmap("data/mono14.glyphmap"))) { 1.53 - fprintf(stderr, "failed to open console font\n"); 1.54 + if(!scn.load("data/sibenik.goatsce")) { 1.55 + fprintf(stderr, "failed to load scene file\n"); 1.56 return false; 1.57 } 1.58 - con.set_font(con_font, 14); 1.59 - con.set_size(7, 52); 1.60 - con.set_position(0, 0, Console::CENTER); 1.61 - con.set_command_func(con_handle); 1.62 - con.set_echo(false); 1.63 1.64 /* initialize all option variables */ 1.65 - set_gvar_bool(OPT_LOOK_WALK, true); 1.66 + set_gvar_bool(GVAR_LOOK_WALK, true); 1.67 + set_gvar_num(GVAR_MAX_STEP, 0.5); 1.68 1.69 return true; 1.70 } 1.71 @@ -105,7 +116,7 @@ 1.72 dir += Vector3(0, 0, offs); 1.73 } 1.74 1.75 - if(get_gvar_bool(OPT_LOOK_WALK)) { 1.76 + if(get_gvar_bool(GVAR_LOOK_WALK)) { 1.77 float rot[4]; 1.78 vr_view_rotation(0, rot); 1.79 Quaternion q(rot[3], rot[0], rot[1], rot[2]); 1.80 @@ -118,6 +129,8 @@ 1.81 cam_pos.x += dir.x * cos_theta - dir.z * sin_theta; 1.82 cam_pos.z += dir.x * sin_theta + dir.z * cos_theta; 1.83 1.84 + float max_step = get_gvar_num(GVAR_MAX_STEP); 1.85 + cam_pos = scn.find_walk_pos(cam_pos + Vector3(0, max_step, 0)); 1.86 } 1.87 1.88 void game_display() 1.89 @@ -242,6 +255,8 @@ 1.90 } 1.91 } 1.92 1.93 +MeshFace dbg_walk_face; 1.94 + 1.95 static void draw_scene() 1.96 { 1.97 float lpos[][4] = { 1.98 @@ -261,6 +276,7 @@ 1.99 1.100 glMatrixMode(GL_MODELVIEW); 1.101 1.102 + /* 1.103 glBindTexture(GL_TEXTURE_2D, chess_tex); 1.104 glEnable(GL_TEXTURE_2D); 1.105 material(1, 1, 1, 1); 1.106 @@ -272,14 +288,33 @@ 1.107 glTexCoord2f(0, 1); glVertex3f(-10, 0, -10); 1.108 glEnd(); 1.109 glDisable(GL_TEXTURE_2D); 1.110 + */ 1.111 1.112 - material(1, 1, 1, 0.4); 1.113 + /*material(1, 1, 1, 0.4); 1.114 glPushMatrix(); 1.115 glTranslatef(0, 1.3, -10); 1.116 glFrontFace(GL_CW); 1.117 bezier_teapot(2.0); 1.118 glFrontFace(GL_CCW); 1.119 - glPopMatrix(); 1.120 + glPopMatrix();*/ 1.121 + 1.122 + for(size_t i=0; i<scn.obj.size(); i++) { 1.123 + scn.obj[i]->draw(); 1.124 + } 1.125 + 1.126 + glPushAttrib(GL_ENABLE_BIT); 1.127 + glDisable(GL_DEPTH_TEST); 1.128 + glDisable(GL_LIGHTING); 1.129 + 1.130 + glBegin(GL_TRIANGLES); 1.131 + glColor3f(0, 1, 0); 1.132 + glVertex3fv(&dbg_walk_face.v[0].x); 1.133 + glVertex3fv(&dbg_walk_face.v[1].x); 1.134 + glVertex3fv(&dbg_walk_face.v[2].x); 1.135 + glColor3f(1, 1, 1); 1.136 + glEnd(); 1.137 + 1.138 + glPopAttrib(); 1.139 } 1.140 1.141 static void material(float r, float g, float b, float roughness) 1.142 @@ -392,6 +427,11 @@ 1.143 1.144 static void con_handle(const char *cmd) 1.145 { 1.146 + /* set debug values */ 1.147 + set_gvar_num("cam-pos-x", cam_pos[0]); 1.148 + set_gvar_num("cam-pos-y", cam_pos[1]); 1.149 + set_gvar_num("cam-pos-z", cam_pos[2]); 1.150 + 1.151 std::vector<char*> argv; 1.152 cmd = strip_spaces(cmd); 1.153
2.1 --- a/src/game_var.cc Wed Oct 01 01:06:55 2014 +0300 2.2 +++ b/src/game_var.cc Fri Oct 03 04:16:16 2014 +0300 2.3 @@ -1,3 +1,4 @@ 2.4 +#include <string.h> 2.5 #include <map> 2.6 #include "game_var.h" 2.7 2.8 @@ -138,4 +139,4 @@ 2.9 res.push_back((it++)->first); 2.10 } 2.11 return res; 2.12 -} 2.13 \ No newline at end of file 2.14 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/material.cc Fri Oct 03 04:16:16 2014 +0300 3.3 @@ -0,0 +1,27 @@ 3.4 +#include "material.h" 3.5 +#include "opengl.h" 3.6 + 3.7 +Material::Material() 3.8 + : diffuse(1, 1, 1) 3.9 +{ 3.10 + alpha = 1.0; 3.11 + shininess = 60.0; 3.12 + tex = 0; 3.13 +} 3.14 + 3.15 +void Material::setup() const 3.16 +{ 3.17 + float diff[] = {diffuse.x, diffuse.y, diffuse.z, alpha}; 3.18 + float spec[] = {specular.x, specular.y, specular.z, 1.0}; 3.19 + 3.20 + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, diff); 3.21 + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec); 3.22 + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess > 128.0f ? 128.0f : shininess); 3.23 + 3.24 + if(tex) { 3.25 + glEnable(GL_TEXTURE_2D); 3.26 + glBindTexture(GL_TEXTURE_2D, tex); 3.27 + } else { 3.28 + glDisable(GL_TEXTURE_2D); 3.29 + } 3.30 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/material.h Fri Oct 03 04:16:16 2014 +0300 4.3 @@ -0,0 +1,19 @@ 4.4 +#ifndef MATERIAL_H_ 4.5 +#define MATERIAL_H_ 4.6 + 4.7 +#include <vmath/vmath.h> 4.8 + 4.9 +class Material { 4.10 +public: 4.11 + Vector3 diffuse, specular; 4.12 + float shininess; 4.13 + float alpha; 4.14 + 4.15 + unsigned int tex; 4.16 + 4.17 + Material(); 4.18 + 4.19 + void setup() const; 4.20 +}; 4.21 + 4.22 +#endif // MATERIAL_H_
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/src/mesh.cc Fri Oct 03 04:16:16 2014 +0300 5.3 @@ -0,0 +1,328 @@ 5.4 +#include <string.h> 5.5 +#include "mesh.h" 5.6 +#include "opengl.h" 5.7 + 5.8 +Mesh::Mesh() 5.9 +{ 5.10 + set_primitive(GL_TRIANGLES); 5.11 + 5.12 + for(int i=0; i<NUM_MESH_ATTRIBS; i++) { 5.13 + attrib[i].nelems = 3; 5.14 + attrib[i].sdrloc = -1; 5.15 + attrib[i].vbo = 0; 5.16 + attrib[i].vbo_valid = false; 5.17 + } 5.18 + num_verts = 0; 5.19 + 5.20 + num_idx = 0; 5.21 + ibo = 0; 5.22 + ibo_size = 0; 5.23 + ibo_valid = false; 5.24 + 5.25 + vbo_usage = ibo_usage = GL_STATIC_DRAW; 5.26 +} 5.27 + 5.28 +Mesh::~Mesh() 5.29 +{ 5.30 + clear(); 5.31 + 5.32 + for(int i=0; i<NUM_MESH_ATTRIBS; i++) { 5.33 + if(attrib[i].vbo) { 5.34 + glDeleteBuffers(1, &attrib[i].vbo); 5.35 + } 5.36 + } 5.37 + if(ibo) { 5.38 + glDeleteBuffers(1, &ibo); 5.39 + } 5.40 +} 5.41 + 5.42 +void Mesh::clear() 5.43 +{ 5.44 + for(int i=0; i<NUM_MESH_ATTRIBS; i++) { 5.45 + attrib[i].vbo_valid = false; 5.46 + attrib[i].data.clear(); 5.47 + 5.48 + } 5.49 + ibo_valid = false; 5.50 + index.clear(); 5.51 +} 5.52 + 5.53 +void Mesh::set_primitive(int prim) 5.54 +{ 5.55 + if(prim == -1) { 5.56 + this->prim = GL_TRIANGLES; 5.57 + } else { 5.58 + this->prim = prim; 5.59 + } 5.60 + 5.61 + switch(this->prim) { 5.62 + case GL_TRIANGLES: 5.63 + prim_verts = 3; 5.64 + break; 5.65 + 5.66 + case GL_QUADS: 5.67 + prim_verts = 4; 5.68 + break; 5.69 + 5.70 + case GL_LINES: 5.71 + prim_verts = 2; 5.72 + break; 5.73 + 5.74 + case GL_POINTS: 5.75 + prim_verts = 1; 5.76 + break; 5.77 + 5.78 + default: 5.79 + break; 5.80 + } 5.81 +} 5.82 + 5.83 +void Mesh::set_attrib_location(int attr, int loc) 5.84 +{ 5.85 + attrib[attr].sdrloc = loc; 5.86 +} 5.87 + 5.88 +float *Mesh::set_vertex_data(int attr, int nelem, int count, float *data) 5.89 +{ 5.90 + attrib[attr].data.resize(count * nelem); 5.91 + if(data) { 5.92 + memcpy(&attrib[attr].data[0], data, nelem * count * sizeof(float)); 5.93 + } 5.94 + 5.95 + attrib[attr].nelems = nelem; 5.96 + attrib[attr].vbo_valid = false; 5.97 + 5.98 + num_verts = count; 5.99 + 5.100 + return &attrib[attr].data[0]; 5.101 +} 5.102 + 5.103 +unsigned int *Mesh::set_index_data(int count, unsigned int *data) 5.104 +{ 5.105 + index.resize(count); 5.106 + if(data) { 5.107 + memcpy(&index[0], data, count * sizeof(unsigned int)); 5.108 + } 5.109 + 5.110 + num_idx = count; 5.111 + ibo_valid = false; 5.112 + 5.113 + return &index[0]; 5.114 +} 5.115 + 5.116 +int Mesh::get_vertex_count() const 5.117 +{ 5.118 + return num_verts; 5.119 +} 5.120 + 5.121 +float *Mesh::get_vertex_data(int attr) 5.122 +{ 5.123 + if(attrib[attr].data.empty()) { 5.124 + return 0; 5.125 + } 5.126 + return &attrib[attr].data[0]; 5.127 +} 5.128 + 5.129 +const float *Mesh::get_vertex_data(int attr) const 5.130 +{ 5.131 + if(attrib[attr].data.empty()) { 5.132 + return 0; 5.133 + } 5.134 + return &attrib[attr].data[0]; 5.135 +} 5.136 + 5.137 +int Mesh::get_index_count() const 5.138 +{ 5.139 + return num_idx; 5.140 +} 5.141 + 5.142 +unsigned int *Mesh::get_index_data() 5.143 +{ 5.144 + if(index.empty()) { 5.145 + return 0; 5.146 + } 5.147 + return &index[0]; 5.148 +} 5.149 + 5.150 +const unsigned int *Mesh::get_index_data() const 5.151 +{ 5.152 + if(index.empty()) { 5.153 + return 0; 5.154 + } 5.155 + return &index[0]; 5.156 +} 5.157 + 5.158 +int Mesh::get_face_count() const 5.159 +{ 5.160 + if(index.empty()) { 5.161 + return get_vertex_count() / prim_verts; 5.162 + } 5.163 + return get_index_count() / prim_verts; 5.164 +} 5.165 + 5.166 +MeshFace Mesh::get_face(int idx) const 5.167 +{ 5.168 + MeshFace face; 5.169 + face.vcount = prim_verts; 5.170 + 5.171 + int nfaces = get_face_count(); 5.172 + if(idx < 0 || idx >= nfaces) { 5.173 + return face; 5.174 + } 5.175 + 5.176 + const Vector3 *verts = (const Vector3*)&attrib[MESH_VERTEX].data[0]; 5.177 + 5.178 + if(index.empty()) { 5.179 + for(int i=0; i<3; i++) { 5.180 + face.v[i] = verts[idx * 3 + i]; 5.181 + } 5.182 + 5.183 + } else { 5.184 + for(int i=0; i<3; i++) { 5.185 + int vidx = index[idx * 3 + i]; 5.186 + face.v[i] = verts[vidx]; 5.187 + } 5.188 + } 5.189 + 5.190 + return face; 5.191 +} 5.192 + 5.193 + 5.194 +void Mesh::begin(int prim) 5.195 +{ 5.196 + if(prim == -1) { 5.197 + this->prim = GL_TRIANGLES; 5.198 + } else { 5.199 + this->prim = prim; 5.200 + } 5.201 + 5.202 + clear(); 5.203 + 5.204 + cur_norm_valid = false; 5.205 + cur_tc_valid = false; 5.206 + cur_tang_valid = false; 5.207 +} 5.208 + 5.209 +void Mesh::end() 5.210 +{ 5.211 +} 5.212 + 5.213 +void Mesh::vertex(float x, float y, float z) 5.214 +{ 5.215 + if(cur_norm_valid) { 5.216 + attrib[MESH_NORMAL].data.push_back(cur_norm.x); 5.217 + attrib[MESH_NORMAL].data.push_back(cur_norm.y); 5.218 + attrib[MESH_NORMAL].data.push_back(cur_norm.z); 5.219 + } 5.220 + if(cur_tc_valid) { 5.221 + attrib[MESH_TEXCOORD].data.push_back(cur_tc.x); 5.222 + attrib[MESH_TEXCOORD].data.push_back(cur_tc.y); 5.223 + } 5.224 + if(cur_tang_valid) { 5.225 + attrib[MESH_TANGENT].data.push_back(cur_tang.x); 5.226 + attrib[MESH_TANGENT].data.push_back(cur_tang.y); 5.227 + attrib[MESH_TANGENT].data.push_back(cur_tang.z); 5.228 + } 5.229 + attrib[MESH_VERTEX].data.push_back(x); 5.230 + attrib[MESH_VERTEX].data.push_back(y); 5.231 + attrib[MESH_VERTEX].data.push_back(z); 5.232 +} 5.233 + 5.234 +void Mesh::normal(float x, float y, float z) 5.235 +{ 5.236 + cur_norm = Vector3(x, y, z); 5.237 + cur_norm_valid = true; 5.238 +} 5.239 + 5.240 +void Mesh::texcoord(float x, float y) 5.241 +{ 5.242 + cur_tc = Vector2(x, y); 5.243 + cur_tc_valid = true; 5.244 +} 5.245 + 5.246 +void Mesh::tangent(float x, float y, float z) 5.247 +{ 5.248 + cur_tang = Vector3(x, y, z); 5.249 + cur_tang_valid = true; 5.250 +} 5.251 + 5.252 +void Mesh::draw() const 5.253 +{ 5.254 + if(attrib[MESH_VERTEX].data.empty()) { 5.255 + return; 5.256 + } 5.257 + 5.258 + bool use_norm = !attrib[MESH_NORMAL].data.empty(); 5.259 + bool use_tc = !attrib[MESH_TEXCOORD].data.empty(); 5.260 + bool use_tang = !attrib[MESH_TANGENT].data.empty(); 5.261 + int norm_loc, tc_loc, tang_loc; 5.262 + 5.263 + const float *ptr = &attrib[MESH_VERTEX].data[0]; 5.264 + int loc = attrib[MESH_VERTEX].sdrloc; 5.265 + if(loc == -1) { 5.266 + glEnableClientState(GL_VERTEX_ARRAY); 5.267 + glVertexPointer(attrib[MESH_VERTEX].nelems, GL_FLOAT, 0, ptr); 5.268 + } else { 5.269 + glEnableVertexAttribArray(loc); 5.270 + glVertexAttribPointer(loc, attrib[MESH_VERTEX].nelems, GL_FLOAT, 0, 0, ptr); 5.271 + } 5.272 + 5.273 + if(use_norm) { 5.274 + const float *ptr = &attrib[MESH_NORMAL].data[0]; 5.275 + norm_loc = attrib[MESH_NORMAL].sdrloc; 5.276 + if(norm_loc == -1) { 5.277 + glEnableClientState(GL_NORMAL_ARRAY); 5.278 + glNormalPointer(GL_FLOAT, 0, ptr); 5.279 + } else { 5.280 + glEnableVertexAttribArray(norm_loc); 5.281 + glVertexAttribPointer(norm_loc, attrib[MESH_NORMAL].nelems, GL_FLOAT, 0, 0, ptr); 5.282 + } 5.283 + } 5.284 + 5.285 + if(use_tc) { 5.286 + const float *ptr = &attrib[MESH_TEXCOORD].data[0]; 5.287 + tc_loc = attrib[MESH_TEXCOORD].sdrloc; 5.288 + if(tc_loc == -1) { 5.289 + glEnableClientState(GL_TEXTURE_COORD_ARRAY); 5.290 + glTexCoordPointer(attrib[MESH_TEXCOORD].nelems, GL_FLOAT, 0, ptr); 5.291 + } else { 5.292 + glEnableVertexAttribArray(tc_loc); 5.293 + glVertexAttribPointer(tc_loc, attrib[MESH_TEXCOORD].nelems, GL_FLOAT, 0, 0, ptr); 5.294 + } 5.295 + } 5.296 + 5.297 + if(!attrib[MESH_TANGENT].data.empty()) { 5.298 + const float *ptr = &attrib[MESH_TANGENT].data[0]; 5.299 + tang_loc = attrib[MESH_TANGENT].sdrloc; 5.300 + if(tang_loc != -1) { 5.301 + glEnableVertexAttribArray(tang_loc); 5.302 + glVertexAttribPointer(tang_loc, attrib[MESH_TANGENT].nelems, GL_FLOAT, 0, 0, ptr); 5.303 + } 5.304 + } 5.305 + 5.306 + if(!index.empty()) { 5.307 + glDrawElements(prim, num_idx, GL_UNSIGNED_INT, &index[0]); 5.308 + } else { 5.309 + glDrawArrays(prim, 0, num_verts * 3); 5.310 + } 5.311 + 5.312 + if(use_norm) { 5.313 + if(norm_loc == -1) { 5.314 + glDisableClientState(GL_NORMAL_ARRAY); 5.315 + } else { 5.316 + glDisableVertexAttribArray(norm_loc); 5.317 + } 5.318 + } 5.319 + if(use_tc) { 5.320 + if(tc_loc == -1) { 5.321 + glDisableClientState(GL_TEXTURE_COORD_ARRAY); 5.322 + } else { 5.323 + glDisableVertexAttribArray(tc_loc); 5.324 + } 5.325 + } 5.326 + if(use_tang) { 5.327 + if(tang_loc != -1) { 5.328 + glDisableVertexAttribArray(tang_loc); 5.329 + } 5.330 + } 5.331 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/src/mesh.h Fri Oct 03 04:16:16 2014 +0300 6.3 @@ -0,0 +1,83 @@ 6.4 +#ifndef MESH_H_ 6.5 +#define MESH_H_ 6.6 + 6.7 +#include <vector> 6.8 +#include <vmath/vmath.h> 6.9 + 6.10 +enum MeshAttrib { 6.11 + MESH_VERTEX, 6.12 + MESH_NORMAL, 6.13 + MESH_TEXCOORD, 6.14 + MESH_TANGENT, 6.15 + 6.16 + NUM_MESH_ATTRIBS 6.17 +}; 6.18 + 6.19 +struct MeshAttribData { 6.20 + std::vector<float> data; 6.21 + int nelems; 6.22 + int sdrloc; 6.23 + 6.24 + int vbo_size; 6.25 + unsigned int vbo; 6.26 + bool vbo_valid; 6.27 +}; 6.28 + 6.29 +struct MeshFace { 6.30 + int vcount; 6.31 + Vector3 v[4]; 6.32 +}; 6.33 + 6.34 +class Mesh { 6.35 +private: 6.36 + int prim, prim_verts; 6.37 + MeshAttribData attrib[NUM_MESH_ATTRIBS]; 6.38 + int num_verts; 6.39 + 6.40 + std::vector<unsigned int> index; 6.41 + int num_idx; 6.42 + unsigned int ibo; 6.43 + int ibo_size; 6.44 + bool ibo_valid; 6.45 + 6.46 + unsigned int vbo_usage, ibo_usage; 6.47 + 6.48 + Vector3 cur_norm, cur_tang; 6.49 + Vector2 cur_tc; 6.50 + bool cur_norm_valid, cur_tc_valid, cur_tang_valid; 6.51 + 6.52 +public: 6.53 + Mesh(); 6.54 + ~Mesh(); 6.55 + 6.56 + void clear(); 6.57 + 6.58 + void set_primitive(int prim = -1); 6.59 + void set_attrib_location(int attr, int loc); 6.60 + 6.61 + float *set_vertex_data(int attr, int nelem, int count, float *data = 0); 6.62 + unsigned int *set_index_data(int count, unsigned int *data = 0); 6.63 + 6.64 + int get_vertex_count() const; 6.65 + float *get_vertex_data(int attr); 6.66 + const float *get_vertex_data(int attr) const; 6.67 + 6.68 + int get_index_count() const; 6.69 + unsigned int *get_index_data(); 6.70 + const unsigned int *get_index_data() const; 6.71 + 6.72 + int get_face_count() const; 6.73 + MeshFace get_face(int idx) const; 6.74 + 6.75 + void begin(int prim = -1); 6.76 + void end(); 6.77 + 6.78 + void vertex(float x, float y, float z); 6.79 + void normal(float x, float y, float z); 6.80 + void texcoord(float x, float y); 6.81 + void tangent(float x, float y, float z); 6.82 + 6.83 + void draw() const; 6.84 +}; 6.85 + 6.86 +#endif // MESH_H_
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/src/object.cc Fri Oct 03 04:16:16 2014 +0300 7.3 @@ -0,0 +1,26 @@ 7.4 +#include "object.h" 7.5 +#include "opengl.h" 7.6 + 7.7 +Object::Object() 7.8 +{ 7.9 + mesh = 0; 7.10 +} 7.11 + 7.12 +void Object::set_mesh(Mesh *m) 7.13 +{ 7.14 + mesh = m; 7.15 +} 7.16 + 7.17 +void Object::draw() const 7.18 +{ 7.19 + if(!mesh) return; 7.20 + 7.21 + glMatrixMode(GL_MODELVIEW); 7.22 + glPushMatrix(); 7.23 + glMultTransposeMatrixf(xform[0]); 7.24 + 7.25 + mtl.setup(); 7.26 + mesh->draw(); 7.27 + 7.28 + glPopMatrix(); 7.29 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/object.h Fri Oct 03 04:16:16 2014 +0300 8.3 @@ -0,0 +1,23 @@ 8.4 +#ifndef OBJECT_H_ 8.5 +#define OBJECT_H_ 8.6 + 8.7 +#include <vmath/vmath.h> 8.8 +#include "mesh.h" 8.9 +#include "material.h" 8.10 + 8.11 +class Object { 8.12 +private: 8.13 + Mesh *mesh; 8.14 + 8.15 +public: 8.16 + Material mtl; 8.17 + Matrix4x4 xform; 8.18 + 8.19 + Object(); 8.20 + 8.21 + void set_mesh(Mesh *m); 8.22 + 8.23 + void draw() const; 8.24 +}; 8.25 + 8.26 +#endif /* OBJECT_H_ */
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/src/scenefile.cc Fri Oct 03 04:16:16 2014 +0300 9.3 @@ -0,0 +1,165 @@ 9.4 +#include <float.h> 9.5 +#include <assert.h> 9.6 +#include <string> 9.7 +#include <map> 9.8 +#include "scenefile.h" 9.9 +#include "goat3d.h" 9.10 +#include "texman.h" 9.11 + 9.12 +SceneFile::SceneFile() 9.13 +{ 9.14 +} 9.15 + 9.16 +SceneFile::~SceneFile() 9.17 +{ 9.18 +} 9.19 + 9.20 +bool SceneFile::load(const char *fname) 9.21 +{ 9.22 + std::map<struct goat3d_mesh*, Mesh*> meshmap; 9.23 + 9.24 + struct goat3d *g3d = goat3d_create(); 9.25 + if(!g3d) return false; 9.26 + 9.27 + if(goat3d_load(g3d, fname) == -1) { 9.28 + return false; 9.29 + } 9.30 + 9.31 + int nmeshes = goat3d_get_mesh_count(g3d); 9.32 + for(int i=0; i<nmeshes; i++) { 9.33 + struct goat3d_mesh *gm = goat3d_get_mesh(g3d, i); 9.34 + int nverts = goat3d_get_mesh_attrib_count(gm, GOAT3D_MESH_ATTR_VERTEX); 9.35 + 9.36 + Mesh *m = new Mesh; 9.37 + m->set_vertex_data(MESH_VERTEX, 3, nverts, (float*)goat3d_get_mesh_attribs(gm, GOAT3D_MESH_ATTR_VERTEX)); 9.38 + 9.39 + int nnorm = goat3d_get_mesh_attrib_count(gm, GOAT3D_MESH_ATTR_NORMAL); 9.40 + if(nnorm) { 9.41 + assert(nnorm == nverts); 9.42 + m->set_vertex_data(MESH_NORMAL, 3, nnorm, (float*)goat3d_get_mesh_attribs(gm, GOAT3D_MESH_ATTR_NORMAL)); 9.43 + } 9.44 + 9.45 + int ntex = goat3d_get_mesh_attrib_count(gm, GOAT3D_MESH_ATTR_TEXCOORD); 9.46 + if(ntex) { 9.47 + assert(ntex == nverts); 9.48 + m->set_vertex_data(MESH_TEXCOORD, 2, ntex, (float*)goat3d_get_mesh_attribs(gm, GOAT3D_MESH_ATTR_TEXCOORD)); 9.49 + } 9.50 + 9.51 + int ntang = goat3d_get_mesh_attrib_count(gm, GOAT3D_MESH_ATTR_TANGENT); 9.52 + if(ntang) { 9.53 + assert(ntang == nverts); 9.54 + m->set_vertex_data(MESH_TANGENT, 3, ntang, (float*)goat3d_get_mesh_attribs(gm, GOAT3D_MESH_ATTR_TANGENT)); 9.55 + } 9.56 + 9.57 + int nfaces = goat3d_get_mesh_face_count(gm); 9.58 + if(nfaces) { 9.59 + m->set_index_data(nfaces * 3, (unsigned int*)goat3d_get_mesh_faces(gm)); 9.60 + } 9.61 + 9.62 + mesh.push_back(m); 9.63 + meshmap[gm] = m; 9.64 + // TODO: do this after nodes are loaded per object to pre-transform if applicable 9.65 + colmesh.push_back(m); 9.66 + } 9.67 + 9.68 + /* iterate the nodes and create objects */ 9.69 + int nnodes = goat3d_get_node_count(g3d); 9.70 + for(int i=0; i<nnodes; i++) { 9.71 + struct goat3d_node *gn = goat3d_get_node(g3d, i); 9.72 + if(goat3d_get_node_type(gn) != GOAT3D_NODE_MESH) { 9.73 + continue; 9.74 + } 9.75 + struct goat3d_mesh *gm = (struct goat3d_mesh*)goat3d_get_node_object(gn); 9.76 + if(!gm) continue; 9.77 + Mesh *m = meshmap[gm]; 9.78 + if(!m) continue; 9.79 + 9.80 + Object *obj = new Object; 9.81 + obj->set_mesh(m); 9.82 + 9.83 + float mat[16]; 9.84 + goat3d_get_node_matrix(gn, mat, 0); 9.85 + for(int i=0; i<4; i++) { 9.86 + for(int j=0; j<4; j++) { 9.87 + obj->xform[i][j] = mat[i * 4 + j]; 9.88 + } 9.89 + } 9.90 + 9.91 + struct goat3d_material *gmtl = goat3d_get_mesh_mtl(gm); 9.92 + const float *col = goat3d_get_mtl_attrib(gmtl, GOAT3D_MAT_ATTR_DIFFUSE); 9.93 + if(col) { 9.94 + obj->mtl.diffuse = Vector3(col[0], col[1], col[2]); 9.95 + } 9.96 + if((col = goat3d_get_mtl_attrib(gmtl, GOAT3D_MAT_ATTR_SPECULAR))) { 9.97 + obj->mtl.specular = Vector3(col[0], col[1], col[2]); 9.98 + } 9.99 + if((col = goat3d_get_mtl_attrib(gmtl, GOAT3D_MAT_ATTR_ALPHA))) { 9.100 + obj->mtl.alpha = col[0]; 9.101 + } 9.102 + if((col = goat3d_get_mtl_attrib(gmtl, GOAT3D_MAT_ATTR_SHININESS))) { 9.103 + obj->mtl.shininess = col[0]; 9.104 + } 9.105 + const char *fname = goat3d_get_mtl_attrib_map(gmtl, GOAT3D_MAT_ATTR_DIFFUSE); 9.106 + if(fname) { 9.107 + obj->mtl.tex = get_texture(fname); 9.108 + } 9.109 + 9.110 + this->obj.push_back(obj); 9.111 + } 9.112 + 9.113 + goat3d_free(g3d); 9.114 + return true; 9.115 +} 9.116 + 9.117 +static Vector3 bary(const Vector3 &a, const Vector3 &b, const Vector3 &c, 9.118 + const Vector3 &p) 9.119 +{ 9.120 + float ctri = cross_product(b - a, c - a).length(); 9.121 + if(ctri == 0.0f) { 9.122 + return Vector3(2, 0, 0); 9.123 + } 9.124 + 9.125 + float ca = cross_product(b - p, c - p).length() / ctri; 9.126 + float cb = cross_product(a - p, c - p).length() / ctri; 9.127 + float cc = cross_product(a - p, b - p).length() / ctri; 9.128 + 9.129 + return Vector3(ca, cb, cc); 9.130 +} 9.131 + 9.132 +extern MeshFace dbg_walk_face; 9.133 + 9.134 +Vector3 SceneFile::find_walk_pos(const Vector3 &pos) const 9.135 +{ 9.136 + float max_y = -FLT_MAX; 9.137 + Vector3 pos_xz = Vector3(pos.x, 0, pos.z); 9.138 + 9.139 + for(size_t i=0; i<colmesh.size(); i++) { 9.140 + const Mesh *m = colmesh[i]; 9.141 + 9.142 + int num_faces = m->get_face_count(); 9.143 + for(int j=0; j<num_faces; j++) { 9.144 + MeshFace face = m->get_face(j); 9.145 + 9.146 + Vector3 v0_xz = Vector3(face.v[0].x, 0, face.v[0].z); 9.147 + Vector3 v1_xz = Vector3(face.v[1].x, 0, face.v[1].z); 9.148 + Vector3 v2_xz = Vector3(face.v[2].x, 0, face.v[2].z); 9.149 + 9.150 + Vector3 bc = bary(v0_xz, v1_xz, v2_xz, pos_xz); 9.151 + float bsum = bc.x + bc.y + bc.z; 9.152 + if(bsum > 1.000001) { 9.153 + continue; 9.154 + } 9.155 + 9.156 + float y = face.v[0].y * bc.x + face.v[1].y * bc.y + face.v[2].y * bc.z; 9.157 + if(y > max_y && y <= pos.y) { 9.158 + dbg_walk_face = face; 9.159 + max_y = y; 9.160 + } 9.161 + } 9.162 + } 9.163 + 9.164 + if(max_y == -FLT_MAX) { 9.165 + return pos; 9.166 + } 9.167 + return Vector3(pos.x, max_y, pos.z); 9.168 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/src/scenefile.h Fri Oct 03 04:16:16 2014 +0300 10.3 @@ -0,0 +1,22 @@ 10.4 +#ifndef SCENEFILE_H_ 10.5 +#define SCENEFILE_H_ 10.6 + 10.7 +#include <vector> 10.8 +#include "mesh.h" 10.9 +#include "object.h" 10.10 + 10.11 +class SceneFile { 10.12 +public: 10.13 + std::vector<Mesh*> mesh; 10.14 + std::vector<Mesh*> colmesh; 10.15 + std::vector<Object*> obj; 10.16 + 10.17 + SceneFile(); 10.18 + ~SceneFile(); 10.19 + 10.20 + bool load(const char *fname); 10.21 + 10.22 + Vector3 find_walk_pos(const Vector3 &pos) const; 10.23 +}; 10.24 + 10.25 +#endif // SCENEFILE_H_
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/src/texman.cc Fri Oct 03 04:16:16 2014 +0300 11.3 @@ -0,0 +1,51 @@ 11.4 +#include <stdio.h> 11.5 +#include <string> 11.6 +#include <map> 11.7 +#include <imago2.h> 11.8 +#include "opengl.h" 11.9 +#include "texman.h" 11.10 + 11.11 +static std::string find_datafile(const std::string &fname); 11.12 + 11.13 +static std::map<std::string, unsigned int> textures; 11.14 +static const char *paths[] = { 11.15 + "data", 11.16 + 0 11.17 +}; 11.18 + 11.19 +unsigned int get_texture(const char *fname) 11.20 +{ 11.21 + unsigned int tex; 11.22 + 11.23 + if(!fname || !*fname) { 11.24 + return 0; 11.25 + } 11.26 + 11.27 + std::map<std::string, unsigned int>::const_iterator it = textures.find(fname); 11.28 + if(it != textures.end()) { 11.29 + tex = it->second; 11.30 + } else { 11.31 + if(!(tex = img_gltexture_load(find_datafile(fname).c_str()))) { 11.32 + fprintf(stderr, "failed to load image: %s\n", fname); 11.33 + } else { 11.34 + textures[fname] = tex; 11.35 + } 11.36 + } 11.37 + 11.38 + return tex; 11.39 +} 11.40 + 11.41 +static std::string find_datafile(const std::string &fname) 11.42 +{ 11.43 + FILE *fp; 11.44 + 11.45 + for(int i=0; paths[i]; i++) { 11.46 + std::string path = paths[i] + std::string("/") + fname; 11.47 + if((fp = fopen(path.c_str(), "rb"))) { 11.48 + fclose(fp); 11.49 + return path; 11.50 + } 11.51 + } 11.52 + 11.53 + return fname; 11.54 +}