Ejemplo n.º 1
0
//----------------------------------------------------------------------------- 
//! SLGLShader::createAndCompile creates & compiles the OpenGL shader object
SLbool SLGLShader::createAndCompile()
{  
    // delete if object already exits
    if (_objectGL) glDeleteShader(_objectGL);

    if (_code!="")
    {  
        switch (_type)
        {   case VertexShader:
                _objectGL = glCreateShader(GL_VERTEX_SHADER); break;
            case FragmentShader:
                _objectGL = glCreateShader(GL_FRAGMENT_SHADER); break;
            default:
                SL_EXIT_MSG("SLGLShader::load: Unknown shader type.");
        }
      
        //SLstring verGLSL = SLGLState::getInstance()->glSLVersionNO();
        //SLstring srcVersion = "#version " + verGLSL + "\n";

        //if (verGLSL > "120")
        //{   if (_type == VertexShader)
        //    {   SLUtils::replaceString(_code, "attribute", "in");
        //        SLUtils::replaceString(_code, "varying", "out");
        //    }
        //    if (_type == FragmentShader)
        //    {   SLUtils::replaceString(_code, "varying", "in");
        //    }
        //}
        //SLstring scrComplete = srcVersion + _code;

        SLstring scrComplete = _code;

        const char* src = scrComplete.c_str();
        glShaderSource(_objectGL, 1, &src, 0);
        glCompileShader(_objectGL);

        // Check compiler log
        SLint compileSuccess = 0;
        glGetShaderiv(_objectGL, GL_COMPILE_STATUS, &compileSuccess);
        if (compileSuccess == GL_FALSE) 
        {   GLchar log[256];
            glGetShaderInfoLog(_objectGL, sizeof(log), 0, &log[0]);
            SL_LOG("*** COMPILER ERROR ***\n");
            SL_LOG("Source file: %s\n", _file.c_str());
            SL_LOG("%s\n\n", log);
            return false;
        }
        return true;
    } else SL_WARN_MSG("SLGLShader::createAndCompile: Nothing to compile!");
    return false;
}
Ejemplo n.º 2
0
/*! The destructor does the final total deallocation of all global resources.
*/
SLScene::~SLScene()
{
   unInit();
   
   // delete global SLGLState instance
   SLGLState::deleteInstance();

   // clear light pointers
   _lights.clear();
   
   // delete materials 
   for (SLuint i=0; i<_materials.size(); ++i) delete _materials[i];
   _materials.clear();
   
   // delete textures
   for (SLuint i=0; i<_textures.size(); ++i) delete _textures[i];
   _textures.clear();
   
   // delete shader programs
   for (SLuint i=0; i<_shaderProgs.size(); ++i) delete _shaderProgs[i];
   _shaderProgs.clear();
   
   // delete fonts   
   SLTexFont::deleteFonts();
   
   // delete menus & statistic texts
   delete _menuGL;      _menuGL     = 0;
   delete _menuRT;      _menuRT     = 0;
   delete _menuPT;      _menuPT     = 0;
   delete _info;        _info       = 0;
   delete _infoGL;      _infoGL     = 0;
   delete _infoRT;      _infoRT     = 0;
   delete _btnAbout;    _btnAbout   = 0;
   delete _btnHelp;     _btnHelp    = 0;
   delete _btnCredits;  _btnCredits = 0;
   
   current = 0;

   SL_LOG("~SLScene\n");
   SL_LOG("------------------------------------------------------------------\n");
}
Ejemplo n.º 3
0
//-----------------------------------------------------------------------------
//! SLGLShader::load loads a shader file into string _shaderSource
void SLGLShader::load(SLstring filename)
{  
    fstream shaderFile(filename.c_str(), ios::in);
    
    if (!shaderFile.is_open())
    {   SL_LOG("File open failed: %s\n", filename.c_str());
        exit(1);
    }
   
    std::stringstream buffer;
    buffer << shaderFile.rdbuf(); 

    // remove comments because some stupid ARM compiler can't handle GLSL comments
    #ifdef SL_OS_MACIOS
    _code = buffer.str();
    #else
    _code = SLUtils::removeComments(buffer.str());
    #endif
}
Ejemplo n.º 4
0
/*!
SLRay::prints prints the rays origin (O), direction (D) and the length to the 
intersection (L) 
*/
void SLRay::print()
{  SL_LOG("Ray: O(%.2f, %.2f, %.2f), D(%.2f, %.2f, %.2f), L: %.2f\n",
          origin.x,origin.y,origin.z, dir.x,dir.y,dir.z, length);
}
Ejemplo n.º 5
0
/*!
SLAssimpImporter::loadMesh creates a new SLMesh an copies the meshs vertex data and
triangle face indices. Normals & tangents are not loaded. They are calculated
in SLMesh.
*/
SLMesh* SLAssimpImporter::loadMesh(aiMesh *mesh)
{
    // Count first the NO. of triangles in the mesh
    SLuint numTriangles = 0;
    for(unsigned int i = 0; i <  mesh->mNumFaces; ++i)
        if(mesh->mFaces[i].mNumIndices == 3)
            numTriangles++;

    // We only load meshes that contain triangles
    if (numTriangles==0 || mesh->mNumVertices==0)
        return nullptr; 

    // create a new mesh. 
    // The mesh pointer is added automatically to the SLScene::meshes vector.
    SLstring name = mesh->mName.data;
    SLMesh *m = new SLMesh(name.empty() ? "Imported Mesh" : name);

    // create position & normal vector
    m->P.clear(); m->P.resize(mesh->mNumVertices);

    // create normal vector
    if (mesh->HasNormals())
    {   m->N.clear();
        m->N.resize(m->P.size());
    }

    // allocate texCoord vector if needed
    if (mesh->HasTextureCoords(0))
    {   m->Tc.clear();
        m->Tc.resize(m->P.size());
    }

    // copy vertex positions & texCoord
    for(SLuint i = 0; i < m->P.size(); ++i)
    {   m->P[i].set(mesh->mVertices[i].x, 
        mesh->mVertices[i].y, 
        mesh->mVertices[i].z);
        if (m->N.size())
            m->N[i].set(mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z);
        if (m->Tc.size())
            m->Tc[i].set(mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].y);
    }

    // create face index vector
    if (m->P.size() < 65536)
    {   m->I16.clear();
        m->I16.resize(mesh->mNumFaces * 3);

        // load face triangle indices only
        SLuint j = 0;
        for(SLuint i = 0; i <  mesh->mNumFaces; ++i)
        {   if(mesh->mFaces[i].mNumIndices == 3)
            {   m->I16[j++] = mesh->mFaces[i].mIndices[0];
                m->I16[j++] = mesh->mFaces[i].mIndices[1];
                m->I16[j++] = mesh->mFaces[i].mIndices[2];
            }
        }
    } else 
    {   m->I32.clear();
        m->I32.resize(mesh->mNumFaces * 3);

        // load face triangle indices only
        SLuint j = 0;
        for(SLuint i = 0; i <  mesh->mNumFaces; ++i)
        {  if(mesh->mFaces[i].mNumIndices == 3)
            {   m->I32[j++] = mesh->mFaces[i].mIndices[0];
                m->I32[j++] = mesh->mFaces[i].mIndices[1];
                m->I32[j++] = mesh->mFaces[i].mIndices[2];
            }
        }
    }

    if (!m->N.size())
        m->calcNormals();

    // load joints
    if (mesh->HasBones())
    {
        _skinnedMeshes.push_back(m);
        m->skeleton(_skeleton);

        m->Ji.resize(m->P.size());
        m->Jw.resize(m->P.size());
        
        // make sure to initialize the weights with 0 vectors
        std::fill(m->Ji.begin(), m->Ji.end(), SLVec4f(0, 0, 0, 0));
        std::fill(m->Jw.begin(), m->Jw.end(), SLVec4f(0, 0, 0, 0));

        for (SLuint i = 0; i < mesh->mNumBones; i++)
        {
            aiBone* joint = mesh->mBones[i];
            SLJoint* slJoint = _skeleton->getJoint(joint->mName.C_Str());
            
            // @todo On OSX it happens from time to time that slJoint is nullptr
            if (slJoint)
            {
                SLuint jointId = slJoint->id();

                for (SLuint j = 0; j < joint->mNumWeights; j++)
                {
                    // add the weight
                    SLuint vertId = joint->mWeights[j].mVertexId;
                    SLfloat weight = joint->mWeights[j].mWeight;

                    m->addWeight(vertId, jointId, weight);

                    // check if the bones max radius changed
                    // @todo this is very specific to this loaded mesh,
                    //       when we add a skeleton instances class this radius
                    //       calculation has to be done on the instance!
                    slJoint->calcMaxRadius(SLVec3f(mesh->mVertices[vertId].x,
                                                   mesh->mVertices[vertId].y,
                                                   mesh->mVertices[vertId].z));
                }
            }
            else
            {   SL_LOG("Failed to load joint of skeleton in SLAssimpImporter::loadMesh: %s\n", joint->mName.C_Str());
                return nullptr;
            }
        }

    }
    return m;
}
Ejemplo n.º 6
0
/*! Loads the scene from a file and creates materials with textures, the 
meshes and the nodes for the scene graph. Materials, textures and meshes are
added to the according vectors of SLScene for later deallocation.
*/
SLNode* SLAssimpImporter::load(SLstring file,           //!< File with path or on default path
                               SLbool loadMeshesOnly,   //!< Only load nodes with meshes
                               SLuint flags)            //!< Import flags (see assimp/postprocess.h)
{
    // clear the intermediate data
    clear();

    // Check existance
    if (!SLFileSystem::fileExists(file))
    {   file = defaultPath + file;
        if (!SLFileSystem::fileExists(file))
        {   SLstring msg = "SLAssimpImporter: File not found: " + file + "\n";
            SL_WARN_MSG(msg.c_str());
            return nullptr;
        }
    }

    // Import file with assimp importer
    Assimp::Importer ai;
    const aiScene* scene = ai.ReadFile(file.c_str(), (SLuint)flags);
    if (!scene)
    {   SLstring msg = "Failed to load file: " + file + "\n" + ai.GetErrorString() + "\n";
        SL_WARN_MSG(msg.c_str());
        return nullptr;
    }

    // initial scan of the scene
    performInitialScan(scene);

    // load skeleton
    loadSkeleton(nullptr, _skeletonRoot);

    // load materials
    SLstring modelPath = SLUtils::getPath(file);
    SLVMaterial materials;
    for(SLint i = 0; i < (SLint)scene->mNumMaterials; i++)
        materials.push_back(loadMaterial(i, scene->mMaterials[i], modelPath));

    // load meshes & set their material
    std::map<int, SLMesh*> meshMap;  // map from the ai index to our mesh
    for(SLint i = 0; i < (SLint)scene->mNumMeshes; i++)
    {   SLMesh* mesh = loadMesh(scene->mMeshes[i]);
        if (mesh != 0)
        {   mesh->mat = materials[scene->mMeshes[i]->mMaterialIndex];
            _meshes.push_back(mesh);
            meshMap[i] = mesh;
        } else SL_LOG("SLAsssimpImporter::load failed: %s\nin path: %s\n", file.c_str(), modelPath.c_str());
    }

    // load the scene nodes recursively
    _sceneRoot = loadNodesRec(nullptr, scene->mRootNode, meshMap, loadMeshesOnly);

    // load animations
    vector<SLAnimation*> animations;
    for (SLint i = 0; i < (SLint)scene->mNumAnimations; i++)
        animations.push_back(loadAnimation(scene->mAnimations[i]));

    logMessage(LV_minimal, "\n---------------------------\n\n");

    return _sceneRoot;
}
Ejemplo n.º 7
0
/*!
SLMesh::calcCenterRad calculates the center and the radius of an almost minimal
bounding sphere. Code by Jack Ritter from Graphic Gems.
*/
void SLMesh::calcCenterRad(SLVec3f& center, SLfloat& radius)
{
   SLint    i;
   SLfloat  dx, dy, dz;
   SLfloat  radius2, xspan, yspan, zspan, maxspan;
   SLfloat  old_to_p, old_to_p_sq, old_to_new;
   SLVec3f  xmin, xmax, ymin, ymax, zmin, zmax, dia1, dia2;

   // FIRST PASS: find 6 minima/maxima points
   xmin.x = ymin.y = zmin.z=  FLT_MAX;
   xmax.x = ymax.y = zmax.z= -FLT_MAX;
   
   for (i=0; i<numV; ++i)
   {
      if (P[i].x < xmin.x) xmin = P[i]; else
      if (P[i].x > xmax.x) xmax = P[i];
      if (P[i].y < ymin.y) ymin = P[i]; else
      if (P[i].y > ymax.y) ymax = P[i];
      if (P[i].z < zmin.z) zmin = P[i]; else
      if (P[i].z > zmax.z) zmax = P[i];
   }
   
   // Set xspan = distance between the 2 points xmin & xmax (squared)
   dx = xmax.x - xmin.x;
   dy = xmax.y - xmin.y;
   dz = xmax.z - xmin.z;
   xspan = dx*dx + dy*dy + dz*dz;

   // Same for y & z spans
   dx = ymax.x - ymin.x;
   dy = ymax.y - ymin.y;
   dz = ymax.z - ymin.z;
   yspan = dx*dx + dy*dy + dz*dz;

   dx = zmax.x - zmin.x;
   dy = zmax.y - zmin.y;
   dz = zmax.z - zmin.z;
   zspan = dx*dx + dy*dy + dz*dz;

   // Set points dia1 & dia2 to the maximally separated pair
   dia1 = xmin; dia2 = xmax; // assume xspan biggest
   maxspan = xspan;
   if (yspan > maxspan)
   {  maxspan = yspan;
      dia1 = ymin; dia2 = ymax;
   }
   if (zspan > maxspan)
   {  dia1 = zmin; dia2 = zmax;
   }

   // dia1,dia2 is a diameter of initial sphere
   // calc initial center
   center.x = (dia1.x + dia2.x)*0.5f;
   center.y = (dia1.y + dia2.y)*0.5f;
   center.z = (dia1.z + dia2.z)*0.5f;
   
   // calculate initial radius*radius and radius
   dx = dia2.x - center.x; // x component of radius vector
   dy = dia2.y - center.y; // y component of radius vector
   dz = dia2.z - center.z; // z component of radius vector
   radius2 = dx*dx + dy*dy + dz*dz;
   radius  = sqrt(radius2);

   // SECOND PASS: increment current sphere
   for (i=0; i<numV; ++i)
   {
      dx = P[i].x - center.x;
      dy = P[i].y - center.y;
      dz = P[i].z - center.z;
      old_to_p_sq = dx*dx + dy*dy + dz*dz;
      
      if (old_to_p_sq > radius2) 	// do r**2 test first
      { 	
         // this point is outside of current sphere
         old_to_p = sqrt(old_to_p_sq);
         
         // calc radius of new sphere
         radius  = (radius + old_to_p) * 0.5f;
         radius2 = radius*radius; 	// for next r**2 compare
         old_to_new = old_to_p - radius;
         
         // calc center of new sphere
         center.x = (radius*center.x + old_to_new*P[i].x) / old_to_p;
         center.y = (radius*center.y + old_to_new*P[i].y) / old_to_p;
         center.z = (radius*center.z + old_to_new*P[i].z) / old_to_p;
         
         // Suppress if desired
         SL_LOG("\n New sphere: center,radius = %f %f %f   %f",
                center.x,center.y,center.z, radius);
      }
   }
}
Ejemplo n.º 8
0
/*!
SLGroup::printStats() prints the statistic info of this group.
*/
void SLGroup::printStats()
{  
   SLfloat voxelsEmpty  = numVoxels ? (SLfloat)numVoxEmpty / 
                                      (SLfloat)numVoxels*100.0f : 0;
   SLfloat avgTriPerVox = numVoxels ? (SLfloat)numRTTriangles / 
                                      (SLfloat)(numVoxels-numVoxEmpty) : 0;
   SL_LOG("RTVertices        : %d\n", numRTVertices);
   SL_LOG("RTTriangles       : %d\n", numRTTriangles);
   SL_LOG("Voxels            : %d\n", numVoxels);
   SL_LOG("Voxels empty      : %4.1f%%\n", voxelsEmpty); 
   SL_LOG("Avg. Tria/Voxel   : %4.1f\n", avgTriPerVox);
   SL_LOG("Max. Tria/Voxel   : %d\n", numVoxMaxTria);
   SL_LOG("MBytes in Meshes  : %f\n", (SLfloat)numBytes / 1000000.0f);
   SL_LOG("Groups            : %d\n", numGroups);
   SL_LOG("Shapes            : %d\n", numShapes);
   SL_LOG("RefShapes         : %d\n", numRefShapes);
   SL_LOG("Lights            : %d\n", numLights);
   SL_LOG("\n");
}
Ejemplo n.º 9
0
/*! SLGLShaderProg::init creates the OpenGL shaderprogram object, compiles all
shader objects and attaches them to the shaderprogram. At the end all shaders
are linked. If a shader fails to compile a simple texture only shader is
compiled that shows an error message in the texture.
*/
void SLGLShaderProg::init()
{     
   // create program object if it doesn't exist
   if(!_programObjectGL) _programObjectGL = glCreateProgram();
   
   // if already linked, detach, recreate and compile shaders
   if (_isLinked)
   {  for (SLuint i=0; i<_shaderList.size(); i++)
      {  if (_isLinked)
         {  glDetachShader(_programObjectGL, _shaderList[i]->_shaderObjectGL);
            GET_GL_ERROR;
         }
      }
      _isLinked = false;
   }
   
   // compile all shader objects
   SLbool allSuccuessfullyCompiled = true;
   for (SLuint i=0; i<_shaderList.size(); i++)
   {  if (!_shaderList[i]->createAndCompile())
      {  allSuccuessfullyCompiled = false;
         break;
      }
      GET_GL_ERROR;
   }

   // try to compile alternative per vertex lighting shaders
   if (!allSuccuessfullyCompiled)
   {        
      // delete all shaders and uniforms that where attached
      for (SLuint i=0; i<_shaderList.size();    i++) delete _shaderList[i]; 
      for (SLuint i=0; i<_uniform1fList.size(); ++i) delete _uniform1fList[i];
      for (SLuint i=0; i<_uniform1iList.size(); ++i) delete _uniform1iList[i];
      _shaderList.clear();
      _uniform1fList.clear();
      _uniform1iList.clear();

      addShader(new SLGLShader(defaultPath+"ErrorTex.vert", SLVertexShader));
      addShader(new SLGLShader(defaultPath+"ErrorTex.frag", SLFragmentShader));

      allSuccuessfullyCompiled = true;
      for (SLuint i=0; i<_shaderList.size(); i++)
      {  if (!_shaderList[i]->createAndCompile())
         {  allSuccuessfullyCompiled = false;
            break;
         }
         GET_GL_ERROR;
      }
   }

   // attach all shader objects
   if (allSuccuessfullyCompiled)
   {  for (SLuint i=0; i<_shaderList.size(); i++)
      {  glAttachShader(_programObjectGL, _shaderList[i]->_shaderObjectGL);
         GET_GL_ERROR;
      }
   } else SL_EXIT_MSG("No successufully compiled shaders attached!");
    
   int linked;
   glLinkProgram(_programObjectGL);
   GET_GL_ERROR;
   glGetProgramiv(_programObjectGL, GL_LINK_STATUS, &linked);
   GET_GL_ERROR;

   if (linked)
   {  _isLinked = true;
      for (SLuint i=0; i<_shaderList.size(); i++) 
         _name += "+"+_shaderList[i]->name();
      //SL_LOG("Linked: %s", _name.c_str());
   } else
   {  SLchar log[256];
      glGetProgramInfoLog(_programObjectGL, sizeof(log), 0, &log[0]);
      SL_LOG("*** LINKER ERROR ***\n");
      SL_LOG("Source files: \n");
      for (SLuint i=0; i<_shaderList.size(); i++) 
         SL_LOG("%s\n", _shaderList[i]->name().c_str());
      SL_LOG("%s\n", log);
      SL_EXIT_MSG("GLSL linker error");
   }
}