/*!**************************************************************************** @Function LoadTextures @Output pErrorStr A string describing the error on failure @Return bool true if no error occured @Description Loads the textures required for this training course ******************************************************************************/ bool OGLES3TextureStreaming::LoadTextures(CPVRTString* pErrorStr) { /* Loads the textures. For a more detailed explanation, see Texturing and IntroducingPVRTools */ /* Initialises an array to lookup the textures for each material in the scene. */ m_puiTextureIDs = new GLuint[m_Scene.nNumMaterial]; if(!m_puiTextureIDs) { *pErrorStr = "ERROR: Insufficient memory.\n"; return false; } for(unsigned int i = 0; i < m_Scene.nNumMaterial; ++i) { m_puiTextureIDs[i] = 0; SPODMaterial* pMaterial = &m_Scene.pMaterial[i]; if(strcmp(pMaterial->pszName, "ScreenMat") == 0) m_uiTVScreen = i; else if(strcmp(pMaterial->pszName, "RecordGlow") == 0) m_uiRecordGlow = i; if(pMaterial->nIdxTexDiffuse != -1) { /* Using the tools function PVRTTextureLoadFromPVR load the textures required by the pod file. Note: This function only loads .pvr files. You can set the textures in 3D Studio Max to .pvr files using the PVRTexTool plug-in for max. Alternatively, the pod material properties can be modified in PVRShaman. */ const char* pszTexFile = m_Scene.pTexture[pMaterial->nIdxTexDiffuse].pszName; if(PVRTTextureLoadFromPVR(pszTexFile, &m_puiTextureIDs[i]) != PVR_SUCCESS) { *pErrorStr += PVRTStringFromFormattedStr("ERROR: Failed to load %s\n", pszTexFile); return false; } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); } } // Load random texture if(PVRTTextureLoadFromPVR(c_pszNoiseTexFile, &m_uiNoiseTex) != PVR_SUCCESS) { *pErrorStr += "ERROR: Failed to load noise texture.\n"; return false; } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); return true; }
/*!**************************************************************************** @Function InitView @Return bool true if no error occurred @Description Code in InitView() will be called by PVRShell upon initialization or after a change in the rendering context. Used to initialize variables that are dependant on the rendering context (e.g. textures, vertex buffers, etc.) ******************************************************************************/ bool OGLES2Shaders::InitView() { // Is the screen rotated bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen); /* Initialize Print3D textures */ if (m_Print3D.SetTextures(0,PVRShellGet(prefWidth),PVRShellGet(prefHeight), bRotate) != PVR_SUCCESS) { PVRShellOutputDebug("ERROR: Cannot initialise Print3D\n"); return false; } glClearColor(0.6f, 0.8f, 1.0f, 1.0f); m_mProjection = PVRTMat4::PerspectiveFovRH(PVRT_PI/6, (float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight), CAM_NEAR, CAM_FAR, PVRTMat4::OGL, bRotate); m_mView = PVRTMat4::Identity(); /* Loads the textures. */ // Textures // Get pointer to the texture name CPVRTString ErrorStr; char *pTexture = 0; PVRTextureHeaderV3 Header; for(int i = 0; i < g_numTextures; ++i) { if(strcmp(g_TextureList[i], "base") == 0) pTexture = (char*) g_aszTextureNames[eTexBase]; else if(strcmp(g_TextureList[i], "reflection") == 0) pTexture = (char*) g_aszTextureNames[eTexReflection]; else if(strcmp(g_TextureList[i], "cubemap") == 0) pTexture = (char*) g_aszTextureNames[eTexCubeMap]; else if(strcmp(g_TextureList[i], "anisotropicmap") == 0) pTexture = (char*) g_aszTextureNames[eTexAnisotropic]; if(PVRTTextureLoadFromPVR(pTexture, &m_puiTextureHandle[i], &Header) != PVR_SUCCESS) { ErrorStr = CPVRTString("ERROR: Could not open texture file ") + pTexture; PVRShellSet(prefExitMessage, ErrorStr.c_str()); return false; } // Get texture flags form the header m_uiTextureFlags[i] = (Header.u32NumFaces==6?PVRTEX_CUBEMAP:0) | (Header.u32MIPMapCount>1?PVRTEX_MIPMAP:0) | (Header.u32Depth>1?PVRTEX_VOLUME:0); } /* Load the effect file */ for(int j = 0; j < g_numShaders; j++) { CPVRTString fileName; unsigned int nUnknownUniformCount; CPVRTString error; /* Parse the file */ m_ppEffectParser[j] = new CPVRTPFXParser(); fileName = CPVRTString(g_ShaderList[j]) + ".pfx"; if(m_ppEffectParser[j]->ParseFromFile(fileName.c_str(), &error) != PVR_SUCCESS) { error = CPVRTString("Parse failed for ") + fileName + ":\n\n" + error; PVRShellSet(prefExitMessage, error.c_str()); FreeMemory(); return false; } /* Load the effect from the file */ error = ""; m_ppEffect[j] = new CPVRTPFXEffect(); if(m_ppEffect[j]->Load(*(m_ppEffectParser[j]), "myEffect", fileName.c_str(), NULL, nUnknownUniformCount, &error) != PVR_SUCCESS) { PVRShellSet(prefExitMessage, error.c_str()); FreeMemory(); return false; } if(nUnknownUniformCount) { error = PVRTStringFromFormattedStr("PFX File: %s\n%s Unknown uniform semantic count: %d\n", fileName.c_str(), error.c_str(), nUnknownUniformCount); PVRShellSet(prefExitMessage, error.c_str()); FreeMemory(); return false; } if(!error.empty()) { PVRShellOutputDebug(error.c_str()); } /* Link the textrues to the effect. */ const CPVRTArray<SPVRTPFXTexture>& sTex = m_ppEffect[j]->GetTextureArray(); // Loop over textures used in the CPVRTPFXEffect for(unsigned int i = 0; i < sTex.GetSize(); ++i) { int iTexIdx = m_ppEffectParser[j]->FindTextureByName(sTex[i].Name); const CPVRTStringHash& FileName = m_ppEffectParser[j]->GetTexture(iTexIdx)->FileName; int k; // Loop over available textures for( k = 0; k < g_numTextures; k++) { CPVRTString texName; texName = CPVRTString(g_TextureList[k]) + ".pvr"; if(FileName == texName) { // Set the current texture if((m_uiTextureFlags[k] & CUBEMAP_FLAG) != 0) glBindTexture(GL_TEXTURE_CUBE_MAP, m_puiTextureHandle[k]); else glBindTexture(GL_TEXTURE_2D, m_puiTextureHandle[k]); // Link the texture to the CPVRTPFXEffect and apply filtering m_ppEffect[j]->SetTexture(i, m_puiTextureHandle[k], m_uiTextureFlags[k]); break; } } if(k == g_numTextures) { // Texture not found PVRShellOutputDebug("Warning: effect file requested unrecognised texture: \"%s\"\n", FileName.c_str()); m_ppEffect[j]->SetTexture(i, 0); } } } glEnable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); // Create the surface m_Surface = new ParametricSurface(50,50); ComputeSurface(m_nCurrentSurface); return true; }
/******************************************************************************* * Function Name : RenderScene * Returns : true if no error occured * Description : Main rendering loop function of the program. The shell will * call this function every frame. *******************************************************************************/ bool OGLESOptimizeMesh::RenderScene() { unsigned long ui32Time; // Clear the depth and frame buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Time ui32Time = PVRShellGetTime(); m_ui32TimeDiff = ui32Time - m_ui32LastTime; m_ui32LastTime = ui32Time; // FPS ++m_ui32FPSFrameCnt; m_ui32FPSTimeDiff += m_ui32TimeDiff; if(m_ui32FPSTimeDiff >= g_ui32TimeFPSUpdate) { m_fFPS = m_ui32FPSFrameCnt * 1000.0f / (float) m_ui32FPSTimeDiff; m_ui32FPSFrameCnt = 0; m_ui32FPSTimeDiff = 0; } // Change mode when necessary m_ui32SwitchTimeDiff += m_ui32TimeDiff; if((m_ui32SwitchTimeDiff > g_ui32TimeAutoSwitch) || PVRShellIsKeyPressed(PVRShellKeyNameACTION1)) { m_ui32SwitchTimeDiff = 0; ++m_i32Page; if(m_i32Page >= (int) m_ui32PageNo) m_i32Page = 0; } PVRTVec3 From; float fFactor; From.x = g_fViewDistance * PVRTSIN(m_fViewAngle); From.y = 0.0f; From.z = g_fViewDistance * PVRTCOS(m_fViewAngle); // Increase the rotation fFactor = 0.005f * (float) m_ui32TimeDiff; m_fViewAngle += fFactor; // Ensure it doesn't grow huge and lose accuracy over time while(m_fViewAngle > PVRT_PI) m_fViewAngle -= PVRT_TWO_PI; // Compute and set the matrix m_mView = PVRTMat4::LookAtRH(From, PVRTVec3(0,0,0), PVRTVec3(0,1,0)); glMatrixMode(GL_MODELVIEW); glLoadMatrixf(m_mView.f); // Setup the lighting glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); PVRTVec4 vLightDir(From.x, From.y, From.z, 0); vLightDir = vLightDir.normalize(); // Set the light direction glLightfv(GL_LIGHT0, GL_POSITION, vLightDir.ptr()); glLightfv(GL_LIGHT0, GL_DIFFUSE, PVRTVec4(0.8f,0.8f,0.8f,1.0f).ptr()); // Draw the model DrawModel(m_i32Page); // Display the frame rate CPVRTString title; const char * pDesc; title = PVRTStringFromFormattedStr("Optimize Mesh %.1ffps", m_fFPS); // Print text on screen switch(m_i32Page) { default: pDesc = "Indexed Tri List: Unoptimized"; break; case 1: pDesc = "Indexed Tri List: Optimized (at export time)"; break; } m_Print3D.DisplayDefaultTitle(title.c_str(), pDesc, ePVRTPrint3DSDKLogo); // Flush all Print3D commands m_Print3D.Flush(); return true; }