00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <GL/glew.h>
00020 #include "rtc/rtcMeshSet3DVBONode.h"
00021
00022 #define VBO_NORMAL 0x01
00023 #define VBO_COLOR 0x02
00024 #define VBO_TEXCOORD 0x04
00025 #define VBO_TEXTURE 0x08
00026
00027 #define CHECKGL while(true){int err=glGetError();if (err==0) break;else printf("OpenGL ERROR: %d, at %s, line %d\n",err,__FILE__,__LINE__);}
00028
00029 namespace rtc {
00030 MeshSet3DVBONode::MeshSet3DVBONode(Renderer* renderer, MeshSet3D* meshset)
00031 :RenderNode(renderer)
00032 {
00033 num_mesh=meshset->numMeshes();
00034 meshvbos=new MeshVBO[num_mesh];
00035 memset(meshvbos,0,sizeof(MeshVBO)*num_mesh);
00036 for (int m=0;m<num_mesh;m++)
00037 {
00038 Mesh3D *mesh=meshset->meshes[m];
00039 MeshVBO *vbo=meshvbos+m;
00040 vbo->num_vertices = mesh->vertices.size();
00041 vbo->num_faces = mesh->faces.size();
00042
00043 vbo->position_size = vbo->num_vertices * 3;
00044 vbo->position_data = new GLfloat[vbo->position_size];
00045
00046 vbo->index_size = vbo->num_faces * 3;
00047 vbo->index_data = new GLuint[vbo->index_size];
00048
00049 vbo->normal_size = vbo->num_vertices * 3;
00050 vbo->normal_data = new GLfloat[vbo->normal_size];
00051 vbo->flag|=VBO_NORMAL;
00052
00053 if(mesh->hasTexture())
00054 {
00055 vbo->texcoord_size = vbo->num_vertices * 2;
00056 vbo->texcoord_data = new GLfloat[vbo->texcoord_size];
00057 vbo->flag|=VBO_TEXCOORD;
00058 }
00059
00060 vbo->color_size = vbo->num_vertices * 3;
00061 vbo->color_data = new GLubyte[vbo->color_size];
00062 vbo->flag|=VBO_COLOR;
00063
00064 for (unsigned int i=0; i<vbo->num_vertices; ++i)
00065 {
00066 vbo->position_data[i * 3] = (GLfloat)mesh->vertices[i]->p[0];
00067 vbo->position_data[i * 3 + 1] = (GLfloat)mesh->vertices[i]->p[1];
00068 vbo->position_data[i * 3 + 2] = (GLfloat)mesh->vertices[i]->p[2];
00069
00070 vbo->normal_data[i * 3] = (GLfloat)mesh->vertices[i]->n[0];
00071 vbo->normal_data[i * 3 + 1] = (GLfloat)mesh->vertices[i]->n[1];
00072 vbo->normal_data[i * 3 + 2] = (GLfloat)mesh->vertices[i]->n[2];
00073
00074 if(mesh->hasTexture())
00075 {
00076 vbo->texcoord_data[i * 2] = (GLfloat)mesh->vertices[i]->t[0];
00077 vbo->texcoord_data[i * 2 + 1] = (GLfloat)mesh->vertices[i]->t[1];
00078 }
00079
00080
00081 vbo->color_data[i * 3] = (GLubyte)mesh->vertices[i]->c[0];
00082 vbo->color_data[i * 3 + 1] = (GLubyte)mesh->vertices[i]->c[1];
00083 vbo->color_data[i * 3 + 2] = (GLubyte)mesh->vertices[i]->c[2];
00084 }
00085
00086 for (unsigned int i=0; i<vbo->num_faces; ++i)
00087 {
00088 vbo->index_data[i * 3 ] = mesh->faces[i]->v(0);
00089 vbo->index_data[i * 3 + 1] = mesh->faces[i]->v(1);
00090 vbo->index_data[i * 3 + 2] = mesh->faces[i]->v(2);
00091 }
00092
00093 if(mesh->hasTexture())
00094 {
00095 vbo->texture_width=mesh->teximage.columns();
00096 vbo->texture_height=mesh->teximage.rows();
00097 vbo->texture_size=vbo->texture_width*vbo->texture_height*3;
00098 vbo->texture_data=new GLubyte[vbo->texture_size];
00099 memcpy(vbo->texture_data,mesh->teximage.x,vbo->texture_size*sizeof(GLubyte));
00100 vbo->flag|=VBO_TEXTURE;
00101 }
00102 }
00103 }
00104
00105 MeshSet3DVBONode::MeshSet3DVBONode( Renderer* renderer, const char* vbofilename )
00106 :RenderNode(renderer)
00107 {
00108 size_t res = 0;
00109 FILE *fp=fopen(vbofilename,"rb");
00110 if (fp==NULL)
00111 {
00112 printf("Open file %s failed\n",vbofilename);
00113 return;
00114 }
00115 res+=fread(&num_mesh,sizeof(num_mesh),1,fp);
00116 meshvbos=new MeshVBO[num_mesh];
00117 memset(meshvbos,0,sizeof(MeshVBO)*num_mesh);
00118 for (int i=0;i<num_mesh;i++)
00119 meshvbos[i].read(fp);
00120 fclose(fp);
00121 }
00122
00123 MeshSet3DVBONode::MeshSet3DVBONode( Renderer* renderer, FILE* fp )
00124 :RenderNode(renderer)
00125 {
00126 size_t res = 0;
00127 res+=fread(&num_mesh,sizeof(num_mesh),1,fp);
00128 meshvbos=new MeshVBO[num_mesh];
00129 memset(meshvbos,0,sizeof(MeshVBO)*num_mesh);
00130 for (int i=0;i<num_mesh;i++)
00131 meshvbos[i].read(fp);
00132 }
00133
00134 MeshSet3DVBONode::~MeshSet3DVBONode()
00135 {
00136 delete[] meshvbos;
00137 meshvbos=NULL;
00138 }
00139
00140 void MeshSet3DVBONode::render()
00141 {
00142 glEnable(GL_COLOR_MATERIAL);
00143
00144
00145
00146 if(m_params->draw_vertices)
00147 drawPointsVBO();
00148 CHECKGL
00149
00150 if(m_params->draw_wireframe)
00151 drawWireFrameVBO();
00152 CHECKGL
00153
00154 if(m_params->draw_faces)
00155 drawFacesVBO();
00156 CHECKGL
00157
00158 }
00159
00160 void MeshSet3DVBONode::drawFacesVBO()
00161 {
00162 glDisable(GL_LIGHTING);
00163 glLineWidth(2.0);
00164 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00165
00166 int f=VBO_NORMAL;
00167 switch(m_params->color_mode)
00168 {
00169 case Parameters::NO_COLOR: break;
00170 case Parameters::VERTEX_COLOR: f|=VBO_COLOR; break;
00171 case Parameters::TEXTURE_COLOR: f|=VBO_TEXCOORD|VBO_TEXTURE;break;
00172 }
00173
00174 for (int i=0;i<num_mesh;i++)
00175 {
00176 meshvbos[i].bind(f);
00177 glDrawElements(GL_TRIANGLES, meshvbos[i].num_faces*3, GL_UNSIGNED_INT, 0);
00178 meshvbos[i].unbind(f);
00179 }
00180 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00181 }
00182
00183 void MeshSet3DVBONode::drawPointsVBO()
00184 {
00185 glDisable(GL_LIGHTING);
00186
00187 int f=VBO_NORMAL;
00188 switch(m_params->color_mode)
00189 {
00190 case Parameters::NO_COLOR: break;
00191 case Parameters::VERTEX_COLOR: f|=VBO_COLOR; break;
00192 case Parameters::TEXTURE_COLOR: f|=VBO_TEXCOORD|VBO_TEXTURE;break;
00193 }
00194
00195 for (int i=0;i<num_mesh;i++)
00196 {
00197 meshvbos[i].bind(f);
00198 glDrawArrays(GL_POINTS, 0, meshvbos[i].num_vertices);
00199 meshvbos[i].unbind(f);
00200 }
00201
00202 }
00203
00204 void MeshSet3DVBONode::drawWireFrameVBO()
00205 {
00206 glDisable(GL_LIGHTING);
00207 glLineWidth(2.0);
00208 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00209
00210 int f=VBO_NORMAL;
00211 switch(m_params->color_mode)
00212 {
00213 case Parameters::NO_COLOR: break;
00214 case Parameters::VERTEX_COLOR: f|=VBO_COLOR; break;
00215 case Parameters::TEXTURE_COLOR: f|=VBO_TEXCOORD|VBO_TEXTURE;break;
00216 }
00217
00218 for (int i=0;i<num_mesh;i++)
00219 {
00220 meshvbos[i].bind(f);
00221 glDrawElements(GL_TRIANGLES, meshvbos[i].num_faces*3, GL_UNSIGNED_INT, 0);
00222 meshvbos[i].unbind(f);
00223 }
00224 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00225 }
00226
00227 void MeshSet3DVBONode::loadToGPU()
00228 {
00229 for (int i=0;i<num_mesh;i++)
00230 meshvbos[i].loadGPU();
00231 }
00232
00233 void MeshSet3DVBONode::unloadGPU()
00234 {
00235 for (int i=0;i<num_mesh;i++)
00236 meshvbos[i].unloadGPU();
00237 }
00238
00239 void MeshSet3DVBONode::writeToFile( const char *filename )
00240 {
00241 FILE *fp=fopen(filename,"wb");
00242 if (fp==NULL)
00243 {
00244 printf("Open file %s failed\n",filename);
00245 return;
00246 }
00247 write(fp);
00248 fclose(fp);
00249 }
00250
00251 void MeshSet3DVBONode::write( FILE* fp )
00252 {
00253 fwrite(&num_mesh,sizeof(num_mesh),1,fp);
00254 for (int i=0;i<num_mesh;i++)
00255 meshvbos[i].write(fp);
00256 }
00257
00259
00260 void MeshSet3DVBONode::MeshVBO::read( FILE* fp )
00261 {
00262 size_t res = 0;
00264 memset(this,0,sizeof(MeshSet3DVBONode::MeshVBO));
00265 res+=fread(&flag,sizeof(flag),1,fp);
00266 res+=fread(&num_vertices,sizeof(num_vertices),1,fp);
00267 res+=fread(&num_faces,sizeof(num_faces),1,fp);
00268
00269 res+=fread(&position_size,sizeof(position_size),1,fp);
00270 position_data=new GLfloat[position_size];
00271 res+=fread(position_data,sizeof(GLfloat),position_size,fp);
00272
00273 res+=fread(&index_size,sizeof(index_size),1,fp);
00274 index_data=new GLuint[index_size];
00275 res+=fread(index_data,sizeof(GLuint),index_size,fp);
00276
00277 if ((flag&VBO_NORMAL)!=0)
00278 {
00279 res+=fread(&normal_size,sizeof(normal_size),1,fp);
00280 normal_data=new GLfloat[normal_size];
00281 res+=fread(normal_data,sizeof(GLfloat),normal_size,fp);
00282 }
00283 if ((flag&VBO_COLOR)!=0)
00284 {
00285 res+=fread(&color_size,sizeof(color_size),1,fp);
00286 color_data=new GLubyte[color_size];
00287 res+=fread(color_data,sizeof(GLubyte),color_size,fp);
00288 }
00289 if ((flag&VBO_TEXCOORD)!=0)
00290 {
00291 res+=fread(&texcoord_size,sizeof(texcoord_size),1,fp);
00292 texcoord_data=new GLfloat[texcoord_size];
00293 res+=fread(texcoord_data,sizeof(GLfloat),texcoord_size,fp);
00294 }
00295 if ((flag&VBO_TEXTURE)!=0)
00296 {
00297 res+=fread(&texture_size,sizeof(texture_size),1,fp);
00298 texture_data=new GLubyte[texture_size];
00299 res+=fread(texture_data,sizeof(GLubyte),texture_size,fp);
00300 res+=fread(&texture_width,sizeof(texture_width),1,fp);
00301 res+=fread(&texture_height,sizeof(texture_height),1,fp);
00302 }
00303 }
00304
00305 void MeshSet3DVBONode::MeshVBO::write( FILE* fp )
00306 {
00307 fwrite(&flag,sizeof(flag),1,fp);
00308 fwrite(&num_vertices,sizeof(num_vertices),1,fp);
00309 fwrite(&num_faces,sizeof(num_faces),1,fp);
00310 fwrite(&position_size,sizeof(position_size),1,fp);
00311 fwrite(position_data,sizeof(GLfloat),position_size,fp);
00312 fwrite(&index_size,sizeof(index_size),1,fp);
00313 fwrite(index_data,sizeof(GLuint),index_size,fp);
00314 if ((flag&VBO_NORMAL)!=0)
00315 {
00316 fwrite(&normal_size,sizeof(normal_size),1,fp);
00317 fwrite(normal_data,sizeof(GLfloat),normal_size,fp);
00318 }
00319 if ((flag&VBO_COLOR)!=0)
00320 {
00321 fwrite(&color_size,sizeof(color_size),1,fp);
00322 fwrite(color_data,sizeof(GLubyte),color_size,fp);
00323 }
00324 if ((flag&VBO_TEXCOORD)!=0)
00325 {
00326 fwrite(&texcoord_size,sizeof(texcoord_size),1,fp);
00327 fwrite(texcoord_data,sizeof(GLfloat),texcoord_size,fp);
00328 }
00329 if ((flag&VBO_TEXTURE)!=0)
00330 {
00331 fwrite(&texture_size,sizeof(texture_size),1,fp);
00332 fwrite(texture_data,sizeof(GLubyte),texture_size,fp);
00333 fwrite(&texture_width,sizeof(texture_width),1,fp);
00334 fwrite(&texture_height,sizeof(texture_height),1,fp);
00335 }
00336 }
00337
00338 void MeshSet3DVBONode::MeshVBO::loadGPU()
00339 {
00340 CHECKGL
00341 getGPUBuffer(position_buffer);
00342 glBindBufferARB(GL_ARRAY_BUFFER_ARB, position_buffer);
00343 glBufferDataARB(GL_ARRAY_BUFFER_ARB, position_size*sizeof(GLfloat), position_data, GL_STATIC_DRAW_ARB);
00344 CHECKGL
00345
00346 getGPUBuffer(index_buffer);
00347 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, index_buffer);
00348 glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, index_size*sizeof(GLuint), index_data, GL_STATIC_DRAW_ARB);
00349 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
00350 CHECKGL
00351
00352 if ((flag&VBO_NORMAL)!=0)
00353 {
00354 getGPUBuffer(normal_buffer);
00355 glBindBufferARB(GL_ARRAY_BUFFER_ARB, normal_buffer);
00356 glBufferDataARB(GL_ARRAY_BUFFER_ARB, normal_size*sizeof(GLfloat), normal_data, GL_STATIC_DRAW_ARB);
00357 }
00358 CHECKGL
00359
00360 if ((flag&VBO_COLOR)!=0)
00361 {
00362 getGPUBuffer(color_buffer);
00363 glBindBufferARB(GL_ARRAY_BUFFER_ARB, color_buffer);
00364 glBufferDataARB(GL_ARRAY_BUFFER_ARB, color_size*sizeof(GLubyte), color_data, GL_STATIC_DRAW_ARB);
00365 }
00366 CHECKGL
00367
00368 if ((flag&VBO_TEXCOORD)!=0)
00369 {
00370 getGPUBuffer(texcoord_buffer);
00371 glBindBufferARB(GL_ARRAY_BUFFER_ARB, texcoord_buffer);
00372 glBufferDataARB(GL_ARRAY_BUFFER_ARB, texcoord_size*sizeof(GLfloat), texcoord_data, GL_STATIC_DRAW_ARB);
00373 }
00374 CHECKGL
00375 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
00376
00377 if ((flag&VBO_TEXTURE)!=0)
00378 {
00379 getTextureId(texture_id);
00380 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00381 glBindTexture(GL_TEXTURE_2D, texture_id);
00382 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
00383 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
00384 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00385 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00386 glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,texture_width,texture_height,0,GL_RGB,GL_UNSIGNED_BYTE,texture_data);
00387 glDisable(GL_TEXTURE_2D);
00388 }
00389 CHECKGL
00390
00391 }
00392
00393 void MeshSet3DVBONode::MeshVBO::unloadGPU()
00394 {
00395 retGPUBuffer(position_buffer);
00396 retGPUBuffer(index_buffer);
00397
00398 if ((flag&VBO_NORMAL)!=0)
00399 {
00400 retGPUBuffer(normal_buffer);
00401 }
00402
00403 if ((flag&VBO_COLOR)!=0)
00404 {
00405 retGPUBuffer(color_buffer);
00406 }
00407
00408 if ((flag&VBO_TEXCOORD)!=0)
00409 {
00410 retGPUBuffer(texcoord_buffer);
00411 }
00412
00413 if ((flag&VBO_TEXTURE)!=0)
00414 {
00415 retTextureId(texture_id);
00416 }
00417 }
00418
00419 void MeshSet3DVBONode::MeshVBO::bind( unsigned int vbo )
00420 {
00421 glEnableClientState(GL_VERTEX_ARRAY);
00422 glBindBufferARB(GL_ARRAY_BUFFER_ARB, position_buffer);
00423 glVertexPointer(3, GL_FLOAT, 0, 0);
00424
00425 glEnableClientState(GL_INDEX_ARRAY);
00426 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, index_buffer);
00427 glIndexPointer(GL_INT, 0, 0);
00428
00429 if ((vbo&VBO_NORMAL)!=0 && (flag&VBO_NORMAL)!=0)
00430 {
00431 glEnableClientState(GL_NORMAL_ARRAY);
00432 glBindBufferARB(GL_ARRAY_BUFFER_ARB, normal_buffer);
00433 glNormalPointer(GL_FLOAT, 0, 0);
00434 }
00435
00436 if ((vbo&VBO_COLOR)!=0 && (flag&VBO_COLOR)!=0)
00437 {
00438 glDisable(GL_TEXTURE_2D);
00439 glEnableClientState(GL_COLOR_ARRAY);
00440 glBindBufferARB(GL_ARRAY_BUFFER_ARB, color_buffer);
00441 glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0);
00442 }
00443
00444 if ((vbo&VBO_TEXCOORD)!=0 && (flag&VBO_TEXCOORD)!=0)
00445 {
00446 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00447 glBindBufferARB(GL_ARRAY_BUFFER_ARB, texcoord_buffer);
00448 glTexCoordPointer(2, GL_FLOAT, 0, 0);
00449 glColor3f(1,1,1);
00450 }
00451
00452 if ((vbo&VBO_TEXTURE)!=0 && (flag&VBO_TEXTURE)!=0)
00453 {
00454 glEnable(GL_TEXTURE_2D);
00455 glActiveTexture(GL_TEXTURE0);
00456 glBindTexture(GL_TEXTURE_2D, texture_id);
00457 }
00458 }
00459
00460 void MeshSet3DVBONode::MeshVBO::unbind( unsigned int vbo )
00461 {
00462 glDisableClientState(GL_VERTEX_ARRAY);
00463 glDisableClientState(GL_INDEX_ARRAY);
00464 if ((vbo&VBO_NORMAL)!=0)
00465 {
00466 glDisableClientState(GL_NORMAL_ARRAY);
00467 }
00468 if ((vbo&VBO_COLOR)!=0)
00469 {
00470 glDisableClientState(GL_COLOR_ARRAY);
00471 }
00472 if ((vbo&VBO_TEXCOORD)!=0)
00473 {
00474 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00475 }
00476 if ((vbo&VBO_TEXTURE)!=0)
00477 {
00478 glActiveTexture(GL_TEXTURE0);
00479 glBindTexture(GL_TEXTURE_2D, 0);
00480 glDisable(GL_TEXTURE_2D);
00481 }
00482 }
00483
00484 MeshSet3DVBONode::MeshVBO::~MeshVBO()
00485 {
00486 delete position_data;
00487 delete normal_data;
00488 delete color_data;
00489 delete texcoord_data;
00490 delete index_data;
00491 delete texture_data;
00492 }
00494 std::vector<GLuint> MeshSet3DVBONode::gpubuffers;
00495 std::vector<GLuint> MeshSet3DVBONode::gputextures;
00496 void MeshSet3DVBONode::getGPUBuffer(GLuint &buffer)
00497 {
00498 if (gpubuffers.empty())
00499 {
00500 glGenBuffersARB(1, &buffer);
00501 CHECKGL
00502 }
00503 else
00504 {
00505 buffer=gpubuffers.back();
00506 gpubuffers.pop_back();
00507 }
00508 }
00509 void MeshSet3DVBONode::retGPUBuffer(GLuint &buffer)
00510 {
00511 gpubuffers.push_back(buffer);
00512 glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer);
00513 glBufferDataARB(GL_ARRAY_BUFFER_ARB, 0, NULL, GL_STATIC_DRAW_ARB);
00514 glBindBufferARB(GL_ARRAY_BUFFER_ARB,0);
00515 buffer=0;
00516 }
00517 void MeshSet3DVBONode::getTextureId(GLuint &texid)
00518 {
00519 if (gputextures.empty())
00520 {
00521 glGenTextures(1, &texid);
00522 }
00523 else
00524 {
00525 texid=gputextures.back();
00526 gputextures.pop_back();
00527 }
00528 }
00529 void MeshSet3DVBONode::retTextureId(GLuint &texid)
00530 {
00531 gputextures.push_back(texid);
00532
00533
00534
00535
00536 texid=0;
00537 }
00538
00539 }