rev |
line source |
nuclear@0
|
1 #include <list>
|
nuclear@0
|
2 #include "zscn.h"
|
nuclear@0
|
3
|
nuclear@0
|
4 struct Face {
|
nuclear@0
|
5 Vector3 v[3];
|
nuclear@0
|
6 Vector3 n[3];
|
nuclear@0
|
7 Vector2 t[3];
|
nuclear@0
|
8
|
nuclear@0
|
9 const henge::Material *mat;
|
nuclear@0
|
10
|
nuclear@0
|
11 Face()
|
nuclear@0
|
12 {
|
nuclear@0
|
13 memset(this, 0, sizeof(Face));
|
nuclear@0
|
14 }
|
nuclear@0
|
15 };
|
nuclear@0
|
16
|
nuclear@0
|
17 static void proc_mesh(std::list<Face> *facelist, const henge::TriMesh *mesh,
|
nuclear@0
|
18 const henge::Material *mat, const Matrix4x4 &xform);
|
nuclear@0
|
19 static bool operator <(const Face &a, const Face &b);
|
nuclear@0
|
20
|
nuclear@0
|
21 ZScene::~ZScene()
|
nuclear@0
|
22 {
|
nuclear@0
|
23 }
|
nuclear@0
|
24
|
nuclear@0
|
25 void ZScene::render(unsigned int msec) const
|
nuclear@0
|
26 {
|
nuclear@0
|
27 setup_lights(msec);
|
nuclear@0
|
28
|
nuclear@0
|
29 glMatrixMode(GL_MODELVIEW);
|
nuclear@0
|
30
|
nuclear@0
|
31 Matrix4x4 view_mat;
|
nuclear@0
|
32 henge::store_matrix(&view_mat);
|
nuclear@0
|
33
|
nuclear@0
|
34 std::list<Face> facelist;
|
nuclear@0
|
35
|
nuclear@0
|
36 for(size_t i=0; i<objects.size(); i++) {
|
nuclear@0
|
37 const henge::RObject *obj = objects[i];
|
nuclear@0
|
38 Matrix4x4 xform = obj->get_xform_matrix(msec) * view_mat;
|
nuclear@0
|
39
|
nuclear@0
|
40 const henge::Material *mat = ((henge::RObject*)obj)->get_material_ptr();
|
nuclear@0
|
41 const henge::TriMesh *mesh = obj->get_mesh();
|
nuclear@0
|
42
|
nuclear@0
|
43 proc_mesh(&facelist, mesh, mat, xform);
|
nuclear@0
|
44 }
|
nuclear@0
|
45
|
nuclear@0
|
46 facelist.sort();
|
nuclear@0
|
47
|
nuclear@0
|
48 glPushAttrib(GL_ENABLE_BIT);
|
nuclear@0
|
49 glDisable(GL_DEPTH_TEST);
|
nuclear@0
|
50
|
nuclear@0
|
51 glPushMatrix();
|
nuclear@0
|
52 glLoadIdentity();
|
nuclear@0
|
53
|
nuclear@0
|
54 glBegin(GL_TRIANGLES);
|
nuclear@0
|
55
|
nuclear@0
|
56 const henge::Material *cur_mat = 0;
|
nuclear@0
|
57 std::list<Face>::iterator face = facelist.begin();
|
nuclear@0
|
58 while(face != facelist.end()) {
|
nuclear@0
|
59 if(face->mat != cur_mat) {
|
nuclear@0
|
60 glEnd();
|
nuclear@0
|
61
|
nuclear@0
|
62 face->mat->bind();
|
nuclear@0
|
63 cur_mat = face->mat;
|
nuclear@0
|
64
|
nuclear@0
|
65 glBegin(GL_TRIANGLES);
|
nuclear@0
|
66 }
|
nuclear@0
|
67
|
nuclear@0
|
68 for(int i=0; i<3; i++) {
|
nuclear@0
|
69 glNormal3f(face->n[i].x, face->n[i].y, face->n[i].z);
|
nuclear@0
|
70 glTexCoord2f(face->t[i].x, face->t[i].y);
|
nuclear@0
|
71 glVertex3f(face->v[i].x, face->v[i].y, face->v[i].z);
|
nuclear@0
|
72 }
|
nuclear@0
|
73
|
nuclear@0
|
74 face++;
|
nuclear@0
|
75 }
|
nuclear@0
|
76 glEnd();
|
nuclear@0
|
77
|
nuclear@0
|
78 glMatrixMode(GL_MODELVIEW);
|
nuclear@0
|
79 glPopMatrix();
|
nuclear@0
|
80 glPopAttrib();
|
nuclear@0
|
81 }
|
nuclear@0
|
82
|
nuclear@0
|
83 static void proc_mesh(std::list<Face> *facelist, const henge::TriMesh *mesh,
|
nuclear@0
|
84 const henge::Material *mat, const Matrix4x4 &xform)
|
nuclear@0
|
85 {
|
nuclear@0
|
86 Matrix3x3 norm_xform = xform;
|
nuclear@0
|
87
|
nuclear@0
|
88 const Vector3 *vert = mesh->get_data_vec3(henge::EL_VERTEX);
|
nuclear@0
|
89 const Vector3 *norm = mesh->get_data_vec3(henge::EL_NORMAL);
|
nuclear@0
|
90 const Vector2 *tc = mesh->get_data_vec2(henge::EL_TEXCOORD);
|
nuclear@0
|
91 const unsigned int *index = mesh->get_data_int(henge::EL_INDEX);
|
nuclear@0
|
92
|
nuclear@0
|
93 int nvert = mesh->get_count(henge::EL_VERTEX);
|
nuclear@0
|
94 int nindex = mesh->get_count(henge::EL_INDEX);
|
nuclear@0
|
95
|
nuclear@0
|
96 if(!vert || !nvert) {
|
nuclear@0
|
97 return;
|
nuclear@0
|
98 }
|
nuclear@0
|
99
|
nuclear@0
|
100 int face_count = (index ? nindex : nvert) / 3;
|
nuclear@0
|
101
|
nuclear@0
|
102 for(int i=0; i<face_count; i++) {
|
nuclear@0
|
103 Face face;
|
nuclear@0
|
104
|
nuclear@0
|
105 for(int j=0; j<3; j++) {
|
nuclear@0
|
106 int idx = index ? index[i * 3 + j] : i * 3 + j;
|
nuclear@0
|
107
|
nuclear@0
|
108 if(norm) {
|
nuclear@0
|
109 face.n[j] = norm[idx].transformed(norm_xform);
|
nuclear@0
|
110 }
|
nuclear@0
|
111 if(tc) {
|
nuclear@0
|
112 face.t[j] = tc[idx];
|
nuclear@0
|
113 }
|
nuclear@0
|
114 if(vert) {
|
nuclear@0
|
115 face.v[j] = vert[idx].transformed(xform);
|
nuclear@0
|
116 }
|
nuclear@0
|
117 }
|
nuclear@0
|
118
|
nuclear@0
|
119 face.mat = mat;
|
nuclear@0
|
120 facelist->push_back(face);
|
nuclear@0
|
121 }
|
nuclear@0
|
122 }
|
nuclear@0
|
123
|
nuclear@0
|
124 static bool operator <(const Face &a, const Face &b)
|
nuclear@0
|
125 {
|
nuclear@0
|
126 return (a.v[0].z + a.v[1].z + a.v[2].z) < (b.v[0].z + b.v[1].z + b.v[2].z);
|
nuclear@0
|
127 }
|