00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "glmesh.h"
00024 #include "common/math/real.h"
00025 #include "material.h"
00026
00027 #include <algorithm>
00028 #include <cassert>
00029
00030 using namespace sheep;
00031 using namespace std;
00032
00033 GLMesh::SubMesh::SubMesh() :
00034 m_material(0),
00035 m_list_name(0)
00036 {
00037 SetupRendering(IMMEDIATE_MODE);
00038 }
00039
00040 GLMesh::SubMesh::~SubMesh() {
00041 if(m_list_name != 0)
00042 glDeleteLists(m_list_name, 1);
00043 }
00044
00045 void GLMesh::SubMesh::SetMaterial(Material *m) {
00046 assert(m);
00047 m_material = m;
00048 }
00049
00050 void GLMesh::SubMesh::SetupRendering(RenderingMode mode) {
00051 m_rendering_mode = mode;
00052
00053 if(m_rendering_mode == DISPLAY_LIST) {
00054 if(m_list_name == 0)
00055 m_list_name = glGenLists(1);
00056
00057 glNewList(m_list_name, GL_COMPILE);
00058 do_rendering();
00059 glEndList();
00060 }
00061 }
00062
00063 void GLMesh::SubMesh::Render() const {
00064 switch(m_rendering_mode) {
00065 case IMMEDIATE_MODE:
00066 do_rendering();
00067 break;
00068 case DISPLAY_LIST:
00069 glCallList(m_list_name);
00070 break;
00071 }
00072 }
00073
00074 void GLMesh::SubMesh::DisplayNormals() const {
00075 glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_LINE_BIT);
00076
00077 glDisable(GL_LIGHTING);
00078 glDisable(GL_TEXTURE_2D);
00079
00080 glLineWidth(1.0f);
00081 glColor3f(1.0f, 0.0f, 0.0f);
00082
00083
00084 const Real NORMAL_LENGTH = 0.6;
00085
00086 glBegin(GL_LINES);
00087
00088 for(unsigned int i = 0; i < m_faces.size(); ++i) {
00089 const Face &f = m_faces[i];
00090
00091 const Vector3 &n0 = m_normals[f.m_n0];
00092 const Vector3 &n1 = m_normals[f.m_n1];
00093 const Vector3 &n2 = m_normals[f.m_n2];
00094
00095 const Vector3 &v0 = m_vertices[f.m_v0];
00096 const Vector3 &v1 = m_vertices[f.m_v1];
00097 const Vector3 &v2 = m_vertices[f.m_v2];
00098
00099 const Vector3 e0 = v0 + NORMAL_LENGTH * n0;
00100 const Vector3 e1 = v1 + NORMAL_LENGTH * n1;
00101 const Vector3 e2 = v2 + NORMAL_LENGTH * n2;
00102
00103 glVertex3f(v0.m_x, v0.m_y, v0.m_z);
00104 glVertex3f(e0.m_x, e0.m_y, e0.m_z);
00105
00106 glVertex3f(v1.m_x, v1.m_y, v1.m_z);
00107 glVertex3f(e1.m_x, e1.m_y, e1.m_z);
00108
00109 glVertex3f(v2.m_x, v2.m_y, v2.m_z);
00110 glVertex3f(e2.m_x, e2.m_y, e2.m_z);
00111
00112
00113
00114
00115
00116
00117
00118 }
00119
00120 glEnd();
00121
00122 glPopAttrib();
00123 }
00124
00125 void GLMesh::SubMesh::do_rendering() const {
00126 assert(m_material);
00127
00128 m_material->SetActive();
00129
00130 glBegin(GL_TRIANGLES);
00131
00132 if(m_material->GetTexture() && m_texcoords.size() > 0) {
00133 for(FaceVectorConstIt i = m_faces.begin(), e = m_faces.end(); i != e; ++i) {
00134 const Face &f = *i;
00135
00136
00137 assert(m_vertices.size() > 0);
00138 assert(m_texcoords.size() > 0);
00139 assert(m_normals.size() > 0);
00140
00141
00142 assert(f.m_v0 >= 0 && f.m_v0 < static_cast<int>(m_vertices.size()));
00143 assert(f.m_v1 >= 0 && f.m_v1 < static_cast<int>(m_vertices.size()));
00144 assert(f.m_v2 >= 0 && f.m_v2 < static_cast<int>(m_vertices.size()));
00145
00146
00147 assert(f.m_t0 >= 0 && f.m_t0 < static_cast<int>(m_texcoords.size()));
00148 assert(f.m_t1 >= 0 && f.m_t1 < static_cast<int>(m_texcoords.size()));
00149 assert(f.m_t2 >= 0 && f.m_t2 < static_cast<int>(m_texcoords.size()));
00150
00151
00152 assert(f.m_n0 >= 0 && f.m_n0 < static_cast<int>(m_normals.size()));
00153 assert(f.m_n1 >= 0 && f.m_n1 < static_cast<int>(m_normals.size()));
00154 assert(f.m_n2 >= 0 && f.m_n2 < static_cast<int>(m_normals.size()));
00155
00156 const Vector2 &t0 = m_texcoords[f.m_t0];
00157 const Vector2 &t1 = m_texcoords[f.m_t1];
00158 const Vector2 &t2 = m_texcoords[f.m_t2];
00159
00160 const Vector3 &n0 = m_normals[f.m_n0];
00161 const Vector3 &n1 = m_normals[f.m_n1];
00162 const Vector3 &n2 = m_normals[f.m_n2];
00163
00164 const Vector3 &v0 = m_vertices[f.m_v0];
00165 const Vector3 &v1 = m_vertices[f.m_v1];
00166 const Vector3 &v2 = m_vertices[f.m_v2];
00167
00168 glTexCoord2f(t0.m_x, t0.m_y);
00169 glNormal3f(n0.m_x, n0.m_y, n0.m_z);
00170 glVertex3f(v0.m_x, v0.m_y, v0.m_z);
00171
00172 glTexCoord2f(t1.m_x, t1.m_y);
00173 glNormal3f(n1.m_x, n1.m_y, n1.m_z);
00174 glVertex3f(v1.m_x, v1.m_y, v1.m_z);
00175
00176 glTexCoord2f(t2.m_x, t2.m_y);
00177 glNormal3f(n2.m_x, n2.m_y, n2.m_z);
00178 glVertex3f(v2.m_x, v2.m_y, v2.m_z);
00179 }
00180 } else {
00181 for(FaceVectorConstIt i = m_faces.begin(), e = m_faces.end(); i != e; ++i) {
00182 const Face &f = *i;
00183
00184
00185 assert(m_vertices.size() > 0);
00186 assert(m_normals.size() > 0);
00187
00188
00189 assert(f.m_v0 >= 0 && f.m_v0 < static_cast<int>(m_vertices.size()));
00190 assert(f.m_v1 >= 0 && f.m_v1 < static_cast<int>(m_vertices.size()));
00191 assert(f.m_v2 >= 0 && f.m_v2 < static_cast<int>(m_vertices.size()));
00192
00193
00194 assert(f.m_n0 >= 0 && f.m_n0 < static_cast<int>(m_normals.size()));
00195 assert(f.m_n1 >= 0 && f.m_n1 < static_cast<int>(m_normals.size()));
00196 assert(f.m_n2 >= 0 && f.m_n2 < static_cast<int>(m_normals.size()));
00197
00198 const Vector3 &n0 = m_normals[f.m_n0];
00199 const Vector3 &n1 = m_normals[f.m_n1];
00200 const Vector3 &n2 = m_normals[f.m_n2];
00201
00202 const Vector3 &v0 = m_vertices[f.m_v0];
00203 const Vector3 &v1 = m_vertices[f.m_v1];
00204 const Vector3 &v2 = m_vertices[f.m_v2];
00205
00206 glNormal3f(n0.m_x, n0.m_y, n0.m_z);
00207 glVertex3f(v0.m_x, v0.m_y, v0.m_z);
00208
00209 glNormal3f(n1.m_x, n1.m_y, n1.m_z);
00210 glVertex3f(v1.m_x, v1.m_y, v1.m_z);
00211
00212 glNormal3f(n2.m_x, n2.m_y, n2.m_z);
00213 glVertex3f(v2.m_x, v2.m_y, v2.m_z);
00214 }
00215 }
00216
00217 glEnd();
00218 }
00219
00220 GLMesh::GLMesh() :
00221 m_vertex_count(0),
00222 m_face_count(0)
00223 {
00224 }
00225
00226 GLMesh::~GLMesh() {
00227 for(SubMeshVectorConstIt i = m_sub_meshes.begin(), e = m_sub_meshes.end(); i != e; ++i) {
00228 delete *i;
00229 }
00230 }
00231
00232 void GLMesh::Insert(SubMesh *m) {
00233 assert(m);
00234
00235 m_sub_meshes.push_back(m);
00236
00237
00238 m_vertex_count += m->m_vertices.size();
00239 m_face_count += m->m_faces.size();
00240
00241
00242 for(SubMesh::Vector3VectorConstIt i = m->m_vertices.begin(),
00243 e = m->m_vertices.end(); i != e; ++i)
00244 {
00245 m_aabb.Include(*i);
00246 }
00247 }
00248
00249 void GLMesh::FlipFaces() {
00250 for(SubMeshVectorConstIt i = m_sub_meshes.begin(), e = m_sub_meshes.end(); i != e; ++i) {
00251 SubMesh *sub_mesh = *i;
00252
00253
00254 for(SubMesh::FaceVectorIt j = sub_mesh->m_faces.begin(),
00255 e = sub_mesh->m_faces.end(); j != e; ++j)
00256 {
00257 SubMesh::Face &f = *j;
00258
00259 swap(f.m_v1, f.m_v2);
00260 swap(f.m_n1, f.m_n2);
00261 swap(f.m_t1, f.m_t2);
00262 }
00263
00264
00265 for(SubMesh::Vector3VectorIt j = sub_mesh->m_normals.begin(),
00266 e = sub_mesh->m_normals.end(); j != e; ++j)
00267 {
00268 *j = - *j;
00269 }
00270 }
00271 }
00272
00273 void GLMesh::SetupRendering(RenderingMode mode) {
00274 for(SubMeshVectorConstIt i = m_sub_meshes.begin(), e = m_sub_meshes.end(); i != e; ++i) {
00275 (*i)->SetupRendering(mode);
00276 }
00277 }
00278
00279 void GLMesh::Render() const {
00280 for(SubMeshVectorConstIt i = m_sub_meshes.begin(), e = m_sub_meshes.end(); i != e; ++i) {
00281 (*i)->Render();
00282 }
00283 }
00284
00285 void GLMesh::DisplayNormals() const {
00286 for(SubMeshVectorConstIt i = m_sub_meshes.begin(), e = m_sub_meshes.end(); i != e; ++i) {
00287 (*i)->DisplayNormals();
00288 }
00289 }