00001
00008 #include "object.h"
00009
00013
00018 TObject::TObject()
00019 {
00020 type = PRIMITIVE;
00021
00022 pos.LoadIdentity();
00023 rot.LoadIdentity();
00024 scale.Set(1.0,1.0,1.0);
00025 transform.LoadIdentity();
00026 transformed = false;
00027
00028 mat = NULL;
00029 shadow_cast = true;
00030 draw_object = true;
00031 cf_buffer = cr_buffer = render_cubemap = render_cubemap_depth = 0;
00032
00033 instances = 1;
00034 drawmode = GL_TRIANGLES;
00035 vbo.indices = 0;
00036 vbo.vao = 0;
00037 }
00038
00039
00045 TObject::~TObject()
00046 {
00047
00048 if(HasFramebuffer())
00049 {
00050 glDeleteFramebuffers(1, &cf_buffer);
00051 glDeleteRenderbuffers(1, &cr_buffer);
00052 glDeleteTextures(1, &render_cubemap);
00053 glDeleteTextures(1, &render_cubemap_depth);
00054 }
00055
00057 if(vbo.vao != 0)
00058 {
00059 glDeleteVertexArrays(1, &vbo.vao);
00060 glDeleteBuffers(4, vbo.buffer);
00061 }
00062
00063 }
00064
00065
00066
00078 void TObject::Create(const char* _name, int primitive, GLfloat size, GLfloat height, GLint sliceX, GLint sliceY)
00079 {
00080 name = _name;
00081 scale.Set(1.0,1.0,1.0);
00082 mat = NULL;
00083 shadow_cast = true;
00084 refl_size = 256;
00085 draw_object = true;
00086 element_indices = true;
00087 transformed = false;
00088
00089
00090 if(primitive == MY_POINT)
00091 {
00092 type = MY_POINT;
00093 return;
00094 }
00095 else
00096 type = PRIMITIVE;
00097
00098 GLfloat x = size/2;
00099 GLfloat z = height/2;
00100
00101
00102 vector<float> vertices, normals,texcoords;
00103 vector<unsigned int> faces;
00104
00106 unsigned int verts = 0;
00107 switch(primitive)
00108 {
00110 case CUBE:
00111 {
00112 verts = 20;
00113 vbo.indices = 36;
00114 drawmode = GL_TRIANGLES;
00115
00116 float vertices_f[] = { -size,-size,-size, -size,-size,-size, -size,-size,-size,
00117 -size,-size,size, -size,-size,size, -size,-size,size,
00118 size,-size,-size, size,-size,-size, size,-size,-size,
00119 size,-size,size, size,-size,size, size,-size,size,
00120 size,size,-size, size,size,-size,
00121 size,size,size, size,size,size,
00122 -size,size,-size, -size,size,-size,
00123 -size,size,size, -size,size,size
00124 };
00125
00126 float texcoords_f[] = { 0.0,1.0, 1.0,0.0, 0.0,0.0,
00127 0.0,0.0, 1.0,1.0, 0.0,1.0,
00128 1.0,1.0, 0.0,0.0, 1.0,0.0,
00129 1.0,0.0, 0.0,1.0, 1.0,1.0,
00130 1.0,0.0, 0.0,0.0,
00131 1.0,1.0, 0.0,1.0,
00132 0.0,0.0, 1.0,0.0,
00133 0.0,1.0, 1.0,1.0 };
00134
00135 float normals_f[] = { -1.0,-1.0,-1.0, -1.0,-1.0,-1.0, -1.0,-1.0,-1.0,
00136 1.0,-1.0,1.0, 1.0,-1.0,1.0, 1.0,-1.0,1.0,
00137 1.0,-1.0,-1.0, 1.0,-1.0,-1.0, 1.0,-1.0,-1.0,
00138 1.0,-1.0,1.0, 1.0,-1.0,1.0, 1.0,-1.0,1.0,
00139 1.0,1.0,-1.0, 1.0,1.0,-1.0,
00140 1.0,1.0,1.0, 1.0,1.0,1.0,
00141 -1.0,1.0,-1.0, -1.0,1.0,-1.0,
00142 -1.0,1.0,1.0, -1.0,1.0,1.0 };
00143
00144 unsigned int faces_f[] = { 11,5,2, 8,11,2, 14,10,7, 12,14,7, 19,15,13, 17,19,13, 4,18,16, 1,4,16,14,18,3, 3,9,14, 6,0,16, 12,6,16 };
00145
00146 vertices = vector<float>(vertices_f, vertices_f + verts*3);
00147 texcoords = vector<float>(texcoords_f, texcoords_f + verts*2);
00148 normals = vector<float>(normals_f, normals_f + verts*3);
00149 faces = vector<unsigned int>(faces_f, faces_f + vbo.indices);
00150 }
00151 break;
00153 case PLANE:
00154 {
00155 verts = 4;
00156 vbo.indices = 4;
00157 drawmode = GL_TRIANGLE_STRIP;
00158
00159 float vertices_f[] = { -x,0.0,z, x,0.0,z, -x,0.0,-z, x,0.0,-z };
00160 float texcoords_f[] = { 0.0,0.0, 1.0,0.0, 0.0,1.0, 1.0,1.0 };
00161 float normals_f[] = { 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0, 0.0,1.0,0.0 };
00162 unsigned short faces_f[] = { 0,1,2,3 };
00163
00164 vertices = vector<float>(vertices_f, vertices_f + 12);
00165 texcoords = vector<float>(texcoords_f, texcoords_f + 8);
00166 normals = vector<float>(normals_f, normals_f + 12);
00167 faces = vector<unsigned int>(faces_f, faces_f + 4);
00168 }
00169 break;
00171 case STRIP_PLANE:
00172 {
00173 float dx = (float)size/sliceX;
00174 float dy = (float)height/sliceY;
00175 float dtx = 1.0f/sliceX;
00176 float dty = 1.0f/sliceY;
00177
00178
00179 for(int i=0; i<sliceY; i++)
00180 {
00181 for(int j=0; j<sliceX; j++)
00182 {
00183 vertices.push_back(j*dx - size/2.0f); vertices.push_back(0.0f); vertices.push_back(i*dy - height/2.0f);
00184 normals.push_back(0.0); normals.push_back(1.0); normals.push_back(0.0);
00185 texcoords.push_back(j*dtx); texcoords.push_back(i*dty);
00186 }
00187 }
00188
00189 for(int i=0; i<sliceY - 2; i++)
00190 {
00191 for(int j=0; j<sliceX - 2; j++)
00192 {
00193 int shift = i*sliceX;
00194 faces.push_back(shift + j); faces.push_back(shift + j + sliceX); faces.push_back(shift + j + sliceX + 1);
00195 faces.push_back(shift + j); faces.push_back(shift + j + sliceX + 1); faces.push_back(shift + j + 1);
00196 }
00197 }
00198 verts = sliceX * sliceY;
00199 vbo.indices = faces.size();
00200 drawmode = GL_TRIANGLES;
00201 }
00202 break;
00204 case CONE:
00205 return;
00207 case CYLINDER:
00208
00209 return;
00211 case DISK:
00212 return;
00214 case SPHERE:
00215 {
00216 int rings = sliceX;
00217 int segments = sliceY;
00218
00219
00220 verts = (rings + 1)*(segments + 1);
00221 vbo.indices = 2 * rings * (segments + 1);
00222 drawmode = GL_TRIANGLE_STRIP;
00223
00225
00226 float fDeltaRingAngle = ( PI / rings );
00227 float fDeltaSegAngle = ( 2.0f * PI / segments );
00228
00229 unsigned int wVerticeIndex = 0 ;
00230
00231 for( int ring = 0; ring < rings + 1 ; ring++ )
00232 {
00233 float r0 = sin( ring * fDeltaRingAngle );
00234 float y0 = cos( ring * fDeltaRingAngle );
00235
00236
00237 for( int seg = 0; seg < segments + 1 ; seg++ )
00238 {
00239 float x0 = r0 * sin( seg * fDeltaSegAngle );
00240 float z0 = r0 * cos( seg * fDeltaSegAngle );
00241
00242 vertices.push_back(x0*size); vertices.push_back(y0*size); vertices.push_back(z0*size);
00243 normals.push_back(x0); normals.push_back(y0); normals.push_back(z0);
00244 texcoords.push_back((float)seg/segments); texcoords.push_back((float)ring/rings);
00245
00246
00247 if ( ring != rings )
00248 {
00249 faces.push_back(wVerticeIndex);
00250 faces.push_back(wVerticeIndex + (unsigned int)(segments + 1));
00251 wVerticeIndex ++ ;
00252 }
00253 }
00254 }
00255 }
00256 break;
00258 case TORUS:
00259 {
00261 float theta, phi, theta1,
00262 cosTheta, sinTheta,
00263 cosTheta1, sinTheta1,
00264 ringDelta, sideDelta,
00265 cosPhi, sinPhi, dist;
00266 vbo.indices = 0;
00267
00268 sideDelta = 2.0f * PI / sliceX;
00269 ringDelta = 2.0f * PI / sliceY;
00270
00271 theta = 0.0;
00272 cosTheta = 1.0;
00273 sinTheta = 0.0;
00274
00275 for(int i = sliceY - 1; i >= 0; i--)
00276 {
00277 theta1 = theta + ringDelta;
00278 cosTheta1 = cos(theta1);
00279 sinTheta1 = sin(theta1);
00280 phi = 0.0;
00281 for(int j = sliceX; j >= 0; j--)
00282 {
00283 phi = phi + sideDelta;
00284 cosPhi = cos(phi);
00285 sinPhi = sin(phi);
00286 dist = height + (size * cosPhi);
00287
00288 texcoords.push_back(cosTheta1 * cosPhi); texcoords.push_back(-sinTheta1 * cosPhi);
00289 normals.push_back(cosTheta1 * cosPhi); normals.push_back(-sinTheta1 * cosPhi); normals.push_back(sinPhi);
00290 vertices.push_back(cosTheta1 * dist); vertices.push_back(-sinTheta1 * dist); vertices.push_back(size * sinPhi);
00291 faces.push_back(vbo.indices++);
00292
00293 texcoords.push_back(cosTheta * cosPhi); texcoords.push_back(-sinTheta * cosPhi);
00294 normals.push_back(cosTheta * cosPhi); normals.push_back(-sinTheta * cosPhi); normals.push_back(sinPhi);
00295 vertices.push_back(cosTheta * dist); vertices.push_back(-sinTheta * dist); vertices.push_back(size * sinPhi);
00296 faces.push_back(vbo.indices++);
00297 }
00298 theta = theta1;
00299 cosTheta = cosTheta1;
00300 sinTheta = sinTheta1;
00301 }
00302
00303 verts = vbo.indices;
00304 drawmode = GL_TRIANGLE_STRIP;
00305 }
00306 break;
00307 case SCREEN_QUAD:
00308 return;
00309 default:
00310 break;
00311 }
00312
00313 glGenVertexArrays(1, &vbo.vao);
00314 glBindVertexArray(vbo.vao);
00315
00316
00317 glGenBuffers(4, vbo.buffer);
00318
00319
00320 glBindBuffer(GL_ARRAY_BUFFER, vbo.buffer[P_VERTEX]);
00321 glBufferData(GL_ARRAY_BUFFER, 3 * verts * sizeof(float), &vertices[0], GL_DYNAMIC_DRAW);
00322 #ifdef GL3
00323
00324 glVertexAttribPointer(GLuint(0), 3, GL_FLOAT, GL_FALSE, 0, 0);
00325 glEnableVertexAttribArray(0);
00326 #else
00327 glVertexPointer(3, GL_FLOAT, 0, 0);
00328 glEnableClientState(GL_VERTEX_ARRAY);
00329 #endif
00330
00331
00332 glBindBuffer(GL_ARRAY_BUFFER, vbo.buffer[P_NORMAL]);
00333 glBufferData(GL_ARRAY_BUFFER, 3 * verts * sizeof(float), &normals[0], GL_STATIC_DRAW);
00334 #ifdef GL3
00335
00336 glVertexAttribPointer(GLuint(1), 3, GL_FLOAT, GL_FALSE, 0, 0);
00337 glEnableVertexAttribArray(1);
00338 #else
00339 glNormalPointer(GL_FLOAT, 0, 0);
00340 glEnableClientState(GL_NORMAL_ARRAY);
00341 #endif
00342
00343
00344 glBindBuffer(GL_ARRAY_BUFFER, vbo.buffer[P_TEXCOORD]);
00345 glBufferData(GL_ARRAY_BUFFER, 2 * verts * sizeof(float), &texcoords[0], GL_STATIC_DRAW);
00346 #ifdef GL3
00347
00348 glVertexAttribPointer(GLuint(2), 2, GL_FLOAT, GL_FALSE, 0, 0);
00349 glEnableVertexAttribArray(2);
00350 #else
00351 glTexCoordPointer(2, GL_FLOAT, 0, 0);
00352 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00353 #endif
00354
00355
00356 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.buffer[P_INDEX]);
00357 glBufferData(GL_ELEMENT_ARRAY_BUFFER, vbo.indices * sizeof(unsigned int), &faces[0], GL_STATIC_DRAW);
00358 }
00359
00364 void TObject::CreateInstance(const TObject &ref)
00365 {
00366 *this = ref;
00367
00368 type = INSTANCE;
00369 }
00370
00371
00381 void TObject::Draw(TMatrix &viewMatrix, bool render_mat)
00382 {
00383
00384 if(!draw_object)
00385 return;
00386
00387 if( (!render_mat && !shadow_cast) || name == "screen_quad")
00388 return;
00389
00390
00391 glLoadMatrixf(viewMatrix);
00392 glMultMatrixf(transform);
00393
00394
00395 if(mat != NULL && type != INSTANCE)
00396 mat->RenderMaterial(render_mat);
00397
00398
00399 if(type == MY_POINT)
00400 {
00401 glBegin(GL_POINTS);
00402 glVertex4f(0.0,0.0,0.0,1.0);
00403 glEnd();
00404 }
00405 else
00406 {
00407 if(type != INSTANCE)
00408 glBindVertexArray(vbo.vao);
00409
00410 if(element_indices)
00411 {
00412
00413 if(instances > 1)
00414 glDrawElementsInstancedEXT(drawmode, vbo.indices, GL_UNSIGNED_INT , 0, instances);
00415 else
00416 glDrawElements(drawmode, vbo.indices, GL_UNSIGNED_INT , 0);
00417 }
00418 else
00419 {
00420 if(instances > 1)
00421 glDrawArraysInstancedEXT(GL_TRIANGLES, 0, vbo.indices * 3, instances);
00422 else
00423 glDrawArrays(GL_TRIANGLES, 0, vbo.indices * 3);
00424 }
00425 }
00426 }
00427
00434 void TObject::DrawScreenQuad()
00435 {
00436
00437 mat->RenderMaterial();
00438
00439
00440 glBegin(GL_TRIANGLE_STRIP);
00441 glTexCoord2f(0.0,1.0); glVertex2f(-1.0, 1.0);
00442 glTexCoord2f(1.0,1.0); glVertex2f( 1.0, 1.0);
00443 glTexCoord2f(0.0,0.0); glVertex2f(-1.0,-1.0);
00444 glTexCoord2f(1.0,0.0); glVertex2f( 1.0,-1.0);
00445 glEnd();
00446 }
00447
00451
00459 void TObject::Move(GLfloat wx, GLfloat wy, GLfloat wz)
00460 {
00461 pos.x += wx;
00462 pos.y += wy;
00463 pos.z += wz;
00464
00465
00466 glLoadMatrixf(transform);
00467 glTranslatef(wx,wy,wz);
00468 glGetFloatv(GL_MODELVIEW_MATRIX,transform);
00469 transformed = true;
00470 }
00471
00479 void TObject::MoveAbs(GLfloat wx, GLfloat wy, GLfloat wz)
00480 {
00481 pos.x = wx;
00482 pos.y = wy;
00483 pos.z = wz;
00484
00485
00486 glLoadIdentity();
00487 glTranslatef(pos.x,pos.y,pos.z);
00488 glRotatef(rot.x,1.0,0.0,0.0);
00489 glRotatef(rot.y,0.0,1.0,0.0);
00490 glRotatef(rot.z,0.0,0.0,1.0);
00491 glScalef(scale.x,scale.y,scale.z);
00492 glGetFloatv(GL_MODELVIEW_MATRIX,transform);
00493 transformed = true;
00494 }
00495
00502 void TObject::Rotate(GLfloat angle, GLint axis)
00503 {
00504 glLoadMatrixf(transform);
00505 switch(axis)
00506 {
00507 case A_X:
00508 rot.x += angle;
00509 glRotatef(angle,1.0,0.0,0.0);
00510 break;
00511 case A_Y:
00512 rot.y += angle;
00513 glRotatef(angle,0.0,1.0,0.0);
00514 break;
00515 case A_Z:
00516 rot.z += angle;
00517 glRotatef(angle,0.0,0.0,1.0);
00518 break;
00519 default:
00520 break;
00521 }
00522
00523 glGetFloatv(GL_MODELVIEW_MATRIX,transform);
00524 transformed = true;
00525 }
00526
00533 void TObject::RotateAbs(GLfloat angle, GLint axis)
00534 {
00535 glLoadIdentity();
00536 switch(axis)
00537 {
00538 case A_X:
00539 rot.x = angle;
00540 break;
00541 case A_Y:
00542 rot.y = angle;
00543 break;
00544 case A_Z:
00545 rot.z = angle;
00546 break;
00547 default:
00548 break;
00549 }
00550
00551 glTranslatef(pos.x,pos.y,pos.z);
00552 glRotatef(rot.x,1.0,0.0,0.0);
00553 glRotatef(rot.y,0.0,1.0,0.0);
00554 glRotatef(rot.z,0.0,0.0,1.0);
00555 glScalef(scale.x,scale.y,scale.z);
00556 glGetFloatv(GL_MODELVIEW_MATRIX,transform);
00557 transformed = true;
00558 }
00559
00565 void TObject::Resize(GLfloat sx, GLfloat sy, GLfloat sz)
00566 {
00567 scale.x = sx;
00568 scale.y = sy;
00569 scale.z = sz;
00570
00571
00572 glLoadMatrixf(transform);
00573 glScalef(sx,sy,sz);
00574 glGetFloatv(GL_MODELVIEW_MATRIX,transform);
00575 }