/*!**************************************************************************** @Function InitView @Return bool true if no error occured @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 OGLESAntialiasedLines::InitView() { bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen); m_iWidth = PVRShellGet(prefWidth); m_iHeight = PVRShellGet(prefHeight); myglClearColor(f2vt(0.6f), f2vt(0.8f), f2vt(1.0f), f2vt(1.0f)); // Initialise Print3D if(m_Print3D.SetTextures(0, m_iWidth, m_iHeight, bRotate) != PVR_SUCCESS) { PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Print3D.\n"); return false; } // Initialise the texture if (PVRTTextureLoadFromPVR("LineRound.pvr", &m_uiTexture) != PVR_SUCCESS) { PVRShellSet(prefExitMessage, "ERROR: Failed to load texture.\n"); return false; } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Initialise geometry SVertex *paVertices = new SVertex[c_iNumLines * 2]; // 2 vertices per GL_LINE STexVertex *paTexVertices = new STexVertex[c_iNumLines * 8]; // 8 vertices per AA line (includes caps) GLushort *paui16Indices = new GLushort[c_iNumLines * 18]; // 18 indices per AA line (6 triangles) if(!paVertices || !paTexVertices || !paui16Indices) { delete[] paVertices; delete[] paTexVertices; delete[] paui16Indices; PVRShellSet(prefExitMessage, "ERROR: Failed to allocate line vertices and indices.\n"); return false; } srand(0); float fAngleStep = PVRT_TWO_PI / c_iNumLines; VERTTYPE fSize = f2vt(PVRT_MIN(m_iWidth, m_iHeight) * 0.4f); for (int i = 0; i < c_iNumLines; ++i) { // Place the line vertices on a circle paVertices[i*2].vPosition.x = VERTTYPEMUL(fSize, PVRTSIN(fAngleStep * (i + c_fLineArc))); paVertices[i*2].vPosition.y = VERTTYPEMUL(fSize, PVRTCOS(fAngleStep * (i + c_fLineArc))); paVertices[i*2+1].vPosition.x = VERTTYPEMUL(fSize, PVRTSIN(fAngleStep * i)); paVertices[i*2+1].vPosition.y = VERTTYPEMUL(fSize, PVRTCOS(fAngleStep * i)); // Pick a random RGB color paVertices[i*2].uiColor = (0xFF << 24) + ((rand() & 0xFF) << 16) + ((rand() & 0xFF) << 8) + (rand() & 0xFF); paVertices[i*2+1].uiColor = paVertices[i*2].uiColor; // Tessellate the antialiased line TessellateLine(paVertices[i*2].vPosition, paVertices[i*2+1].vPosition, c_fLineWidth, paVertices[i*2].uiColor, &paTexVertices[i * 8], i * 8, &paui16Indices[i * 18]); } // We use 3 VBOs for clarity: // 0: AA line vertex data // 1: AA line index data // 2: GL_LINES vertex data glGenBuffers(3, m_uiVbos); // Bind the VBOs and fill them with data glBindBuffer(GL_ARRAY_BUFFER, m_uiVbos[0]); glBufferData(GL_ARRAY_BUFFER, sizeof(*paTexVertices) * c_iNumLines * 8, paTexVertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_uiVbos[1]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(*paui16Indices) * c_iNumLines * 18, paui16Indices, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, m_uiVbos[2]); glBufferData(GL_ARRAY_BUFFER, sizeof(*paVertices) * c_iNumLines * 2, paVertices, GL_STATIC_DRAW); // Unbind buffers glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // Set projection to use pixel coordinates glMatrixMode(GL_PROJECTION); glLoadIdentity(); myglOrtho(0, f2vt((float)PVRShellGet(prefWidth)), f2vt((float)PVRShellGet(prefHeight)), 0, 0, 1); delete[] paVertices; delete[] paTexVertices; delete[] paui16Indices; 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 OGLESPolybump::RenderScene() { if(PVRShellIsKeyPressed(PVRShellKeyNameACTION1)) m_bDrawWithDot3 = !m_bDrawWithDot3; PVRTVec4 LightVector; PVRTMat4 mRotateY, mModelView; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); LightVector.x = PVRTSIN(m_i32Frame / 40.0f); LightVector.y = 0.0f; LightVector.z = -PVRTABS(PVRTCOS(m_i32Frame / 40.0f)); LightVector.w = 0.0f; PVRTTransformBack(&LightVector, &LightVector, &m_mView); // Normalize light vector in case it is not LightVector.normalize(); if(m_bDrawWithDot3) { // Setup texture blend modes // First layer (Dot3) glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_ui32CloneMap); if(m_bCombinersPresent) { glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB); glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE); glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS); } else if(m_bIMGTextureFFExtPresent) { glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DOT3_RGBA); } // Second layer (modulate) glActiveTexture(GL_TEXTURE1); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, m_ui32DiffuseMap); if(m_bCombinersPresent) { glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE); glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS); } else if (m_bIMGTextureFFExtPresent) { glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } // Calculate Dot3 light direction CalculateDot3LightDirection(LightVector); } else { glActiveTexture(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, m_ui32DiffuseMap); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); LightVector.z = -LightVector.z; glLightfv(GL_LIGHT0, GL_POSITION, &LightVector.x); } glMatrixMode(GL_MODELVIEW); // Render mesh SPODNode& Node = m_Scene.pNode[0]; // Rotate the mesh around a point mModelView = m_mView * PVRTMat4::RotationY((float) sin(m_i32Frame * 0.003f) - PVRT_PI_OVER_TWOf); glLoadMatrixf(mModelView.f); DrawMesh(Node.nIdx); // Disable the second layer of texturing if(m_bDrawWithDot3) { glActiveTexture(GL_TEXTURE1); glDisable(GL_TEXTURE_2D); } else glDisable(GL_LIGHTING); // Display info text m_Print3D.DisplayDefaultTitle("PolyBump", m_bDrawWithDot3 ? m_pDescription : "Standard GL lighting" , ePVRTPrint3DSDKLogo); m_Print3D.Flush(); // Increase frame counter ++m_i32Frame; 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); #ifdef ENABLE_LOAD_TIME_STRIP /* Show a message on-screen then generate the necessary data on the second frame. */ if(m_i32Init) { --m_i32Init; if(m_i32Init) { m_Print3D.DisplayDefaultTitle("OptimizeMesh", "Generating data...", ePVRTPrint3DSDKLogo); m_Print3D.Flush(); return true; } StripMesh(); LoadVbos(); } #endif // 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)) // if((m_ui32SwitchTimeDiff > g_ui32TimeAutoSwitch) || PVRShellIsKeyPressed(PVRShellKeyNameACTION1)) { m_ui32SwitchTimeDiff = 0; ++m_i32Page; if(m_i32Page >= (int) m_ui32PageNo) m_i32Page = 0; } PVRTVec3 From; VERTTYPE fFactor; From.x = VERTTYPEMUL(g_fViewDistance, PVRTCOS(m_fViewAngle)); From.y = f2vt(0.0f); From.z = VERTTYPEMUL(g_fViewDistance, PVRTSIN(m_fViewAngle)); // Increase the rotation fFactor = f2vt(0.005f * (float) m_ui32TimeDiff); m_fViewAngle += fFactor; // Ensure it doesn't grow huge and lose accuracy over time if(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,f2vt(1),0)); glMatrixMode(GL_MODELVIEW); myglLoadMatrix(m_mView.f); // Draw the model DrawModel(m_i32Page); // Display the frame rate char pTitle[512]; const char * pDesc; sprintf(pTitle, "Optimize Mesh %.1ffps", m_fFPS); // Print text on screen switch(m_i32Page) { default: pDesc = "Indexed Triangle List: Unoptimized"; break; case 1: pDesc = "Indexed Triangle List: Optimized (at export time)"; break; #ifdef ENABLE_LOAD_TIME_STRIP case 2: pDesc = "Indexed Triangle List: Optimized (at load time)"; break; #endif } m_Print3D.DisplayDefaultTitle(pTitle, pDesc, ePVRTPrint3DSDKLogo); // Flush all Print3D commands m_Print3D.Flush(); 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; }