tavli
changeset 1:3fcd7b4d631f
board mesh generation
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 22 Jun 2015 05:05:37 +0300 |
parents | 52e0dd47753b |
children | 893192aea099 |
files | Makefile src/board.cc src/board.h src/game.cc src/mesh.cc src/meshgen.cc src/meshgen.h src/object.cc src/object.h |
diffstat | 9 files changed, 676 insertions(+), 33 deletions(-) [+] |
line diff
1.1 --- a/Makefile Sun Jun 21 06:30:39 2015 +0300 1.2 +++ b/Makefile Mon Jun 22 05:05:37 2015 +0300 1.3 @@ -6,7 +6,7 @@ 1.4 bin = tavli 1.5 1.6 CXXFLAGS = -pedantic -Wall -g 1.7 -LDFLAGS = $(libgl) 1.8 +LDFLAGS = $(libgl) -lvmath -limago -lm -lpthread 1.9 1.10 ifeq ($(shell uname -s), Darwin) 1.11 libgl = -framework OpenGL -framework GLUT -lGLEW
2.1 --- a/src/board.cc Sun Jun 21 06:30:39 2015 +0300 2.2 +++ b/src/board.cc Mon Jun 22 05:05:37 2015 +0300 2.3 @@ -1,11 +1,11 @@ 2.4 #include "opengl.h" 2.5 #include "board.h" 2.6 +#include "meshgen.h" 2.7 2.8 -static Mesh *gen_board_mesh(); 2.9 -static Mesh *gen_puck_mesh(); 2.10 2.11 Board::Board() 2.12 { 2.13 + puck_mesh = 0; 2.14 clear(); 2.15 } 2.16 2.17 @@ -16,20 +16,22 @@ 2.18 2.19 bool Board::init() 2.20 { 2.21 - if(!(board_mesh = gen_board_mesh())) { 2.22 + if(!generate()) { 2.23 return false; 2.24 } 2.25 - if(!(puck_mesh = gen_puck_mesh())) { 2.26 - return false; 2.27 - } 2.28 + 2.29 return true; 2.30 } 2.31 2.32 void Board::destroy() 2.33 { 2.34 - delete board_mesh; 2.35 + for(size_t i=0; i<board_meshes.size(); i++) { 2.36 + delete board_meshes[i]; 2.37 + } 2.38 + board_meshes.clear(); 2.39 + 2.40 delete puck_mesh; 2.41 - board_mesh = puck_mesh = 0; 2.42 + puck_mesh = 0; 2.43 } 2.44 2.45 void Board::clear() 2.46 @@ -39,16 +41,77 @@ 2.47 2.48 void Board::draw() const 2.49 { 2.50 - if(board_mesh) 2.51 - board_mesh->draw(); 2.52 + for(size_t i=0; i<board_meshes.size(); i++) { 2.53 + board_meshes[i]->draw(); 2.54 + } 2.55 } 2.56 2.57 -static Mesh *gen_board_mesh() 2.58 +#define HSIZE 1.0 2.59 +#define VSIZE (2.0 * HSIZE) 2.60 +#define BOT_THICKNESS (HSIZE * 0.01) 2.61 +#define WALL_THICKNESS (HSIZE * 0.05) 2.62 +#define WALL_HEIGHT (HSIZE * 0.1) 2.63 +#define GAP (HSIZE * 0.025) 2.64 +#define HINGE_RAD (GAP * 0.5) 2.65 +#define HINGE_HEIGHT (VSIZE * 0.075) 2.66 + 2.67 +bool Board::generate() 2.68 { 2.69 - return 0; 2.70 + Matrix4x4 xform; 2.71 + 2.72 + // generate bottom 2.73 + Mesh *bottom = new Mesh; 2.74 + gen_box(bottom, HSIZE, BOT_THICKNESS, HSIZE * 2.0); 2.75 + xform.set_translation(Vector3(0, -BOT_THICKNESS / 2.0, 0)); 2.76 + bottom->apply_xform(xform); 2.77 + 2.78 + // generate the 4 sides 2.79 + Mesh *sides = new Mesh; 2.80 + gen_box(sides, WALL_THICKNESS, WALL_HEIGHT, VSIZE + WALL_THICKNESS * 2); 2.81 + xform.set_translation(Vector3(-(HSIZE + WALL_THICKNESS) / 2.0, 2.82 + WALL_HEIGHT / 2.0 - BOT_THICKNESS, 0)); 2.83 + sides->apply_xform(xform); 2.84 + 2.85 + Mesh tmp; 2.86 + gen_box(&tmp, WALL_THICKNESS, WALL_HEIGHT, VSIZE + WALL_THICKNESS * 2); 2.87 + xform.set_translation(Vector3((HSIZE + WALL_THICKNESS) / 2.0, 2.88 + WALL_HEIGHT / 2.0 - BOT_THICKNESS, 0)); 2.89 + tmp.apply_xform(xform); 2.90 + sides->append(tmp); 2.91 + tmp.clear(); 2.92 + 2.93 + gen_box(&tmp, HSIZE, WALL_HEIGHT, WALL_THICKNESS); 2.94 + xform.set_translation(Vector3(0, WALL_HEIGHT / 2.0 - BOT_THICKNESS, 2.95 + (VSIZE + WALL_THICKNESS) / 2.0)); 2.96 + tmp.apply_xform(xform); 2.97 + sides->append(tmp); 2.98 + tmp.clear(); 2.99 + 2.100 + gen_box(&tmp, HSIZE, WALL_HEIGHT, WALL_THICKNESS); 2.101 + xform.set_translation(Vector3(0, WALL_HEIGHT / 2.0 - BOT_THICKNESS, 2.102 + -(VSIZE + WALL_THICKNESS) / 2.0)); 2.103 + tmp.apply_xform(xform); 2.104 + sides->append(tmp); 2.105 + tmp.clear(); 2.106 + 2.107 + // generate the hinges 2.108 + Mesh *hinges = new Mesh; 2.109 + gen_cylinder(hinges, HINGE_RAD, HINGE_HEIGHT, 10, 1, 1); 2.110 + xform.set_rotation(Vector3(M_PI / 2.0, 0, 0)); 2.111 + xform.translate(Vector3(0, VSIZE / 4.0, 0)); 2.112 + hinges->apply_xform(xform); 2.113 + 2.114 + gen_cylinder(&tmp, HINGE_RAD, HINGE_HEIGHT, 10, 1, 1); 2.115 + xform.set_rotation(Vector3(M_PI / 2.0, 0, 0)); 2.116 + xform.translate(Vector3(0, -VSIZE / 4.0, 0)); 2.117 + tmp.apply_xform(xform); 2.118 + 2.119 + hinges->append(tmp); 2.120 + 2.121 + 2.122 + board_meshes.clear(); 2.123 + board_meshes.push_back(bottom); 2.124 + board_meshes.push_back(sides); 2.125 + board_meshes.push_back(hinges); 2.126 + return true; 2.127 } 2.128 - 2.129 -static Mesh *gen_puck_mesh() 2.130 -{ 2.131 - return 0; 2.132 -}
3.1 --- a/src/board.h Sun Jun 21 06:30:39 2015 +0300 3.2 +++ b/src/board.h Mon Jun 22 05:05:37 2015 +0300 3.3 @@ -1,6 +1,7 @@ 3.4 #ifndef BOARD_H_ 3.5 #define BOARD_H_ 3.6 3.7 +#include <vector> 3.8 #include "mesh.h" 3.9 3.10 #define NUM_SLOTS 24 3.11 @@ -11,7 +12,10 @@ 3.12 class Board { 3.13 private: 3.14 int slots[NUM_SLOTS][MAX_PUCKS]; 3.15 - Mesh *board_mesh, *puck_mesh; 3.16 + std::vector<Mesh*> board_meshes; 3.17 + Mesh *puck_mesh; 3.18 + 3.19 + bool generate(); 3.20 3.21 public: 3.22 Board();
4.1 --- a/src/game.cc Sun Jun 21 06:30:39 2015 +0300 4.2 +++ b/src/game.cc Mon Jun 22 05:05:37 2015 +0300 4.3 @@ -1,11 +1,14 @@ 4.4 #include <stdio.h> 4.5 #include <GL/glew.h> 4.6 #include "game.h" 4.7 +#include "board.h" 4.8 4.9 static void draw_backdrop(); 4.10 4.11 int win_width, win_height; 4.12 4.13 +static Board board; 4.14 + 4.15 static float cam_theta, cam_phi = 25, cam_dist = 6; 4.16 static bool bnstate[8]; 4.17 static int prev_x, prev_y; 4.18 @@ -19,11 +22,16 @@ 4.19 glEnable(GL_LIGHTING); 4.20 glEnable(GL_LIGHT0); 4.21 4.22 + if(!board.init()) { 4.23 + return false; 4.24 + } 4.25 + 4.26 return true; 4.27 } 4.28 4.29 void game_cleanup() 4.30 { 4.31 + board.destroy(); 4.32 } 4.33 4.34 void game_update(unsigned long time_msec) 4.35 @@ -42,13 +50,16 @@ 4.36 4.37 draw_backdrop(); 4.38 4.39 + board.draw(); 4.40 + 4.41 + /* 4.42 glBegin(GL_QUADS); 4.43 glNormal3f(0, 1, 0); 4.44 glVertex3f(-1, 0, 1); 4.45 glVertex3f(1, 0, 1); 4.46 glVertex3f(1, 0, -1); 4.47 glVertex3f(-1, 0, -1); 4.48 - glEnd(); 4.49 + glEnd();*/ 4.50 } 4.51 4.52 static void draw_backdrop() 4.53 @@ -85,7 +96,7 @@ 4.54 { 4.55 glMatrixMode(GL_PROJECTION); 4.56 glLoadIdentity(); 4.57 - gluPerspective(50, (float)x / (float)y, 0.5, 500.0); 4.58 + gluPerspective(50, (float)x / (float)y, 0.2, 200.0); 4.59 4.60 glViewport(0, 0, x, y); 4.61 }
5.1 --- a/src/mesh.cc Sun Jun 21 06:30:39 2015 +0300 5.2 +++ b/src/mesh.cc Mon Jun 22 05:05:37 2015 +0300 5.3 @@ -5,15 +5,16 @@ 5.4 #include "opengl.h" 5.5 #include "mesh.h" 5.6 //#include "xform_node.h" 5.7 -#include "shader.h" 5.8 5.9 -int Mesh::global_sdr_loc[NUM_MESH_ATTR] = { 5.10 +int Mesh::global_sdr_loc[NUM_MESH_ATTR] = { 0, 1, 2, 3, 4, 5, 6 }; 5.11 +/* 5.12 (int)SDR_ATTR_VERTEX, 5.13 (int)SDR_ATTR_NORMAL, 5.14 (int)SDR_ATTR_TANGENT, 5.15 (int)SDR_ATTR_TEXCOORD, 5.16 (int)SDR_ATTR_COLOR, 5.17 -1, -1}; 5.18 +*/ 5.19 unsigned int Mesh::intersect_mode = ISECT_DEFAULT; 5.20 float Mesh::vertex_sel_dist = 0.01; 5.21 float Mesh::vis_vecsize = 1.0; 5.22 @@ -555,12 +556,9 @@ 5.23 5.24 void Mesh::draw() const 5.25 { 5.26 -#ifdef GL_ES_VERSION_2_0 5.27 - if(!SdrProg::active) { 5.28 - fprintf(stderr, "%s: CrippledGL ES can't draw without a shader\n", __FUNCTION__); 5.29 - return; 5.30 - } 5.31 -#endif 5.32 + int cur_sdr; 5.33 + glGetIntegerv(GL_CURRENT_PROGRAM, &cur_sdr); 5.34 + 5.35 5.36 ((Mesh*)this)->update_buffers(); 5.37 5.38 @@ -569,7 +567,7 @@ 5.39 return; 5.40 } 5.41 5.42 - if(SdrProg::active) { 5.43 + if(cur_sdr) { 5.44 // rendering with shaders 5.45 if(global_sdr_loc[MESH_ATTR_VERTEX] == -1) { 5.46 fprintf(stderr, "%s: shader attribute location for vertices unset\n", __FUNCTION__); 5.47 @@ -618,7 +616,7 @@ 5.48 glDrawArrays(GL_TRIANGLES, 0, nverts); 5.49 } 5.50 5.51 - if(SdrProg::active) { 5.52 + if(cur_sdr) { 5.53 // rendered with shaders 5.54 for(int i=0; i<NUM_MESH_ATTR; i++) { 5.55 int loc = global_sdr_loc[i]; 5.56 @@ -1128,7 +1126,6 @@ 5.57 5.58 glDisableVertexAttribArray(vloc); 5.59 glDisableVertexAttribArray(nloc); 5.60 - CHECK_GLERROR; 5.61 } 5.62 5.63 void Triangle::draw_wire() const 5.64 @@ -1142,7 +1139,6 @@ 5.65 glDrawElements(GL_LINES, 6, GL_UNSIGNED_INT, idxarr); 5.66 5.67 glDisableVertexAttribArray(vloc); 5.68 - CHECK_GLERROR; 5.69 } 5.70 5.71 Vector3 Triangle::calc_barycentric(const Vector3 &pos) const
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/src/meshgen.cc Mon Jun 22 05:05:37 2015 +0300 6.3 @@ -0,0 +1,487 @@ 6.4 +#include <stdio.h> 6.5 +#include "meshgen.h" 6.6 +#include "mesh.h" 6.7 + 6.8 +// -------- sphere -------- 6.9 + 6.10 +#define SURAD(u) ((u) * 2.0 * M_PI) 6.11 +#define SVRAD(v) ((v) * M_PI) 6.12 + 6.13 +static Vector3 sphvec(float theta, float phi) 6.14 +{ 6.15 + return Vector3(sin(theta) * sin(phi), 6.16 + cos(phi), 6.17 + cos(theta) * sin(phi)); 6.18 +} 6.19 + 6.20 +void gen_sphere(Mesh *mesh, float rad, int usub, int vsub, float urange, float vrange) 6.21 +{ 6.22 + if(usub < 4) usub = 4; 6.23 + if(vsub < 2) vsub = 2; 6.24 + 6.25 + int uverts = usub + 1; 6.26 + int vverts = vsub + 1; 6.27 + 6.28 + int num_verts = uverts * vverts; 6.29 + int num_quads = usub * vsub; 6.30 + int num_tri = num_quads * 2; 6.31 + 6.32 + mesh->clear(); 6.33 + Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0); 6.34 + Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0); 6.35 + Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0); 6.36 + Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0); 6.37 + unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0); 6.38 + 6.39 + float du = urange / (float)(uverts - 1); 6.40 + float dv = vrange / (float)(vverts - 1); 6.41 + 6.42 + float u = 0.0; 6.43 + for(int i=0; i<uverts; i++) { 6.44 + float theta = SURAD(u * urange); 6.45 + 6.46 + float v = 0.0; 6.47 + for(int j=0; j<vverts; j++) { 6.48 + float phi = SVRAD(v * vrange); 6.49 + 6.50 + Vector3 pos = sphvec(theta, phi); 6.51 + 6.52 + *varr++ = pos * rad; 6.53 + *narr++ = pos; 6.54 + *tarr++ = (sphvec(theta + 0.1f, (float)M_PI / 2.0f) - sphvec(theta - 0.1f, (float)M_PI / 2.0f)).normalized(); 6.55 + *uvarr++ = Vector2(u * urange, v * vrange); 6.56 + 6.57 + if(i < usub && j < vsub) { 6.58 + int idx = i * vverts + j; 6.59 + *idxarr++ = idx; 6.60 + *idxarr++ = idx + 1; 6.61 + *idxarr++ = idx + vverts + 1; 6.62 + 6.63 + *idxarr++ = idx; 6.64 + *idxarr++ = idx + vverts + 1; 6.65 + *idxarr++ = idx + vverts; 6.66 + } 6.67 + 6.68 + v += dv; 6.69 + } 6.70 + u += du; 6.71 + } 6.72 +} 6.73 + 6.74 + 6.75 +// -------- cylinder -------- 6.76 + 6.77 +static Vector3 cylvec(float theta, float height) 6.78 +{ 6.79 + return Vector3(sin(theta), height, cos(theta)); 6.80 +} 6.81 + 6.82 +void gen_cylinder(Mesh *mesh, float rad, float height, int usub, int vsub, int capsub, float urange, float vrange) 6.83 +{ 6.84 + if(usub < 4) usub = 4; 6.85 + if(vsub < 1) vsub = 1; 6.86 + 6.87 + int uverts = usub + 1; 6.88 + int vverts = vsub + 1; 6.89 + 6.90 + int num_body_verts = uverts * vverts; 6.91 + int num_body_quads = usub * vsub; 6.92 + int num_body_tri = num_body_quads * 2; 6.93 + 6.94 + int capvverts = capsub ? capsub + 1 : 0; 6.95 + int num_cap_verts = uverts * capvverts; 6.96 + int num_cap_quads = usub * capsub; 6.97 + int num_cap_tri = num_cap_quads * 2; 6.98 + 6.99 + int num_verts = num_body_verts + num_cap_verts * 2; 6.100 + int num_tri = num_body_tri + num_cap_tri * 2; 6.101 + 6.102 + mesh->clear(); 6.103 + Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0); 6.104 + Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0); 6.105 + Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0); 6.106 + Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0); 6.107 + unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0); 6.108 + 6.109 + float du = urange / (float)(uverts - 1); 6.110 + float dv = vrange / (float)(vverts - 1); 6.111 + 6.112 + float u = 0.0; 6.113 + for(int i=0; i<uverts; i++) { 6.114 + float theta = SURAD(u); 6.115 + 6.116 + float v = 0.0; 6.117 + for(int j=0; j<vverts; j++) { 6.118 + float y = (v - 0.5) * height; 6.119 + Vector3 pos = cylvec(theta, y); 6.120 + 6.121 + *varr++ = Vector3(pos.x * rad, pos.y, pos.z * rad); 6.122 + *narr++ = Vector3(pos.x, 0.0, pos.z); 6.123 + *tarr++ = (cylvec(theta + 0.1, 0.0) - cylvec(theta - 0.1, 0.0)).normalized(); 6.124 + *uvarr++ = Vector2(u * urange, v * vrange); 6.125 + 6.126 + if(i < usub && j < vsub) { 6.127 + int idx = i * vverts + j; 6.128 + 6.129 + *idxarr++ = idx; 6.130 + *idxarr++ = idx + vverts + 1; 6.131 + *idxarr++ = idx + 1; 6.132 + 6.133 + *idxarr++ = idx; 6.134 + *idxarr++ = idx + vverts; 6.135 + *idxarr++ = idx + vverts + 1; 6.136 + } 6.137 + 6.138 + v += dv; 6.139 + } 6.140 + u += du; 6.141 + } 6.142 + 6.143 + 6.144 + // now the cap! 6.145 + if(!capsub) { 6.146 + return; 6.147 + } 6.148 + 6.149 + dv = 1.0 / (float)(capvverts - 1); 6.150 + 6.151 + u = 0.0; 6.152 + for(int i=0; i<uverts; i++) { 6.153 + float theta = SURAD(u); 6.154 + 6.155 + float v = 0.0; 6.156 + for(int j=0; j<capvverts; j++) { 6.157 + float r = v * rad; 6.158 + 6.159 + Vector3 pos = cylvec(theta, height / 2.0) * r; 6.160 + pos.y = height / 2.0; 6.161 + Vector3 tang = (cylvec(theta + 0.1, 0.0) - cylvec(theta - 0.1, 0.0)).normalized(); 6.162 + 6.163 + *varr++ = pos; 6.164 + *narr++ = Vector3(0, 1, 0); 6.165 + *tarr++ = tang; 6.166 + *uvarr++ = Vector2(u * urange, v); 6.167 + 6.168 + pos.y = -height / 2.0; 6.169 + *varr++ = pos; 6.170 + *narr++ = Vector3(0, -1, 0); 6.171 + *tarr++ = -tang; 6.172 + *uvarr++ = Vector2(u * urange, v); 6.173 + 6.174 + if(i < usub && j < capsub) { 6.175 + unsigned int idx = num_body_verts + (i * capvverts + j) * 2; 6.176 + 6.177 + unsigned int vidx[4] = { 6.178 + idx, 6.179 + idx + capvverts * 2, 6.180 + idx + (capvverts + 1) * 2, 6.181 + idx + 2 6.182 + }; 6.183 + 6.184 + *idxarr++ = vidx[0]; 6.185 + *idxarr++ = vidx[2]; 6.186 + *idxarr++ = vidx[1]; 6.187 + *idxarr++ = vidx[0]; 6.188 + *idxarr++ = vidx[3]; 6.189 + *idxarr++ = vidx[2]; 6.190 + 6.191 + *idxarr++ = vidx[0] + 1; 6.192 + *idxarr++ = vidx[1] + 1; 6.193 + *idxarr++ = vidx[2] + 1; 6.194 + *idxarr++ = vidx[0] + 1; 6.195 + *idxarr++ = vidx[2] + 1; 6.196 + *idxarr++ = vidx[3] + 1; 6.197 + } 6.198 + 6.199 + v += dv; 6.200 + } 6.201 + u += du; 6.202 + } 6.203 +} 6.204 + 6.205 +// -------- cone -------- 6.206 + 6.207 +static Vector3 conevec(float theta, float y, float height) 6.208 +{ 6.209 + float scale = 1.0 - y / height; 6.210 + return Vector3(sin(theta) * scale, y, cos(theta) * scale); 6.211 +} 6.212 + 6.213 +void gen_cone(Mesh *mesh, float rad, float height, int usub, int vsub, int capsub, float urange, float vrange) 6.214 +{ 6.215 + if(usub < 4) usub = 4; 6.216 + if(vsub < 1) vsub = 1; 6.217 + 6.218 + int uverts = usub + 1; 6.219 + int vverts = vsub + 1; 6.220 + 6.221 + int num_body_verts = uverts * vverts; 6.222 + int num_body_quads = usub * vsub; 6.223 + int num_body_tri = num_body_quads * 2; 6.224 + 6.225 + int capvverts = capsub ? capsub + 1 : 0; 6.226 + int num_cap_verts = uverts * capvverts; 6.227 + int num_cap_quads = usub * capsub; 6.228 + int num_cap_tri = num_cap_quads * 2; 6.229 + 6.230 + int num_verts = num_body_verts + num_cap_verts; 6.231 + int num_tri = num_body_tri + num_cap_tri; 6.232 + 6.233 + mesh->clear(); 6.234 + Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0); 6.235 + Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0); 6.236 + Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0); 6.237 + Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0); 6.238 + unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0); 6.239 + 6.240 + float du = urange / (float)(uverts - 1); 6.241 + float dv = vrange / (float)(vverts - 1); 6.242 + 6.243 + float u = 0.0; 6.244 + for(int i=0; i<uverts; i++) { 6.245 + float theta = SURAD(u); 6.246 + 6.247 + float v = 0.0; 6.248 + for(int j=0; j<vverts; j++) { 6.249 + float y = v * height; 6.250 + Vector3 pos = conevec(theta, y, height); 6.251 + 6.252 + Vector3 tang = (conevec(theta + 0.1, 0.0, height) - conevec(theta - 0.1, 0.0, height)).normalized(); 6.253 + Vector3 bitang = (conevec(theta, y + 0.1, height) - pos).normalized(); 6.254 + 6.255 + *varr++ = Vector3(pos.x * rad, pos.y, pos.z * rad); 6.256 + *narr++ = cross_product(tang, bitang); 6.257 + *tarr++ = tang; 6.258 + *uvarr++ = Vector2(u * urange, v * vrange); 6.259 + 6.260 + if(i < usub && j < vsub) { 6.261 + int idx = i * vverts + j; 6.262 + 6.263 + *idxarr++ = idx; 6.264 + *idxarr++ = idx + vverts + 1; 6.265 + *idxarr++ = idx + 1; 6.266 + 6.267 + *idxarr++ = idx; 6.268 + *idxarr++ = idx + vverts; 6.269 + *idxarr++ = idx + vverts + 1; 6.270 + } 6.271 + 6.272 + v += dv; 6.273 + } 6.274 + u += du; 6.275 + } 6.276 + 6.277 + 6.278 + // now the bottom cap! 6.279 + if(!capsub) { 6.280 + return; 6.281 + } 6.282 + 6.283 + dv = 1.0 / (float)(capvverts - 1); 6.284 + 6.285 + u = 0.0; 6.286 + for(int i=0; i<uverts; i++) { 6.287 + float theta = SURAD(u); 6.288 + 6.289 + float v = 0.0; 6.290 + for(int j=0; j<capvverts; j++) { 6.291 + float r = v * rad; 6.292 + 6.293 + Vector3 pos = conevec(theta, 0.0, height) * r; 6.294 + Vector3 tang = (cylvec(theta + 0.1, 0.0) - cylvec(theta - 0.1, 0.0)).normalized(); 6.295 + 6.296 + *varr++ = pos; 6.297 + *narr++ = Vector3(0, -1, 0); 6.298 + *tarr++ = tang; 6.299 + *uvarr++ = Vector2(u * urange, v); 6.300 + 6.301 + if(i < usub && j < capsub) { 6.302 + unsigned int idx = num_body_verts + i * capvverts + j; 6.303 + 6.304 + unsigned int vidx[4] = { 6.305 + idx, 6.306 + idx + capvverts, 6.307 + idx + (capvverts + 1), 6.308 + idx + 1 6.309 + }; 6.310 + 6.311 + *idxarr++ = vidx[0]; 6.312 + *idxarr++ = vidx[1]; 6.313 + *idxarr++ = vidx[2]; 6.314 + *idxarr++ = vidx[0]; 6.315 + *idxarr++ = vidx[2]; 6.316 + *idxarr++ = vidx[3]; 6.317 + } 6.318 + 6.319 + v += dv; 6.320 + } 6.321 + u += du; 6.322 + } 6.323 +} 6.324 + 6.325 + 6.326 +// -------- plane -------- 6.327 + 6.328 +void gen_plane(Mesh *mesh, float width, float height, int usub, int vsub) 6.329 +{ 6.330 + gen_heightmap(mesh, width, height, usub, vsub, 0); 6.331 +} 6.332 + 6.333 + 6.334 +// ----- heightmap ------ 6.335 + 6.336 +void gen_heightmap(Mesh *mesh, float width, float height, int usub, int vsub, float (*hf)(float, float, void*), void *hfdata) 6.337 +{ 6.338 + if(usub < 1) usub = 1; 6.339 + if(vsub < 1) vsub = 1; 6.340 + 6.341 + mesh->clear(); 6.342 + 6.343 + int uverts = usub + 1; 6.344 + int vverts = vsub + 1; 6.345 + int num_verts = uverts * vverts; 6.346 + 6.347 + int num_quads = usub * vsub; 6.348 + int num_tri = num_quads * 2; 6.349 + 6.350 + Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0); 6.351 + Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0); 6.352 + Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0); 6.353 + Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0); 6.354 + unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0); 6.355 + 6.356 + float du = 1.0 / (float)usub; 6.357 + float dv = 1.0 / (float)vsub; 6.358 + 6.359 + float u = 0.0; 6.360 + for(int i=0; i<uverts; i++) { 6.361 + float v = 0.0; 6.362 + for(int j=0; j<vverts; j++) { 6.363 + float x = (u - 0.5) * width; 6.364 + float y = (v - 0.5) * height; 6.365 + float z = hf ? hf(u, v, hfdata) : 0.0; 6.366 + 6.367 + Vector3 normal = Vector3(0, 0, 1); 6.368 + if(hf) { 6.369 + float u1z = hf(u + du, v, hfdata); 6.370 + float v1z = hf(u, v + dv, hfdata); 6.371 + 6.372 + Vector3 tang = Vector3(du * width, 0, u1z - z); 6.373 + Vector3 bitan = Vector3(0, dv * height, v1z - z); 6.374 + normal = cross_product(tang, bitan).normalized(); 6.375 + } 6.376 + 6.377 + *varr++ = Vector3(x, y, z); 6.378 + *narr++ = normal; 6.379 + *tarr++ = Vector3(1, 0, 0); 6.380 + *uvarr++ = Vector2(u, v); 6.381 + 6.382 + if(i < usub && j < vsub) { 6.383 + int idx = i * vverts + j; 6.384 + 6.385 + *idxarr++ = idx; 6.386 + *idxarr++ = idx + vverts + 1; 6.387 + *idxarr++ = idx + 1; 6.388 + 6.389 + *idxarr++ = idx; 6.390 + *idxarr++ = idx + vverts; 6.391 + *idxarr++ = idx + vverts + 1; 6.392 + } 6.393 + 6.394 + v += dv; 6.395 + } 6.396 + u += du; 6.397 + } 6.398 +} 6.399 + 6.400 +// ----- heightmap ------ 6.401 + 6.402 +void gen_box(Mesh *mesh, float xsz, float ysz, float zsz) 6.403 +{ 6.404 + mesh->clear(); 6.405 + 6.406 + const int num_faces = 6; 6.407 + int num_verts = num_faces * 4; 6.408 + int num_tri = num_faces * 2; 6.409 + 6.410 + float x = xsz / 2.0; 6.411 + float y = ysz / 2.0; 6.412 + float z = zsz / 2.0; 6.413 + 6.414 + Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0); 6.415 + Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0); 6.416 + Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0); 6.417 + Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0); 6.418 + unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0); 6.419 + 6.420 + static const Vector2 uv[] = { Vector2(0, 0), Vector2(1, 0), Vector2(1, 1), Vector2(0, 1) }; 6.421 + 6.422 + // front 6.423 + for(int i=0; i<4; i++) { 6.424 + *narr++ = Vector3(0, 0, 1); 6.425 + *tarr++ = Vector3(1, 0, 0); 6.426 + *uvarr++ = uv[i]; 6.427 + } 6.428 + *varr++ = Vector3(-x, -y, z); 6.429 + *varr++ = Vector3(x, -y, z); 6.430 + *varr++ = Vector3(x, y, z); 6.431 + *varr++ = Vector3(-x, y, z); 6.432 + // right 6.433 + for(int i=0; i<4; i++) { 6.434 + *narr++ = Vector3(1, 0, 0); 6.435 + *tarr++ = Vector3(0, 0, -1); 6.436 + *uvarr++ = uv[i]; 6.437 + } 6.438 + *varr++ = Vector3(x, -y, z); 6.439 + *varr++ = Vector3(x, -y, -z); 6.440 + *varr++ = Vector3(x, y, -z); 6.441 + *varr++ = Vector3(x, y, z); 6.442 + // back 6.443 + for(int i=0; i<4; i++) { 6.444 + *narr++ = Vector3(0, 0, -1); 6.445 + *tarr++ = Vector3(-1, 0, 0); 6.446 + *uvarr++ = uv[i]; 6.447 + } 6.448 + *varr++ = Vector3(x, -y, -z); 6.449 + *varr++ = Vector3(-x, -y, -z); 6.450 + *varr++ = Vector3(-x, y, -z); 6.451 + *varr++ = Vector3(x, y, -z); 6.452 + // left 6.453 + for(int i=0; i<4; i++) { 6.454 + *narr++ = Vector3(-1, 0, 0); 6.455 + *tarr++ = Vector3(0, 0, 1); 6.456 + *uvarr++ = uv[i]; 6.457 + } 6.458 + *varr++ = Vector3(-x, -y, -z); 6.459 + *varr++ = Vector3(-x, -y, z); 6.460 + *varr++ = Vector3(-x, y, z); 6.461 + *varr++ = Vector3(-x, y, -z); 6.462 + // top 6.463 + for(int i=0; i<4; i++) { 6.464 + *narr++ = Vector3(0, 1, 0); 6.465 + *tarr++ = Vector3(1, 0, 0); 6.466 + *uvarr++ = uv[i]; 6.467 + } 6.468 + *varr++ = Vector3(-x, y, z); 6.469 + *varr++ = Vector3(x, y, z); 6.470 + *varr++ = Vector3(x, y, -z); 6.471 + *varr++ = Vector3(-x, y, -z); 6.472 + // bottom 6.473 + for(int i=0; i<4; i++) { 6.474 + *narr++ = Vector3(0, -1, 0); 6.475 + *tarr++ = Vector3(1, 0, 0); 6.476 + *uvarr++ = uv[i]; 6.477 + } 6.478 + *varr++ = Vector3(-x, -y, -z); 6.479 + *varr++ = Vector3(x, -y, -z); 6.480 + *varr++ = Vector3(x, -y, z); 6.481 + *varr++ = Vector3(-x, -y, z); 6.482 + 6.483 + // index array 6.484 + static const int faceidx[] = {0, 1, 2, 0, 2, 3}; 6.485 + for(int i=0; i<num_faces; i++) { 6.486 + for(int j=0; j<6; j++) { 6.487 + *idxarr++ = faceidx[j] + i * 4; 6.488 + } 6.489 + } 6.490 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/src/meshgen.h Mon Jun 22 05:05:37 2015 +0300 7.3 @@ -0,0 +1,13 @@ 7.4 +#ifndef MESHGEN_H_ 7.5 +#define MESHGEN_H_ 7.6 + 7.7 +class Mesh; 7.8 + 7.9 +void gen_sphere(Mesh *mesh, float rad, int usub, int vsub, float urange = 1.0, float vrange = 1.0); 7.10 +void gen_cylinder(Mesh *mesh, float rad, float height, int usub, int vsub, int capsub = 0, float urange = 1.0, float vrange = 1.0); 7.11 +void gen_cone(Mesh *mesh, float rad, float height, int usub, int vsub, int capsub = 0, float urange = 1.0, float vrange = 1.0); 7.12 +void gen_plane(Mesh *mesh, float width, float height, int usub = 1, int vsub = 1); 7.13 +void gen_heightmap(Mesh *mesh, float width, float height, int usub, int vsub, float (*hf)(float, float, void*), void *hfdata = 0); 7.14 +void gen_box(Mesh *mesh, float xsz, float ysz, float zsz); 7.15 + 7.16 +#endif // MESHGEN_H_
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/object.cc Mon Jun 22 05:05:37 2015 +0300 8.3 @@ -0,0 +1,45 @@ 8.4 +#include "object.h" 8.5 +#include "opengl.h" 8.6 + 8.7 +Object::Object() 8.8 +{ 8.9 + mesh = 0; 8.10 +} 8.11 + 8.12 +Object::~Object() 8.13 +{ 8.14 + delete mesh; 8.15 +} 8.16 + 8.17 +Matrix4x4 &Object::xform() 8.18 +{ 8.19 + return matrix; 8.20 +} 8.21 + 8.22 +const Matrix4x4 &Object::xform() const 8.23 +{ 8.24 + return matrix; 8.25 +} 8.26 + 8.27 +void Object::set_mesh(Mesh *m) 8.28 +{ 8.29 + this->mesh = m; 8.30 +} 8.31 + 8.32 +Mesh *Object::get_mesh() const 8.33 +{ 8.34 + return mesh; 8.35 +} 8.36 + 8.37 +void Object::draw() const 8.38 +{ 8.39 + if(!mesh) return; 8.40 + 8.41 + glMatrixMode(GL_MODELVIEW); 8.42 + glPushMatrix(); 8.43 + glLoadTransposeMatrixf(matrix[0]); 8.44 + 8.45 + mesh->draw(); 8.46 + 8.47 + glPopMatrix(); 8.48 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/src/object.h Mon Jun 22 05:05:37 2015 +0300 9.3 @@ -0,0 +1,24 @@ 9.4 +#ifndef OBJECT_H_ 9.5 +#define OBJECT_H_ 9.6 + 9.7 +#include "mesh.h" 9.8 + 9.9 +class Object { 9.10 +private: 9.11 + Mesh *mesh; 9.12 + Matrix4x4 matrix; 9.13 + 9.14 +public: 9.15 + Object(); 9.16 + ~Object(); 9.17 + 9.18 + Matrix4x4 &xform(); 9.19 + const Matrix4x4 &xform() const; 9.20 + 9.21 + void set_mesh(Mesh *m); 9.22 + Mesh *get_mesh() const; 9.23 + 9.24 + void draw() const; 9.25 +}; 9.26 + 9.27 +#endif // OBJECT_H_