rev |
line source |
nuclear@0
|
1 #include <stdio.h>
|
nuclear@0
|
2 #include <stdlib.h>
|
nuclear@0
|
3 #include <assert.h>
|
nuclear@6
|
4 #include <vector>
|
nuclear@0
|
5
|
nuclear@8
|
6 #include "opengl.h"
|
nuclear@0
|
7 #ifndef __APPLE__
|
nuclear@0
|
8 #include <GL/glut.h>
|
nuclear@0
|
9 #else
|
nuclear@0
|
10 #include <GLUT/glut.h>
|
nuclear@0
|
11 #endif
|
nuclear@0
|
12
|
nuclear@8
|
13 #include "objfile.h"
|
nuclear@8
|
14 #include "mesh.h"
|
nuclear@6
|
15 #include "gobj.h"
|
nuclear@6
|
16 #include "co_xform.h"
|
nuclear@6
|
17 #include "co_dbgvis.h"
|
nuclear@8
|
18 #include "co_mesh.h"
|
nuclear@8
|
19 #include "co_phys.h"
|
nuclear@6
|
20 #include "sim.h"
|
nuclear@6
|
21
|
nuclear@0
|
22 static bool init();
|
nuclear@0
|
23 static void cleanup();
|
nuclear@0
|
24 static void display();
|
nuclear@0
|
25 static void idle();
|
nuclear@0
|
26 static void reshape(int x, int y);
|
nuclear@0
|
27 static void keyb(unsigned char key, int x, int y);
|
nuclear@0
|
28 static void mouse(int bn, int st, int x, int y);
|
nuclear@0
|
29 static void motion(int x, int y);
|
nuclear@8
|
30 static Mesh *load_mesh(const char *fname);
|
nuclear@0
|
31
|
nuclear@8
|
32 float cam_theta, cam_phi = 25, cam_dist = 10;
|
nuclear@6
|
33
|
nuclear@6
|
34 std::vector<GObject*> objects;
|
nuclear@6
|
35 SimWorld simworld;
|
nuclear@6
|
36
|
nuclear@0
|
37
|
nuclear@0
|
38 int main(int argc, char **argv)
|
nuclear@0
|
39 {
|
nuclear@0
|
40 glutInit(&argc, argv);
|
nuclear@0
|
41 glutInitWindowSize(800, 600);
|
nuclear@0
|
42 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
|
nuclear@0
|
43 glutCreateWindow("component system test");
|
nuclear@0
|
44
|
nuclear@0
|
45 glutDisplayFunc(display);
|
nuclear@7
|
46 glutIdleFunc(idle);
|
nuclear@0
|
47 glutReshapeFunc(reshape);
|
nuclear@0
|
48 glutKeyboardFunc(keyb);
|
nuclear@0
|
49 glutMouseFunc(mouse);
|
nuclear@0
|
50 glutMotionFunc(motion);
|
nuclear@0
|
51
|
nuclear@0
|
52 if(!init()) {
|
nuclear@0
|
53 return 1;
|
nuclear@0
|
54 }
|
nuclear@0
|
55 atexit(cleanup);
|
nuclear@0
|
56
|
nuclear@0
|
57 glutMainLoop();
|
nuclear@0
|
58 return 0;
|
nuclear@0
|
59 }
|
nuclear@0
|
60
|
nuclear@0
|
61 static bool init()
|
nuclear@0
|
62 {
|
nuclear@8
|
63 init_opengl();
|
nuclear@8
|
64
|
nuclear@0
|
65 glEnable(GL_DEPTH_TEST);
|
nuclear@0
|
66 glEnable(GL_CULL_FACE);
|
nuclear@0
|
67
|
nuclear@6
|
68 glEnable(GL_LIGHTING);
|
nuclear@6
|
69 glEnable(GL_LIGHT0);
|
nuclear@6
|
70 float ldir[] = {-1, 1, 2, 0};
|
nuclear@6
|
71 glLightfv(GL_LIGHT0, GL_POSITION, ldir);
|
nuclear@6
|
72
|
nuclear@8
|
73 GObject *obj;
|
nuclear@8
|
74
|
nuclear@8
|
75 Mesh *mesh = load_mesh("lucy.obj");
|
nuclear@8
|
76 if(!mesh) {
|
nuclear@8
|
77 return false;
|
nuclear@8
|
78 }
|
nuclear@8
|
79
|
nuclear@8
|
80 obj = new GObject;
|
nuclear@6
|
81 obj->add_component(new CoXForm);
|
nuclear@6
|
82 obj->add_component(new CoPRS);
|
nuclear@8
|
83 obj->add_component(new CoMesh);
|
nuclear@8
|
84 gobj_co_prs(obj)->pos = Vector3(-3, 0, 0);
|
nuclear@8
|
85 gobj_co_mesh(obj)->mesh = mesh;
|
nuclear@6
|
86 objects.push_back(obj);
|
nuclear@6
|
87
|
nuclear@6
|
88 obj = new GObject;
|
nuclear@6
|
89 obj->add_component(new CoSphereVis);
|
nuclear@6
|
90 obj->add_component(new CoXForm);
|
nuclear@6
|
91 obj->add_component(new CoPRS);
|
nuclear@8
|
92 gobj_co_prs(obj)->pos = Vector3(3, 3, 0);
|
nuclear@8
|
93 obj->add_component(new CoRigid);
|
nuclear@8
|
94 obj->add_component(new CoCollider);
|
nuclear@8
|
95 gobj_co_collider(obj)->shape = new Sphere;
|
nuclear@6
|
96 objects.push_back(obj);
|
nuclear@8
|
97 simworld.add_object(obj);
|
nuclear@8
|
98
|
nuclear@8
|
99 obj = new GObject;
|
nuclear@8
|
100 obj->add_component(new CoXForm);
|
nuclear@8
|
101 obj->add_component(new CoRigid);
|
nuclear@8
|
102 obj->add_component(new CoCollider);
|
nuclear@8
|
103 gobj_co_collider(obj)->shape = new Plane;
|
nuclear@8
|
104 gobj_co_rigid(obj)->set_fixed(true);
|
nuclear@8
|
105 objects.push_back(obj);
|
nuclear@8
|
106 simworld.add_object(obj);
|
nuclear@6
|
107
|
nuclear@0
|
108 return true;
|
nuclear@0
|
109 }
|
nuclear@0
|
110
|
nuclear@0
|
111 static void cleanup()
|
nuclear@0
|
112 {
|
nuclear@8
|
113 for(size_t i=0; i<objects.size(); i++) {
|
nuclear@8
|
114 delete objects[i];
|
nuclear@8
|
115 }
|
nuclear@8
|
116 objects.clear();
|
nuclear@0
|
117 }
|
nuclear@0
|
118
|
nuclear@6
|
119 static void update()
|
nuclear@6
|
120 {
|
nuclear@6
|
121 static unsigned int prev_upd;
|
nuclear@6
|
122 unsigned int msec = glutGet(GLUT_ELAPSED_TIME);
|
nuclear@6
|
123 float dt = (float)(msec - prev_upd) / 1000.0f;
|
nuclear@6
|
124 prev_upd = msec;
|
nuclear@6
|
125
|
nuclear@6
|
126 for(size_t i=0; i<objects.size(); i++) {
|
nuclear@6
|
127 objects[i]->update(dt);
|
nuclear@6
|
128 }
|
nuclear@6
|
129 }
|
nuclear@6
|
130
|
nuclear@0
|
131 static void display()
|
nuclear@0
|
132 {
|
nuclear@6
|
133 update();
|
nuclear@6
|
134
|
nuclear@0
|
135 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
nuclear@0
|
136
|
nuclear@6
|
137 glMatrixMode(GL_MODELVIEW);
|
nuclear@6
|
138 glLoadIdentity();
|
nuclear@6
|
139 glTranslatef(0, 0, -cam_dist);
|
nuclear@6
|
140 glRotatef(cam_phi, 1, 0, 0);
|
nuclear@6
|
141 glRotatef(cam_theta, 0, 1, 0);
|
nuclear@8
|
142 glTranslatef(0, -0.5, 0);
|
nuclear@6
|
143
|
nuclear@6
|
144 float floor_col[] = {0.2, 0.8, 0.2, 1};
|
nuclear@6
|
145 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, floor_col);
|
nuclear@6
|
146
|
nuclear@6
|
147 glBegin(GL_QUADS);
|
nuclear@6
|
148 glNormal3f(0, 1, 0);
|
nuclear@6
|
149 glVertex3f(-10, 0, 10);
|
nuclear@6
|
150 glVertex3f(10, 0, 10);
|
nuclear@6
|
151 glVertex3f(10, 0, -10);
|
nuclear@6
|
152 glVertex3f(-10, 0, -10);
|
nuclear@6
|
153 glEnd();
|
nuclear@6
|
154
|
nuclear@8
|
155 float obj_col[] = {0.9, 0.9, 0.9, 1};
|
nuclear@8
|
156 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, obj_col);
|
nuclear@8
|
157
|
nuclear@6
|
158 for(size_t i=0; i<objects.size(); i++) {
|
nuclear@8
|
159 objects[i]->draw();
|
nuclear@6
|
160 }
|
nuclear@6
|
161
|
nuclear@0
|
162 glutSwapBuffers();
|
nuclear@0
|
163 assert(glGetError() == GL_NO_ERROR);
|
nuclear@0
|
164 }
|
nuclear@0
|
165
|
nuclear@0
|
166 static void idle()
|
nuclear@0
|
167 {
|
nuclear@0
|
168 glutPostRedisplay();
|
nuclear@0
|
169 }
|
nuclear@0
|
170
|
nuclear@0
|
171 static void reshape(int x, int y)
|
nuclear@0
|
172 {
|
nuclear@0
|
173 glViewport(0, 0, x, y);
|
nuclear@0
|
174
|
nuclear@2
|
175 glMatrixMode(GL_PROJECTION);
|
nuclear@0
|
176 glLoadIdentity();
|
nuclear@0
|
177 gluPerspective(50.0, (float)x / (float)y, 0.5, 500.0);
|
nuclear@0
|
178 }
|
nuclear@0
|
179
|
nuclear@0
|
180 static void keyb(unsigned char key, int x, int y)
|
nuclear@0
|
181 {
|
nuclear@0
|
182 switch(key) {
|
nuclear@0
|
183 case 27:
|
nuclear@0
|
184 exit(0);
|
nuclear@0
|
185 }
|
nuclear@0
|
186 }
|
nuclear@0
|
187
|
nuclear@6
|
188 static bool bnstate[16];
|
nuclear@0
|
189 static int prev_x, prev_y;
|
nuclear@0
|
190
|
nuclear@0
|
191 static void mouse(int bn, int st, int x, int y)
|
nuclear@0
|
192 {
|
nuclear@6
|
193 bnstate[bn - GLUT_LEFT_BUTTON] = st == GLUT_DOWN;
|
nuclear@6
|
194 prev_x = x;
|
nuclear@6
|
195 prev_y = y;
|
nuclear@0
|
196 }
|
nuclear@0
|
197
|
nuclear@0
|
198 static void motion(int x, int y)
|
nuclear@0
|
199 {
|
nuclear@6
|
200 int dx = x - prev_x;
|
nuclear@6
|
201 int dy = y - prev_y;
|
nuclear@6
|
202 prev_x = x;
|
nuclear@6
|
203 prev_y = y;
|
nuclear@6
|
204
|
nuclear@6
|
205 if(bnstate[0]) {
|
nuclear@6
|
206 cam_theta += dx * 0.5;
|
nuclear@6
|
207 cam_phi += dy * 0.5;
|
nuclear@6
|
208
|
nuclear@6
|
209 if(cam_phi < -90) cam_phi = -90;
|
nuclear@6
|
210 if(cam_phi > 90) cam_phi = 90;
|
nuclear@6
|
211
|
nuclear@6
|
212 glutPostRedisplay();
|
nuclear@6
|
213 }
|
nuclear@6
|
214 if(bnstate[2]) {
|
nuclear@6
|
215 cam_dist += dy * 0.1;
|
nuclear@6
|
216
|
nuclear@6
|
217 if(cam_dist < 0.0) cam_dist = 0.0;
|
nuclear@6
|
218 }
|
nuclear@0
|
219 }
|
nuclear@8
|
220
|
nuclear@8
|
221 static Mesh *load_mesh(const char *fname)
|
nuclear@8
|
222 {
|
nuclear@8
|
223 struct objfile *objf = objf_load(fname);
|
nuclear@8
|
224 if(!objf) {
|
nuclear@8
|
225 return 0;
|
nuclear@8
|
226 }
|
nuclear@8
|
227 int nverts = objf_vertex_count(objf);
|
nuclear@8
|
228
|
nuclear@8
|
229 Mesh *m = new Mesh;
|
nuclear@8
|
230 m->set_attrib_data(MESH_ATTR_VERTEX, 3, nverts, objf_vertices(objf));
|
nuclear@8
|
231 m->set_attrib_data(MESH_ATTR_NORMAL, 3, nverts, objf_normals(objf));
|
nuclear@8
|
232 m->set_attrib_data(MESH_ATTR_TEXCOORD, 2, nverts, objf_texcoords(objf));
|
nuclear@8
|
233 objf_free(objf);
|
nuclear@8
|
234 return m;
|
nuclear@8
|
235 }
|