00001
00009 #include "object.h"
00010
00011
00012
00013
00014
00015
00016
00023 VBO TObject::Create(Lib3dsMesh *mesh)
00024 {
00025 name = mesh->name;
00026 scale.Set(1.0,1.0,1.0);
00027 mat = NULL;
00028 shadow_cast = true;
00029 refl_size = 256;
00030 draw_object = true;
00031 type = EXTERN;
00032 drawmode = GL_TRIANGLES;
00033 element_indices = false;
00034
00035
00036 vbo.indices = mesh->nfaces;
00037
00038
00039 TVertex *vertices = new TVertex[vbo.indices * 3];
00040 TVertex *normals = new TVertex[vbo.indices * 3];
00041 TCoord *texcoords = new TCoord[vbo.indices * 3];
00042
00043 unsigned int FinishedFaces = 0;
00044 lib3ds_mesh_calculate_vertex_normals(mesh, &normals[FinishedFaces*3]);
00045
00046 for(unsigned curr_face = 0; curr_face < mesh->nfaces; curr_face++)
00047 {
00048 Lib3dsFace *face = &mesh->faces[curr_face];
00049 for(unsigned i = 0; i < 3; i++)
00050 {
00051
00052 memcpy(&vertices[FinishedFaces*3 + i], mesh->vertices[face->index[i]], sizeof(TVertex) );
00053
00054 if(mesh->texcos != NULL)
00055 memcpy(&texcoords[FinishedFaces*3 + i], mesh->texcos[face->index[i]], sizeof(TCoord) );
00056 }
00057 FinishedFaces++;
00058 }
00059
00060 for(unsigned i=0; i<vbo.indices * 3; i++)
00061 {
00062 std::swap(*(vertices[i]+1),*(vertices[i]+2));
00063 *(vertices[i]+2) *= -1.0;
00064 std::swap(*(normals[i]+1),*(normals[i]+2));
00065 *(normals[i]+2) *= -1.0;
00066 }
00067
00068
00069 glGenVertexArrays(1, &vbo.vao);
00070 glBindVertexArray(vbo.vao);
00071
00072
00073 glGenBuffers(4, vbo.buffer);
00074
00075
00076 glBindBuffer(GL_ARRAY_BUFFER, vbo.buffer[P_VERTEX]);
00077 glBufferData(GL_ARRAY_BUFFER, sizeof(TVertex) * 3 * vbo.indices, vertices, GL_STATIC_DRAW);
00078 #ifdef GL3
00079
00080 glVertexAttribPointer(GLuint(0), 3, GL_FLOAT, GL_FALSE, 0, 0);
00081 glEnableVertexAttribArray(0);
00082 #else
00083 glVertexPointer(3, GL_FLOAT, 0, 0);
00084 glEnableClientState(GL_VERTEX_ARRAY);
00085 #endif
00086
00087
00088 glBindBuffer(GL_ARRAY_BUFFER, vbo.buffer[P_NORMAL]);
00089 glBufferData(GL_ARRAY_BUFFER, sizeof(TVertex) * 3 * vbo.indices, normals, GL_STATIC_DRAW);
00090 #ifdef GL3
00091
00092 glVertexAttribPointer(GLuint(1), 3, GL_FLOAT, GL_FALSE, 0, 0);
00093 glEnableVertexAttribArray(1);
00094 #else
00095 glNormalPointer(GL_FLOAT, 0, 0);
00096 glEnableClientState(GL_NORMAL_ARRAY);
00097 #endif
00098
00099
00100 glBindBuffer(GL_ARRAY_BUFFER, vbo.buffer[P_TEXCOORD]);
00101 glBufferData(GL_ARRAY_BUFFER, sizeof(TCoord) * 3 * vbo.indices, texcoords, GL_STATIC_DRAW);
00102 #ifdef GL3
00103
00104 glVertexAttribPointer(GLuint(2), 2, GL_FLOAT, GL_FALSE, 0, 0);
00105 glEnableVertexAttribArray(2);
00106 #else
00107 glTexCoordPointer(2, GL_FLOAT, 0, 0);
00108 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00109 #endif
00110
00111
00112 delete [] vertices;
00113 delete [] normals;
00114 delete [] texcoords;
00115
00116
00117 return vbo;
00118 }
00119
00120
00121
00129 VBO TObject::Create(const char *_name, const char *_file, bool load)
00130 {
00131 name = _name;
00132 scale.Set(1.0,1.0,1.0);
00133 mat = NULL;
00134 shadow_cast = true;
00135 refl_size = 256;
00136 draw_object = true;
00137 type = EXTERN;
00138 drawmode = GL_TRIANGLES;
00139 element_indices = false;
00140
00141
00142 if(!load)
00143 {
00144
00145 glBindVertexArray(vbo.vao);
00146 glBindBuffer(GL_ARRAY_BUFFER, vbo.buffer[P_VERTEX]);
00147 #ifdef GL3
00148
00149 glVertexAttribPointer(GLuint(0), 3, GL_FLOAT, GL_FALSE, 0, 0);
00150 glEnableVertexAttribArray(0);
00151 #else
00152 glVertexPointer(3, GL_FLOAT, 0, 0);
00153 glEnableClientState(GL_VERTEX_ARRAY);
00154 #endif
00155
00156 glBindBuffer(GL_ARRAY_BUFFER, vbo.buffer[P_NORMAL]);
00157 #ifdef GL3
00158
00159 glVertexAttribPointer(GLuint(1), 3, GL_FLOAT, GL_FALSE, 0, 0);
00160 glEnableVertexAttribArray(1);
00161 #else
00162 glNormalPointer(GL_FLOAT, 0, 0);
00163 glEnableClientState(GL_NORMAL_ARRAY);
00164 #endif
00165
00166 glBindBuffer(GL_ARRAY_BUFFER, vbo.buffer[P_TEXCOORD]);
00167 #ifdef GL3
00168
00169 glVertexAttribPointer(GLuint(2), 2, GL_FLOAT, GL_FALSE, 0, 0);
00170 glEnableVertexAttribArray(2);
00171 #else
00172 glTexCoordPointer(2, GL_FLOAT, 0, 0);
00173 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00174 #endif
00175
00176 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.buffer[P_INDEX]);
00177 return vbo;
00178 }
00179
00181
00182 cout<<"Loading object "<<_file<<"...";
00183 Lib3dsFile *model;
00184 model = lib3ds_file_open(_file);
00185 if(!model)
00186 {
00187 ShowMessage("Cannot open 3DS file!",false);
00188 return VBO();
00189 }
00190
00191
00192 vbo.indices = 0;
00193
00194 for(int i=0; i < model->nmeshes; i++)
00195 {
00196
00197 vbo.indices += model->meshes[i]->nfaces;
00198 }
00199
00200
00201 TVertex *vertices = new TVertex[vbo.indices * 3];
00202 TVertex *normals = new TVertex[vbo.indices * 3];
00203 TCoord *texcoords = new TCoord[vbo.indices * 3];
00204
00205 unsigned int FinishedFaces = 0;
00206
00207 for(int curr_mesh = 0; curr_mesh < model->nmeshes; curr_mesh++)
00208 {
00209 Lib3dsMesh *mesh = model->meshes[curr_mesh];
00210 lib3ds_mesh_calculate_vertex_normals(mesh, &normals[FinishedFaces*3]);
00211
00212 for(unsigned curr_face = 0; curr_face < mesh->nfaces; curr_face++)
00213 {
00214 Lib3dsFace *face = &mesh->faces[curr_face];
00215 for(unsigned i = 0; i < 3; i++)
00216 {
00217
00218 memcpy(&vertices[FinishedFaces*3 + i], mesh->vertices[face->index[i]], sizeof(TVertex) );
00219
00220 if(mesh->texcos != NULL)
00221 memcpy(&texcoords[FinishedFaces*3 + i], mesh->texcos[face->index[i]], sizeof(TCoord) );
00222 }
00223 FinishedFaces++;
00224 }
00225 }
00226
00227
00228 for(unsigned i=0; i<vbo.indices * 3; i++)
00229 {
00230 std::swap(*(vertices[i]+1),*(vertices[i]+2));
00231 *(vertices[i]+2) *= -1.0;
00232 std::swap(*(normals[i]+1),*(normals[i]+2));
00233 *(normals[i]+2) *= -1.0;
00234 }
00235
00236
00237 glGenVertexArrays(1, &vbo.vao);
00238 glBindVertexArray(vbo.vao);
00239
00240
00241 glGenBuffers(4, vbo.buffer);
00242
00243
00244 glBindBuffer(GL_ARRAY_BUFFER, vbo.buffer[P_VERTEX]);
00245 glBufferData(GL_ARRAY_BUFFER, sizeof(TVertex) * 3 * vbo.indices, vertices, GL_STATIC_DRAW);
00246 #ifdef GL3
00247
00248 glVertexAttribPointer(GLuint(0), 3, GL_FLOAT, GL_FALSE, 0, 0);
00249 glEnableVertexAttribArray(0);
00250 #else
00251 glVertexPointer(3, GL_FLOAT, 0, 0);
00252 glEnableClientState(GL_VERTEX_ARRAY);
00253 #endif
00254
00255
00256 glBindBuffer(GL_ARRAY_BUFFER, vbo.buffer[P_NORMAL]);
00257 glBufferData(GL_ARRAY_BUFFER, sizeof(TVertex) * 3 * vbo.indices, normals, GL_STATIC_DRAW);
00258 #ifdef GL3
00259
00260 glVertexAttribPointer(GLuint(1), 3, GL_FLOAT, GL_FALSE, 0, 0);
00261 glEnableVertexAttribArray(1);
00262 #else
00263 glNormalPointer(GL_FLOAT, 0, 0);
00264 glEnableClientState(GL_NORMAL_ARRAY);
00265 #endif
00266
00267
00268 glBindBuffer(GL_ARRAY_BUFFER, vbo.buffer[P_TEXCOORD]);
00269 glBufferData(GL_ARRAY_BUFFER, sizeof(TCoord) * 3 * vbo.indices, texcoords, GL_STATIC_DRAW);
00270 #ifdef GL3
00271
00272 glVertexAttribPointer(GLuint(2), 2, GL_FLOAT, GL_FALSE, 0, 0);
00273 glEnableVertexAttribArray(2);
00274 #else
00275 glTexCoordPointer(2, GL_FLOAT, 0, 0);
00276 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00277 #endif
00278
00279
00280 delete [] vertices;
00281 delete [] normals;
00282 delete [] texcoords;
00283
00284
00285 lib3ds_file_free(model);
00286 model = NULL;
00287
00288 cout<<"Done(vertices: "<<vbo.indices*3<<", faces: "<<vbo.indices<<")\n";
00289
00290
00291 return vbo;
00292 }