/*!**************************************************************************** @Function QuitApplication @Return bool true if no error occurred @Description Code in QuitApplication() will be called by PVRShell once per run, just before exiting the program. If the rendering context is lost, QuitApplication() will not be called. ******************************************************************************/ bool OGLESPVRScopeRemote::QuitApplication() { if (m_psSPSCommsData) { m_bCommsError |= !pplSendProcessingBegin(m_psSPSCommsData, __FUNCTION__, static_cast<unsigned int>(strlen(__FUNCTION__)), m_i32FrameCounter); } // Free the memory allocated for the scene m_Scene.Destroy(); delete [] m_puiVbo; delete [] m_puiIndexVbo; // Close the data connection to PVRPerfServer if(m_psSPSCommsData) { for(unsigned int i = 0; i < 40; ++i) { char buf[128]; const int nLen = sprintf(buf, "test %u", i); m_bCommsError |= !pplSendMark(m_psSPSCommsData, buf, nLen); } m_bCommsError |= !pplSendProcessingEnd(m_psSPSCommsData); pplShutdown(m_psSPSCommsData); } return true; }
/*!**************************************************************************** @Function QuitApplication @Return bool true if no error occured @Description Code in QuitApplication() will be called by PVRShell once per run, just before exiting the program. If the rendering context is lost, QuitApplication() will not be called. ******************************************************************************/ bool OGLES2PVRScopeRemote::QuitApplication() { // Free the memory allocated for the scene m_Scene.Destroy(); delete [] m_puiVbo; delete [] m_puiIndexVbo; // Close the data connection to PVRPerfServer for(unsigned int i = 0; i < 40; ++i) { char buf[128]; const int nLen = sprintf(buf, "test %u", i); pplSendMark(*m_psSPSCommsData, buf, nLen); } pplShutdown(m_psSPSCommsData); return true; }
/*!**************************************************************************** @Function RenderScene @Return bool true if no error occurred @Description Main rendering loop function of the program. The shell will call this function every frame. eglSwapBuffers() will be performed by PVRShell automatically. PVRShell will also manage important OS events. Will also manage relevant OS events. The user has access to these events through an abstraction layer provided by PVRShell. ******************************************************************************/ bool OGLESPVRScopeRemote::RenderScene() { CPPLProcessingScoped PPLProcessingScoped(m_psSPSCommsData, __FUNCTION__, static_cast<unsigned int>(strlen(__FUNCTION__)), m_i32FrameCounter); if(m_psSPSCommsData) { // mark every N frames if(!(m_i32FrameCounter % 100)) { char buf[128]; const int nLen = sprintf(buf, "frame %u", m_i32FrameCounter); m_bCommsError |= !pplSendMark(m_psSPSCommsData, buf, nLen); } // Check for dirty items m_bCommsError |= !pplSendProcessingBegin(m_psSPSCommsData, "dirty", static_cast<unsigned int>(strlen("dirty")), m_i32FrameCounter); { unsigned int nItem, nNewDataLen; const char *pData; while(pplLibraryDirtyGetFirst(m_psSPSCommsData, &nItem, &nNewDataLen, &pData)) { PVRShellOutputDebug("dirty item %u %u 0x%08x\n", nItem, nNewDataLen, pData); switch(nItem) { case 0: if(nNewDataLen == sizeof(SSPSCommsLibraryTypeFloat)) { const SSPSCommsLibraryTypeFloat * const psData = (SSPSCommsLibraryTypeFloat*)pData; m_fMinThickness = psData->fCurrent; } break; case 1: if(nNewDataLen == sizeof(SSPSCommsLibraryTypeFloat)) { const SSPSCommsLibraryTypeFloat * const psData = (SSPSCommsLibraryTypeFloat*)pData; m_fMaxVariation = psData->fCurrent; } break; } } } m_bCommsError |= !pplSendProcessingEnd(m_psSPSCommsData); } if (m_psSPSCommsData) { m_bCommsError |= !pplSendProcessingBegin(m_psSPSCommsData, "draw", static_cast<unsigned int>(strlen("draw")), m_i32FrameCounter); } // Clear the color and depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Loads the projection matrix glMatrixMode(GL_PROJECTION); glLoadMatrixf(m_mProjection.f); // Specify the modelview matrix PVRTMat4 mModel; SPODNode& Node = m_Scene.pNode[0]; m_Scene.GetWorldMatrix(mModel, Node); // Rotate and Translate the model matrix m_fAngleY += (2*PVRT_PIf/60)/7; // Set model view projection matrix PVRTMat4 mModelView; mModelView = m_mView * PVRTMat4::RotationY(m_fAngleY) * mModel; glMatrixMode(GL_MODELVIEW); glLoadMatrixf(mModelView.f); /* Load the light direction from the scene if we have one */ // Enables lighting. See BasicTnL for a detailed explanation glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); // Set light direction PVRTVec4 vLightDirModel; vLightDirModel = mModel.inverse() * PVRTVec4(1, 1, 1, 0); glLightfv(GL_LIGHT0, GL_POSITION, (float*)&vLightDirModel.x); // Enable the vertex position attribute array glEnableClientState(GL_VERTEX_ARRAY); // bind the texture glBindTexture(GL_TEXTURE_2D, m_uiTexture); /* Now that the model-view matrix is set and the materials are ready, call another function to actually draw the mesh. */ DrawMesh(Node.nIdx); // Disable the vertex positions glDisableClientState(GL_VERTEX_ARRAY); if (m_psSPSCommsData) { m_bCommsError |= !pplSendProcessingEnd(m_psSPSCommsData); m_bCommsError |= !pplSendProcessingBegin(m_psSPSCommsData, "Print3D", static_cast<unsigned int>(strlen("Print3D")), m_i32FrameCounter); } // Displays the demo name using the tools. For a detailed explanation, see the example IntroducingPVRTools if(m_bCommsError) { m_Print3D.DisplayDefaultTitle("PVRScopeRemote", "Remote APIs\n\nError:\n PVRScopeComms failed\n Is PVRPerfServer connected?", ePVRTPrint3DSDKLogo); m_bCommsError = false; } else m_Print3D.DisplayDefaultTitle("PVRScopeRemote", "Remote APIs", ePVRTPrint3DSDKLogo); m_Print3D.Flush(); if (m_psSPSCommsData) { m_bCommsError |= !pplSendProcessingEnd(m_psSPSCommsData); } // send counters m_anCounterReadings[eCounter] = m_i32FrameCounter; m_anCounterReadings[eCounter10] = m_i32Frame10Counter; if(m_psSPSCommsData) { m_bCommsError |= !pplCountersUpdate(m_psSPSCommsData, m_anCounterReadings); } // update some counters ++m_i32FrameCounter; if(0 == (m_i32FrameCounter / 10) % 10) { m_i32Frame10Counter += 10; } return true; }
/*!**************************************************************************** @Function InitApplication @Return bool true if no error occurred @Description Code in InitApplication() will be called by PVRShell once per run, before the rendering context is created. Used to initialize variables that are not dependent on it (e.g. external modules, loading meshes, etc.) If the rendering context is lost, InitApplication() will not be called again. ******************************************************************************/ bool OGLESPVRScopeRemote::InitApplication() { // We want a data connection to PVRPerfServer { m_psSPSCommsData = pplInitialise("PVRScopeRemote", 14); m_bCommsError = false; // Demonstrate that there is a good chance of the initial data being // lost - the connection is normally completed asynchronously. pplSendMark(m_psSPSCommsData, "lost", static_cast<unsigned int>(strlen("lost"))); // This is entirely optional. Wait for the connection to succeed, it will // timeout if e.g. PVRPerfServer is not running. int nBoolConnected; pplWaitForConnection(m_psSPSCommsData, &nBoolConnected, 1, 200); } CPPLProcessingScoped PPLProcessingScoped(m_psSPSCommsData, __FUNCTION__, static_cast<unsigned int>(strlen(__FUNCTION__)), m_i32FrameCounter); // set thickness variation of the film m_fMaxVariation = 100.0f; // set the minimum thickness of the film m_fMinThickness = 100.0f; m_i32FrameCounter = 0; m_i32Frame10Counter = 0; // Get and set the read path for content files CPVRTResourceFile::SetReadPath((char*)PVRShellGet(prefReadPath)); // Get and set the load/release functions for loading external files. // In the majority of cases the PVRShell will return NULL function pointers implying that // nothing special is required to load external files. CPVRTResourceFile::SetLoadReleaseFunctions(PVRShellGet(prefLoadFileFunc), PVRShellGet(prefReleaseFileFunc)); /* Loads the scene from the .pod file into a CPVRTModelPOD object. We could also export the scene as a header file and load it with ReadFromMemory(). */ if(m_Scene.ReadFromFile(c_szSceneFile) != PVR_SUCCESS) { CPVRTString ErrorStr = "ERROR: Couldn't load '" + CPVRTString(c_szSceneFile) + "'."; PVRShellSet(prefExitMessage, ErrorStr.c_str()); return false; } /* Remotely editable library items */ if(m_psSPSCommsData) { SSPSCommsLibraryItem asItems[8]; unsigned int nItemCount = 0; // Want editable: min thickness m_sCommsLibMinThickness.fCurrent = m_fMinThickness; m_sCommsLibMinThickness.fMin = 0.0f; m_sCommsLibMinThickness.fMax = 500.0f; asItems[nItemCount].pszName = "min thickness"; asItems[nItemCount].nNameLength = (unsigned int)strlen(asItems[nItemCount].pszName); asItems[nItemCount].eType = eSPSCommsLibTypeFloat; asItems[nItemCount].pData = (const char*)&m_sCommsLibMinThickness; asItems[nItemCount].nDataLength = sizeof(m_sCommsLibMinThickness); ++nItemCount; // Want editable: max variation m_sCommsLibMaxVariation.fCurrent = m_fMaxVariation; m_sCommsLibMaxVariation.fMin = 50.0f; m_sCommsLibMaxVariation.fMax = 150.0f; asItems[nItemCount].pszName = "max variation"; asItems[nItemCount].nNameLength = (unsigned int)strlen(asItems[nItemCount].pszName); asItems[nItemCount].eType = eSPSCommsLibTypeFloat; asItems[nItemCount].pData = (const char*)&m_sCommsLibMaxVariation; asItems[nItemCount].nDataLength = sizeof(m_sCommsLibMaxVariation); ++nItemCount; _ASSERT(nItemCount < sizeof(asItems) / sizeof(*asItems)); /* Ok, submit our library */ if(!pplLibraryCreate(m_psSPSCommsData, asItems, nItemCount)) { PVRShellOutputDebug("PVRScopeRemote: pplLibraryCreate() failed\n"); } } /* User defined counters */ if(m_psSPSCommsData) { SSPSCommsCounterDef asDefs[eCounterNum]; for(unsigned int i = 0; i < eCounterNum; ++i) { asDefs[i].pszName = c_apszDefs[i]; asDefs[i].nNameLength = (unsigned int)strlen(c_apszDefs[i]); } if(!pplCountersCreate(m_psSPSCommsData, asDefs, eCounterNum)) { PVRShellOutputDebug("PVRScopeRemote: pplCountersCreate() failed\n"); } } return true; }
/*!**************************************************************************** @Function RenderScene @Return bool true if no error occured @Description Main rendering loop function of the program. The shell will call this function every frame. eglSwapBuffers() will be performed by PVRShell automatically. PVRShell will also manage important OS events. Will also manage relevent OS events. The user has access to these events through an abstraction layer provided by PVRShell. ******************************************************************************/ bool OGLES2PVRScopeRemote::RenderScene() { CPPLProcessingScoped PPLProcessingScoped(m_psSPSCommsData, __FUNCTION__, static_cast<unsigned int>(strlen(__FUNCTION__)), m_i32FrameCounter); if(m_psSPSCommsData) { // mark every N frames if(!(m_i32FrameCounter % 100)) { char buf[128]; const int nLen = sprintf(buf, "frame %u", m_i32FrameCounter); m_bCommsError |= !pplSendMark(m_psSPSCommsData, buf, nLen); } // Check for dirty items m_bCommsError |= !pplSendProcessingBegin(m_psSPSCommsData, "dirty", static_cast<unsigned int>(strlen("dirty")), m_i32FrameCounter); { unsigned int nItem, nNewDataLen; const char *pData; bool bRecompile = false; while(pplLibraryDirtyGetFirst(m_psSPSCommsData, &nItem, &nNewDataLen, &pData)) { PVRShellOutputDebug("dirty item %u %u 0x%08x\n", nItem, nNewDataLen, pData); switch(nItem) { case 0: delete [] m_pszFragShader; m_pszFragShader = new char [nNewDataLen+1]; strncpy(m_pszFragShader, (char*)pData, nNewDataLen); m_pszFragShader[nNewDataLen] = 0; bRecompile = true; break; case 1: delete [] m_pszVertShader; m_pszVertShader = new char [nNewDataLen+1]; strncpy(m_pszVertShader, (char*)pData, nNewDataLen); m_pszVertShader[nNewDataLen] = 0; bRecompile = true; break; case 2: if(nNewDataLen == sizeof(SSPSCommsLibraryTypeFloat)) { const SSPSCommsLibraryTypeFloat * const psData = (SSPSCommsLibraryTypeFloat*)pData; m_fMinThickness = psData->fCurrent; } break; case 3: if(nNewDataLen == sizeof(SSPSCommsLibraryTypeFloat)) { const SSPSCommsLibraryTypeFloat * const psData = (SSPSCommsLibraryTypeFloat*)pData; m_fMaxVariation = psData->fCurrent; } break; } } if(bRecompile) { CPVRTString ErrorStr; glDeleteProgram(m_ShaderProgram.uiId); glDeleteShader(m_uiVertShader); glDeleteShader(m_uiFragShader); if (!LoadShaders(&ErrorStr, m_pszFragShader, m_pszVertShader)) { PVRShellOutputDebug("%s", ErrorStr.c_str()); } } } m_bCommsError |= !pplSendProcessingEnd(m_psSPSCommsData); } if (m_psSPSCommsData) { m_bCommsError |= !pplSendProcessingBegin(m_psSPSCommsData, "draw", static_cast<unsigned int>(strlen("draw")), m_i32FrameCounter); } // Clear the color and depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Use shader program glUseProgram(m_ShaderProgram.uiId); // Bind texture glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_uiTexture); // Rotate and Translation the model matrix PVRTMat4 mModel; mModel = PVRTMat4::RotationY(m_fAngleY); m_fAngleY += (2*PVRT_PI/60)/7; // Set model view projection matrix PVRTMat4 mModelView, mMVP; mModelView = m_mView * mModel; mMVP = m_mProjection * mModelView; glUniformMatrix4fv(m_ShaderProgram.uiMVPMatrixLoc, 1, GL_FALSE, mMVP.ptr()); // Set light direction in model space PVRTVec4 vLightDirModel; vLightDirModel = mModel.inverse() * PVRTVec4(1, 1, 1, 0); glUniform3fv(m_ShaderProgram.uiLightDirLoc, 1, &vLightDirModel.x); // Set eye position in model space PVRTVec4 vEyePosModel; vEyePosModel = mModelView.inverse() * PVRTVec4(0, 0, 0, 1); glUniform3fv(m_ShaderProgram.uiEyePosLoc, 1, &vEyePosModel.x); /* Set the iridescent shading parameters */ // Set the minimum thickness of the coating in nm glUniform1f(m_ShaderProgram.uiMinThicknessLoc, m_fMinThickness); // Set the maximum variation in thickness of the coating in nm glUniform1f(m_ShaderProgram.uiMaxVariationLoc, m_fMaxVariation); /* Now that the uniforms are set, call another function to actually draw the mesh. */ DrawMesh(0); if (m_psSPSCommsData) { m_bCommsError |= !pplSendProcessingEnd(m_psSPSCommsData); m_bCommsError |= !pplSendProcessingBegin(m_psSPSCommsData, "Print3D", static_cast<unsigned int>(strlen("Print3D")), m_i32FrameCounter); } // Displays the demo name using the tools. For a detailed explanation, see the example IntroducingPVRTools if(m_bCommsError) { m_Print3D.DisplayDefaultTitle("PVRScopeRemote", "Remote APIs\n\nError:\n PVRScopeComms failed\n Is PVRPerfServer connected?", ePVRTPrint3DSDKLogo); m_bCommsError = false; } else m_Print3D.DisplayDefaultTitle("PVRScopeRemote", "Remote APIs", ePVRTPrint3DSDKLogo); m_Print3D.Flush(); if (m_psSPSCommsData) { m_bCommsError |= !pplSendProcessingEnd(m_psSPSCommsData); } // send counters m_anCounterReadings[eCounter] = m_i32FrameCounter; m_anCounterReadings[eCounter10] = m_i32Frame10Counter; if(m_psSPSCommsData) { m_bCommsError |= !pplCountersUpdate(m_psSPSCommsData, m_anCounterReadings); } // update some counters ++m_i32FrameCounter; if(0 == (m_i32FrameCounter / 10) % 10) { m_i32Frame10Counter += 10; } return true; }