BambooIsland: C:/Users/easterbunny/Desktop/Echtzeitgraphik-LU/trunk/src/SceneObject_OgreImport.cpp Source File

BambooIsland Abgabe 2

- Main Page
- Related Pages
- Classes
- Files

- File List

# C:/Users/easterbunny/Desktop/Echtzeitgraphik-LU/trunk/src/SceneObject_OgreImport.cpp

    00001 /*
    00002  * source file for SceneObject_OgreImport class
    00003  * written by: christian moellinger <ch.moellinger@gmail.com>
    00004  * 10/2010
    00005  */
    00006
    00007 #include <glm/gtc/matrix_projection.hpp>
    00008 #include <glm/gtc/matrix_transform.hpp>
    00009 #include <glm/gtx/transform.hpp>
    00010 #include <glm/gtx/transform2.hpp>
    00011 #include <glm/gtc/type_ptr.hpp>
    00012
    00013 #include "TextureManager.h"
    00014 #include "Logger.h"
    00015 #include "error.h"
    00016 #include "ShaderManager.h"
    00017 #include "SceneObject_OgreImport.h"
    00018
    00019 #undef DEBUG
    00020
    00021 using namespace std;
    00022
    00023 SceneObject_OgreImport::SceneObject_OgreImport(const char * filename) : SceneObject()
    00024 {
    00025         /************************************************************************/
    00026         /* Load the model                                                       */
    00027         /************************************************************************/
    00028         modelsmanager = Modelsmanager();
    00029         try
    00030         {
    00031                 modelsmanager.loadModel(filename, filename);
    00032         }
    00033         catch (Error *e)
    00034         {
    00035                 e->printMessage();
    00036                 e->printDetails();
    00037         }
    00038         this->model = modelsmanager.getModel(filename);
    00039
    00040         /************************************************************************/
    00041         /* Load textures if there are some                                      */
    00042         /************************************************************************/
    00043         this->realname = string(filename);
    00044         realname.resize(realname.find_first_of("."));
    00045         realname = realname.substr(realname.find_first_of("/")+1);
    00046         this->hasColormap=false;
    00047         this->hasBumpmap = false;
    00048         this->hasNormalmap = false;
    00049
    00050         if (TextureManager::instance()->loadTexture(realname+"Color","textures/"+realname+".color.jpg", true))
    00051         {
    00052                 this->hasColormap = true;
    00053         }
    00054         else
    00055             Logger::instance()->log(Logger::FATAL, string("Could not read color texture for model ") + realname);
    00056
    00057         if (TextureManager::instance()->loadTexture(realname+"Bump","textures/"+realname+".bump.jpg", false)){
    00058                 this->hasBumpmap = true;
    00059         }
    00060         if (TextureManager::instance()->loadTexture(realname+"Normal","textures/"+realname+".normal.jpg", false)){
    00061                 this->hasNormalmap = true;
    00062         }
    00063
    00064         /************************************************************************/
    00065         /* Setup OpenGL Stuff for submesh[0] at the moment                      */
    00066         /************************************************************************/
    00067
    00068         // VAO
    00069         glGenVertexArrays(1, &this->vao);
    00070         glBindVertexArray(this->vao);
    00071
    00072         // Vertexbuffer, Indexbuffer, Normalbuffer, texcoordbuffer generieren
    00073         glGenBuffers(1,&this->vertex_buffer);
    00074         glGenBuffers(1,&this->index_buffer);
    00075
    00076
    00077         // **** send Data to high speed server memory ***
    00078         // vertices
    00079
    00080
    00081         vector<GLfloat> vertexBufferData;
    00082
    00083         GLfloat *raw_vertices = model->Submeshes()[0]->Vertices();
    00084         GLfloat *raw_normals = model->Submeshes()[0]->Normals();
    00085         GLfloat *raw_textures = model->Submeshes()[0]->TexCoords();
    00086         GLfloat *raw_tangents = model->Submeshes()[0]->Tangents();
    00087
    00088         // write vertices data (positions, normals and texcoords in a vector)
    00089         for (int i=0; i < model->Submeshes()[0]->VertexCount(); i++)
    00090         {
    00091             vertexBufferData.push_back(raw_vertices[3*i + 0]);  //push position (x)
    00092             vertexBufferData.push_back(raw_vertices[3*i + 1]);  //push position (y)
    00093             vertexBufferData.push_back(raw_vertices[3*i + 2]);  //push position (z)
    00094             vertexBufferData.push_back(raw_tangents[3*i + 0]);  //push tangent (x)
    00095             vertexBufferData.push_back(raw_tangents[3*i + 1]);  //push tangent (y)
    00096             vertexBufferData.push_back(raw_tangents[3*i + 2]);  //push tangent (z)
    00097             vertexBufferData.push_back(raw_normals[3*i + 0]);   //push normal (x)
    00098             vertexBufferData.push_back(raw_normals[3*i + 1]);   //push normal (y)
    00099             vertexBufferData.push_back(raw_normals[3*i + 2]);   //push normal (z)
    00100             vertexBufferData.push_back(raw_textures[2*i + 0]);  //push texcoord u
    00101             vertexBufferData.push_back(raw_textures[2*i + 1]);  //push texcoord v
    00102         }
    00103
    00104         //create one big array and copy vector contents
    00105         GLfloat *packed_vertex_buffer_data = new GLfloat[vertexBufferData.size()];
    00106
    00107         for (int i=0; i < vertexBufferData.size(); i++)
    00108             packed_vertex_buffer_data[i] = vertexBufferData[i];
    00109
    00110         glBindBuffer(GL_ARRAY_BUFFER, this->vertex_buffer);
    00111         glBufferData(GL_ARRAY_BUFFER, vertexBufferData.size() * sizeof(GLfloat), packed_vertex_buffer_data, GL_STATIC_DRAW);
    00112         // indices
    00113         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,this->index_buffer);
    00114         this->indexArray_size = model->Submeshes()[0]->FaceIndizesArrayLength();
    00115         glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->indexArray_size*sizeof(GLuint), model->Submeshes()[0]->FaceIndizes(), GL_STATIC_DRAW);
    00116
    00117         //check for error
    00118         GLenum error = glGetError();
    00119
    00120         if (error != GL_NO_ERROR)
    00121                 Logger::instance()->log(Logger::ERROR, translateGLerror(error));
    00122
    00123         Logger::instance()->log(Logger::DEBUG, string("Created new SceneObject_OgreImporter1 instance, loaded mesh from \"") + string(filename) + "\"");
    00124         Logger::instance()->log(Logger::DEBUG, string("  found corresponding textures:"));
    00125         Logger::instance()->log(Logger::DEBUG, string("   ")  + realname + ".color.jpg");
    00126
    00127         if (hasBumpmap)
    00128             Logger::instance()->log(Logger::DEBUG, string("   ")  + realname + ".bump.jpg");
    00129         if (hasNormalmap)
    00130             Logger::instance()->log(Logger::DEBUG, string("   ")  + realname + ".normal.jpg");
    00131
    00132         this->isClone = false;      //this object is not a clone, its loaded from file
    00133
    00134         delete this->model;
    00135 }
    00136
    00137
    00138 SceneObject_OgreImport::SceneObject_OgreImport(SceneObject_OgreImport *src)
    00139 {
    00140     this->hasBumpmap = src->hasBumpmap;
    00141     this->hasColormap = src->hasColormap;
    00142     this->hasNormalmap = src->hasNormalmap;
    00143     this->realname = src->realname;
    00144     this->indexArray_size = src->indexArray_size;
    00145     this->index_buffer = src->index_buffer;
    00146     this->vao = src->vao;
    00147     this->vertex_buffer = src->vertex_buffer;
    00148
    00149     this->transformMatrix = src->transformMatrix;
    00150     this->children = src->children;
    00151     this->isClone = true;       //this object is a clone
    00152 }
    00153
    00154 SceneObject_OgreImport::~SceneObject_OgreImport()
    00155 {
    00156 }
    00157
    00158 void SceneObject_OgreImport::itlRender()
    00159 {
    00160         bool our_shader_active;
    00161         /************************************************************************/
    00162         /* DRAW submesh0                                                        */
    00163         /************************************************************************/
    00164         glBindVertexArray(this->vao);
    00165         glBindBuffer(GL_ARRAY_BUFFER, this->vertex_buffer);
    00166
    00167         ShaderManager::instance()->pushActiveShader();
    00168         if (m_tRenderState == LightAsCam)
    00169             ShaderManager::instance()->activateShader("simple_shader");
    00170         else
    00171         if (hasBumpmap && hasNormalmap)
    00172             our_shader_active = ShaderManager::instance()->activateShader("parallax_shader");
    00173         else if (hasNormalmap)
    00174             our_shader_active = ShaderManager::instance()->activateShader("bump_shader");
    00175         else
    00176                 ShaderManager::instance()->activateShader("phong_shader");
    00177
    00178         this->sendTransformMatrices();
    00179
    00180         glm::mat4 initial;
    00181
    00182         glUniformMatrix4fv(ShaderManager::instance()->getUniform("Model_TransformMatrix"), 1, GL_FALSE, &initial[0][0]);
    00183
    00184         //if (ShaderManager::instance()->isActiveShaderLocked() == false)
    00185         this->sendInstancedTransformMatrices();
    00186
    00187
    00188         // tell the shader where to find the data
    00189         const GLint l_in_Position(ShaderManager::instance()->getAttribute("in_Position"));
    00190         const GLint l_tangents(ShaderManager::instance()->getAttribute("in_Tangent"));
    00191         const GLint l_normals(ShaderManager::instance()->getAttribute("in_Normal"));
    00192         const GLint l_texcoords(ShaderManager::instance()->getAttribute("in_Texcoord"));
    00193
    00194         // vertices
    00195         glBindBuffer(GL_ARRAY_BUFFER,this->vertex_buffer);
    00196
    00197         if (l_in_Position != -1)
    00198         {
    00199             glVertexAttribPointer(l_in_Position, 3, GL_FLOAT, GL_FALSE, 11 * sizeof(GLfloat) , NULL);
    00200             glEnableVertexAttribArray(l_in_Position);
    00201         }
    00202
    00203         if (l_normals != -1)
    00204         {
    00205             glVertexAttribPointer(l_normals, 3, GL_FLOAT, GL_FALSE, 11 * sizeof(GLfloat) , (const GLvoid *) (6 * sizeof(GLfloat)) );
    00206             glEnableVertexAttribArray(l_normals);
    00207         }
    00208
    00209         if (l_texcoords != -1)
    00210         {
    00211             glVertexAttribPointer(l_texcoords, 2, GL_FLOAT, GL_FALSE, 11 * sizeof(GLfloat), (const GLvoid *) (9 * sizeof(GLfloat)));
    00212             glEnableVertexAttribArray(l_texcoords);
    00213         }
    00214
    00215         if (l_tangents != -1)
    00216         {
    00217             glVertexAttribPointer(l_tangents, 3, GL_FLOAT, GL_FALSE, 11 * sizeof(GLfloat) , (const GLvoid *) (3 * sizeof(GLfloat)) );
    00218             glEnableVertexAttribArray(l_tangents);
    00219         }
    00220
    00221         GLint l_color_texture = ShaderManager::instance()->getUniform("color_texture");
    00222         if (hasColormap && l_color_texture != -1)
    00223         {
    00224                 GLuint used_texture_unit1 = TextureManager::instance()->useTexture(realname+"Color");       //load texture in texture unit
    00225                 glUniform1i(l_color_texture, used_texture_unit1);   //tell the shader which texture unit was used
    00226         }
    00227
    00228         GLint l_normal_texture = ShaderManager::instance()->getUniform("normal_texture");
    00229         if (hasNormalmap && l_normal_texture != -1)
    00230         {
    00231                 GLuint used_texture_unit2 = TextureManager::instance()->useTexture(realname+"Normal");      //load texture in texture unit
    00232                 glUniform1i(l_normal_texture, used_texture_unit2);   //tell the shader which texture unit was used
    00233         }
    00234
    00235         GLint l_bump_texture = ShaderManager::instance()->getUniform("height_texture");
    00236         if (hasBumpmap && l_normal_texture != -1)
    00237         {
    00238                 GLuint used_texture_unit3 = TextureManager::instance()->useTexture(realname+"Bump");        //load texture in texture unit
    00239                 glUniform1i(l_bump_texture, used_texture_unit3);   //tell the shader which texture unit was used
    00240         }
    00241
    00242         //  glBindBuffer(GL_ARRAY_BUFFER,this->vertex_buffer);
    00243         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,this->index_buffer);
    00244
    00245         GLint l_shadow_texture = ShaderManager::instance()->getUniform("shadowmap");
    00246         if (l_shadow_texture != -1)
    00247         {
    00248                 GLuint texture_unit_shadowmap = TextureManager::instance()->useTexture("fbo_light_color");          //load texture in texture unit
    00249                 glUniform1i(l_shadow_texture, texture_unit_shadowmap);   //tell the shader which texture unit was used
    00250         }
    00251
    00252         glDrawElementsInstanced(GL_TRIANGLES, this->indexArray_size, GL_UNSIGNED_INT, NULL, this->instancedModelTransformMatrices.size());
    00253
    00254         //glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
    00255
    00256         /************************************************************************/
    00257         /* CLEAN UP                                                             */
    00258         /************************************************************************/
    00259         if (hasColormap && l_color_texture != -1)
    00260             TextureManager::instance()->unuseTexture(realname+"Color");     //unload texture in texture unit
    00261
    00262         if (hasNormalmap && l_normal_texture != -1)
    00263             TextureManager::instance()->unuseTexture(realname+"Normal");            //unload texture in texture unit
    00264
    00265         if (hasBumpmap && l_normal_texture != -1)
    00266             TextureManager::instance()->unuseTexture(realname+"Bump");  //unload texture in texture unit
    00267
    00268         if (l_shadow_texture != -1)
    00269         {
    00270                 TextureManager::instance()->unuseTexture("fbo_light_color");    //unload texture in texture unit
    00271         }
    00272
    00273         ShaderManager::instance()->popActiveShader();
    00274 }
    00275
    00276 void SceneObject_OgreImport::sendInstancedTransformMatrices()
    00277 {
    00278     /* this function sends all the instanced matrices to the shader
    00279        the c-style data is prepared each time when the size of the
    00280         vector "instancedModelTransformMatrices" changes
    00281
    00282         edit: the data must be updated every time, else reflection does not work!
    00283
    00284         TODO: yeah, caused by pressure of time, this is not a nice design, make it better!
    00285     */
    00286
    00287     static int old_count_instances = 0;
    00288     static GLfloat matrices_raw[128 * 16];
    00289
    00290     //if (old_count_instances != this->instancedModelTransformMatrices.size())
    00291     {
    00292         glm::mat4 *matrices = new glm::mat4[this->instancedModelTransformMatrices.size()];
    00293         int a = 0;
    00294         for (std::vector<glm::mat4>::iterator iter = this->instancedModelTransformMatrices.begin(); iter < this->instancedModelTransformMatrices.end(); iter++)
    00295             matrices[a++] = this->completeTransformMatrix * (*iter);
    00296
    00297         for (int i=0; i < a; i++)
    00298         {
    00299             matrices_raw[16 * i + 0] = matrices[i][0][0];
    00300             matrices_raw[16 * i + 1] = matrices[i][0][1];
    00301             matrices_raw[16 * i + 2] = matrices[i][0][2];
    00302             matrices_raw[16 * i + 3] = matrices[i][0][3];
    00303             matrices_raw[16 * i + 4] = matrices[i][1][0];
    00304             matrices_raw[16 * i + 5] = matrices[i][1][1];
    00305             matrices_raw[16 * i + 6] = matrices[i][1][2];
    00306             matrices_raw[16 * i + 7] = matrices[i][1][3];
    00307             matrices_raw[16 * i + 8] = matrices[i][2][0];
    00308             matrices_raw[16 * i + 9] = matrices[i][2][1];
    00309             matrices_raw[16 * i + 10] = matrices[i][2][2];
    00310             matrices_raw[16 * i + 11] = matrices[i][2][3];
    00311             matrices_raw[16 * i + 12] = matrices[i][3][0];
    00312             matrices_raw[16 * i + 13] = matrices[i][3][1];
    00313             matrices_raw[16 * i + 14] = matrices[i][3][2];
    00314             matrices_raw[16 * i + 15] = matrices[i][3][3];
    00315         }
    00316
    00317         delete[] matrices;
    00318
    00319         old_count_instances = this->instancedModelTransformMatrices.size();
    00320     }
    00321
    00322     glUniformMatrix4fv(ShaderManager::instance()->getUniform("Model_TransformMatrix"), 128, GL_FALSE, &matrices_raw[0]);
    00323 }
    00324
    00325 void SceneObject_OgreImport::addInstancedTransformMatrix(glm::mat4 mat)
    00326 {
    00327     if (instancedModelTransformMatrices.size() < 128)
    00328         instancedModelTransformMatrices.push_back(mat);
    00329     else
    00330         Logger::instance()->log(Logger::FATAL, "Only 128 instances of an object are allowed!");
    00331 }

All Classes Functions Variables Enumerations Enumerator