# CPVRTPrint3D made rotating content disappear

**URL:** <https://forums.imgtec.com/t/cpvrtprint3d-made-rotating-content-disappear/739>\
**Category:** PowerVR Insider\
**Tags:** pvrvframe\
**Created:** [June 17, 2010, 8:22pm UTC](https://forums.imgtec.com/t/cpvrtprint3d-made-rotating-content-disappear/739 "2010-06-17T20:22:55Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![renaissance](https://avatars.discourse-cdn.com/v4/letter/r/b19c9b/32.png) [@renaissance](https://forums.imgtec.com/u/renaissance)\
**Post date:** [June 17, 2010, 8:22pm UTC](https://forums.imgtec.com/t/cpvrtprint3d-made-rotating-content-disappear/739/1 "2010-06-17T20:22:55Z")

</div>

My application is very similar to the TrainingCourse5\_BasicTnL in the PC version (OGLES2\_WINDOWS\_PCEMULATION\_2.06.26.0649) . The only difference is I would like add text to the window.&nbsp; After I compiled the code and run it, the very first frame is exactly what I am looking for, with the text and the target.

  

 ![]()
  

When I use the PVRVFRAME to start the rotation, the triangle is gone. 
  

 ![]()
  

I am wondering what caused this problem.&nbsp; Thank you very much.
  

In the following is the source code of the OGLES2BasicTnL.cpp I modified by adding the text in there (highlighted with red color). 
  

&nbsp;
  

/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
  

&nbsp;@File&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OGLES2BasicTnL.cpp
  

&nbsp;@Title&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Shows basic transformations and lighting
  

&nbsp;@Version&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  

&nbsp;@Copyright&nbsp;&nbsp;&nbsp; Copyright (C)&nbsp; Imagination Technologies Limited.
  

&nbsp;@Platform&nbsp;&nbsp;&nbsp;&nbsp; Independant
  

&nbsp;@Description&nbsp; Shows basic transformations and lighting
  

\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/  
#include \<math.h\>  
#include \<stdio.h\>
  

#if defined(\_\_APPLE\_\_)  
#import \<OpenGLES/ES2/gl.h\>  
#import \<OpenGLES/ES2/glext.h\>  
#else  
#include \<EGL/egl.h\>  
#include \<GLES2/gl2.h\>  
#endif
  

#include "PVRShell.h"  
#include "OGLES2Tools.h"&nbsp; 
  

  
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
&nbsp;Defines  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
  

// Index to bind the attributes to vertex shaders  
#define VERTEX\_ARRAY&nbsp;0  
#define TEXCOORD\_ARRAY&nbsp;1  
#define NORMAL\_ARRAY&nbsp;2
  

// Size of the texture we create  
#define TEX\_SIZE&nbsp;&nbsp;128
  

/\*!\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
&nbsp;Class implementing the PVRShell functions.  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/  
class OGLESBasicTnL : public PVRShell  
{  
&nbsp;// The vertex and fragment shader OpenGL handles  
&nbsp;GLuint m\_uiVertexShader, m\_uiFragShader;
  

&nbsp;// The program object containing the 2 shader objects  
&nbsp;GLuint m\_uiProgramObject;
  

&nbsp;// Texture handle  
&nbsp;GLuint&nbsp;m\_uiTexture;
  

&nbsp;// VBO handle  
&nbsp;GLuint m\_ui32Vbo;
  

&nbsp;//   
&nbsp;unsigned int m\_ui32VertexStride;
  

&nbsp;// Angle to rotate the triangle  
&nbsp;float&nbsp;m\_fAngle;  
&nbsp;  
**&nbsp;// Print3D class used to display text  
&nbsp;CPVRTPrint3D&nbsp;m\_Print3D;**
  

  
public:  
&nbsp;virtual bool InitApplication();  
&nbsp;virtual bool InitView();  
&nbsp;virtual bool ReleaseView();  
&nbsp;virtual bool QuitApplication();  
&nbsp;virtual bool RenderScene();  
};
  

  
/\*!\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
&nbsp;@Function&nbsp;&nbsp;InitApplication  
&nbsp;@Return&nbsp;&nbsp;bool&nbsp;&nbsp;true if no error occured  
&nbsp;@Description&nbsp;Code in InitApplication() will be called by PVRShell once per  
&nbsp;&nbsp;&nbsp;&nbsp;run, before the rendering context is created.  
&nbsp;&nbsp;&nbsp;&nbsp;Used to initialize variables that are not dependant on it  
&nbsp;&nbsp;&nbsp;&nbsp;(e.g. external modules, loading meshes, etc.)  
&nbsp;&nbsp;&nbsp;&nbsp;If the rendering context is lost, InitApplication() will  
&nbsp;&nbsp;&nbsp;&nbsp;not be called again.  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/  
bool OGLESBasicTnL::InitApplication()  
{  
&nbsp;m\_fAngle = 0;  
&nbsp;return true;  
}
  

/\*!\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
&nbsp;@Function&nbsp;&nbsp;QuitApplication  
&nbsp;@Return&nbsp;&nbsp;bool&nbsp;&nbsp;true if no error occured  
&nbsp;@Description&nbsp;Code in QuitApplication() will be called by PVRShell once per  
&nbsp;&nbsp;&nbsp;&nbsp;run, just before exiting the program.  
&nbsp;&nbsp;&nbsp;&nbsp;If the rendering context is lost, QuitApplication() will  
&nbsp;&nbsp;&nbsp;&nbsp;not be called.  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/  
bool OGLESBasicTnL::QuitApplication()  
{  
&nbsp;&nbsp;&nbsp; return true;  
}
  

/\*!\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
&nbsp;@Function&nbsp;&nbsp;InitView  
&nbsp;@Return&nbsp;&nbsp;bool&nbsp;&nbsp;true if no error occured  
&nbsp;@Description&nbsp;Code in InitView() will be called by PVRShell upon  
&nbsp;&nbsp;&nbsp;&nbsp;initialization or after a change in the rendering context.  
&nbsp;&nbsp;&nbsp;&nbsp;Used to initialize variables that are dependant on the rendering  
&nbsp;&nbsp;&nbsp;&nbsp;context (e.g. textures, vertex buffers, etc.)  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/  
bool OGLESBasicTnL::InitView()  
{  
&nbsp;  
&nbsp;**bool bRotate = false;  
&nbsp;if(m\_Print3D.SetTextures(0,PVRShellGet(prefWidth),PVRShellGet(prefHeight), bRotate) != PVR\_SUCCESS)  
&nbsp;{  
&nbsp;&nbsp;PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Print3Dn");  
&nbsp;&nbsp;return false;  
&nbsp;}&nbsp;&nbsp;** 
  

&nbsp;// Fragment and vertex shaders code  
&nbsp;char\* pszFragShader = "  
&nbsp;&nbsp;uniform sampler2D sampler2d;  
&nbsp;&nbsp;varying mediump float&nbsp;varDot;  
&nbsp;&nbsp;varying mediump vec2&nbsp;varCoord;  
&nbsp;&nbsp;void main (void)  
&nbsp;&nbsp;{  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gl\_FragColor = texture2D(sampler2d,varCoord) \* varDot;  
&nbsp;&nbsp;}";
  

&nbsp;char\* pszVertShader = "  
&nbsp;&nbsp;attribute highp vec4&nbsp;myVertex;  
&nbsp;&nbsp;attribute mediump vec3&nbsp;myNormal;  
&nbsp;&nbsp;attribute mediump vec4&nbsp;myUV;  
&nbsp;&nbsp;uniform mediump mat4&nbsp;myPMVMatrix;  
&nbsp;&nbsp;uniform mediump mat3&nbsp;myModelViewIT;  
&nbsp;&nbsp;uniform mediump vec3&nbsp;myLightDirection;  
&nbsp;&nbsp;varying mediump float&nbsp;varDot;  
&nbsp;&nbsp;varying mediump vec2&nbsp;varCoord;  
&nbsp;&nbsp;void main(void)  
&nbsp;&nbsp;{  
&nbsp;&nbsp;&nbsp;gl\_Position = myPMVMatrix \* myVertex;  
&nbsp;&nbsp;&nbsp;varCoord = myUV.st;  
&nbsp;&nbsp;&nbsp;mediump vec3 transNormal = myModelViewIT \* myNormal;  
&nbsp;&nbsp;&nbsp;varDot = max( dot(transNormal, myLightDirection), 0.0 );  
&nbsp;&nbsp;}";
  

&nbsp;// Create the fragment shader object  
&nbsp;m\_uiFragShader = glCreateShader(GL\_FRAGMENT\_SHADER);
  

&nbsp;// Load the source code into it  
&nbsp;glShaderSource(m\_uiFragShader, 1, (const char\*\*)&pszFragShader, NULL);
  

&nbsp;// Compile the source code  
&nbsp;glCompileShader(m\_uiFragShader);
  

&nbsp;// Check if compilation succeeded  
&nbsp;GLint bShaderCompiled;  
&nbsp;&nbsp;&nbsp; glGetShaderiv(m\_uiFragShader, GL\_COMPILE\_STATUS, &bShaderCompiled);  
&nbsp;if (!bShaderCompiled)  
&nbsp;{  
&nbsp;&nbsp;// An error happened, first retrieve the length of the log message  
&nbsp;&nbsp;int i32InfoLogLength, i32CharsWritten;  
&nbsp;&nbsp;glGetShaderiv(m\_uiFragShader, GL\_INFO\_LOG\_LENGTH, &i32InfoLogLength);
  

&nbsp;&nbsp;// Allocate enough space for the message and retrieve it  
&nbsp;&nbsp;char\* pszInfoLog = new char[i32InfoLogLength];  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; glGetShaderInfoLog(m\_uiFragShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog);
  

&nbsp;&nbsp;/\*  
&nbsp;&nbsp;&nbsp;Displays the message in a dialog box when the application quits  
&nbsp;&nbsp;&nbsp;using the shell PVRShellSet function with first parameter prefExitMessage.  
&nbsp;&nbsp;\*/  
&nbsp;&nbsp;char\* pszMsg = new char[i32InfoLogLength+256];  
&nbsp;&nbsp;sprintf(pszMsg, "Failed to compile fragment shader: %s", pszInfoLog);  
&nbsp;&nbsp;PVRShellSet(prefExitMessage, pszMsg);  
&nbsp;&nbsp;delete [] pszMsg;  
&nbsp;&nbsp;delete [] pszInfoLog;  
&nbsp;&nbsp;return false;  
&nbsp;}
  

&nbsp;// Loads the vertex shader in the same way  
&nbsp;m\_uiVertexShader = glCreateShader(GL\_VERTEX\_SHADER);  
&nbsp;glShaderSource(m\_uiVertexShader, 1, (const char\*\*)&pszVertShader, NULL);  
&nbsp;glCompileShader(m\_uiVertexShader);  
&nbsp;&nbsp;&nbsp; glGetShaderiv(m\_uiVertexShader, GL\_COMPILE\_STATUS, &bShaderCompiled);  
&nbsp;if (!bShaderCompiled)  
&nbsp;{  
&nbsp;&nbsp;int i32InfoLogLength, i32CharsWritten;  
&nbsp;&nbsp;glGetShaderiv(m\_uiVertexShader, GL\_INFO\_LOG\_LENGTH, &i32InfoLogLength);  
&nbsp;&nbsp;char\* pszInfoLog = new char[i32InfoLogLength];  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; glGetShaderInfoLog(m\_uiVertexShader, i32InfoLogLength, &i32CharsWritten, pszInfoLog);  
&nbsp;&nbsp;char\* pszMsg = new char[i32InfoLogLength+256];  
&nbsp;&nbsp;sprintf(pszMsg, "Failed to compile vertex shader: %s", pszInfoLog);  
&nbsp;&nbsp;PVRShellSet(prefExitMessage, pszMsg);  
&nbsp;&nbsp;delete [] pszMsg;  
&nbsp;&nbsp;delete [] pszInfoLog;  
&nbsp;&nbsp;return false;  
&nbsp;}
  

&nbsp;// Create the shader program  
&nbsp;&nbsp;&nbsp; m\_uiProgramObject = glCreateProgram();
  

&nbsp;// Attach the fragment and vertex shaders to it  
&nbsp;&nbsp;&nbsp; glAttachShader(m\_uiProgramObject, m\_uiFragShader);  
&nbsp;&nbsp;&nbsp; glAttachShader(m\_uiProgramObject, m\_uiVertexShader);
  

&nbsp;// Bind the custom vertex attribute "myVertex" to location VERTEX\_ARRAY  
&nbsp;&nbsp;&nbsp; glBindAttribLocation(m\_uiProgramObject, VERTEX\_ARRAY, "myVertex");  
&nbsp;// Bind the custom vertex attribute "myUV" to location TEXCOORD\_ARRAY  
&nbsp;&nbsp;&nbsp; glBindAttribLocation(m\_uiProgramObject, TEXCOORD\_ARRAY, "myUV");
  

  
&nbsp;// Link the program  
&nbsp;&nbsp;&nbsp; glLinkProgram(m\_uiProgramObject);
  

&nbsp;// Check if linking succeeded in the same way we checked for compilation success  
&nbsp;&nbsp;&nbsp; GLint bLinked;  
&nbsp;&nbsp;&nbsp; glGetProgramiv(m\_uiProgramObject, GL\_LINK\_STATUS, &bLinked);  
&nbsp;if (!bLinked)  
&nbsp;{  
&nbsp;&nbsp;int i32InfoLogLength, i32CharsWritten;  
&nbsp;&nbsp;glGetProgramiv(m\_uiProgramObject, GL\_INFO\_LOG\_LENGTH, &i32InfoLogLength);  
&nbsp;&nbsp;char\* pszInfoLog = new char[i32InfoLogLength];  
&nbsp;&nbsp;glGetProgramInfoLog(m\_uiProgramObject, i32InfoLogLength, &i32CharsWritten, pszInfoLog);  
&nbsp;&nbsp;char\* pszMsg = new char[i32InfoLogLength+256];  
&nbsp;&nbsp;sprintf(pszMsg, "Failed to link program: %s", pszInfoLog);  
&nbsp;&nbsp;PVRShellSet(prefExitMessage, pszMsg);  
&nbsp;&nbsp;delete [] pszMsg;  
&nbsp;&nbsp;delete [] pszInfoLog;  
&nbsp;&nbsp;return false;  
&nbsp;}
  

&nbsp;// Actually use the created program  
&nbsp;glUseProgram(m\_uiProgramObject);
  

&nbsp;// Sets the sampler2D variable to the first texture unit  
&nbsp;glUniform1i(glGetUniformLocation(m\_uiProgramObject, "sampler2d"), 0);
  

  
&nbsp;// Sets the clear color  
&nbsp;glClearColor(0.6f, 0.8f, 1.0f, 1.0f);
  

&nbsp;/\*  
&nbsp;&nbsp;Creates the texture.  
&nbsp;&nbsp;Please refer to the training course "Texturing" for a detailed explanation.  
&nbsp;\*/  
&nbsp;glGenTextures(1, &m\_uiTexture);  
&nbsp;glBindTexture(GL\_TEXTURE\_2D, m\_uiTexture);  
&nbsp;GLuint\* pTexData = new GLuint[TEX\_SIZE\*TEX\_SIZE];  
&nbsp;for (int i=0; i\<TEX\_SIZE; i++)  
&nbsp;for (int j=0; j\<TEX\_SIZE; j++)  
&nbsp;{  
&nbsp;&nbsp;GLuint col = (255L\<\<24) + ((255L-j\*2)\<\<16) + ((255L-i)\<\<8) + (255L-i\*2);  
&nbsp;&nbsp;if ( ((i\*j)/8) % 2 ) col = (GLuint) (255L\<\<24) + (255L\<\<16) + (0L\<\<8) + (255L);  
&nbsp;&nbsp;pTexData[j\*TEX\_SIZE+i] = col;  
&nbsp;}  
&nbsp;glTexImage2D(GL\_TEXTURE\_2D, 0, GL\_RGBA, TEX\_SIZE, TEX\_SIZE, 0, GL\_RGBA, GL\_UNSIGNED\_BYTE, pTexData);  
&nbsp;glTexParameteri(GL\_TEXTURE\_2D, GL\_TEXTURE\_MIN\_FILTER, GL\_LINEAR );  
&nbsp;glTexParameteri(GL\_TEXTURE\_2D, GL\_TEXTURE\_MAG\_FILTER, GL\_LINEAR );  
&nbsp;delete [] pTexData;
  

&nbsp;// Create VBO for the triangle from our data
  

&nbsp;// Interleaved vertex data  
&nbsp;GLfloat afVertices[] = {-0.4f,-0.4f,0.0f, // Pos  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.0f,0.0f ,&nbsp;&nbsp; // UVs  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.0f,0.0f,1.0f,&nbsp; // Normals  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.4f,-0.4f,0.0f,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.0f,0.0f ,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.0f,0.0f,1.0f,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.0f,0.4f ,0.0f,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.5f,1.0f,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.0f,0.0f,1.0f  
};
  

&nbsp;glGenBuffers(1, &m\_ui32Vbo);
  

&nbsp;m\_ui32VertexStride = 8 \* sizeof(GLfloat); // 3 floats for the pos, 2 for the UVs, 3 for normals
  

&nbsp;// Bind the VBO  
&nbsp;glBindBuffer(GL\_ARRAY\_BUFFER, m\_ui32Vbo);
  

&nbsp;// Set the buffer's data  
&nbsp;glBufferData(GL\_ARRAY\_BUFFER, 5 \* m\_ui32VertexStride, afVertices, GL\_STATIC\_DRAW);
  

&nbsp;// Unbind the VBO  
&nbsp;glBindBuffer(GL\_ARRAY\_BUFFER, 0);  
&nbsp;return true;  
}
  

/\*!\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
&nbsp;@Function&nbsp;&nbsp;ReleaseView  
&nbsp;@Return&nbsp;&nbsp;bool&nbsp;&nbsp;true if no error occured  
&nbsp;@Description&nbsp;Code in ReleaseView() will be called by PVRShell when the  
&nbsp;&nbsp;&nbsp;&nbsp;application quits or before a change in the rendering context.  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/  
bool OGLESBasicTnL::ReleaseView()  
{  
&nbsp;// Frees the texture  
&nbsp;glDeleteTextures(1, &m\_uiTexture);
  

&nbsp;// Release Vertex buffer object.  
&nbsp;glDeleteBuffers(1, &m\_ui32Vbo);
  

&nbsp;// Frees the OpenGL handles for the program and the 2 shaders  
&nbsp;glDeleteProgram(m\_uiProgramObject);  
&nbsp;glDeleteShader(m\_uiVertexShader);  
&nbsp;glDeleteShader(m\_uiFragShader);  
&nbsp;//m\_Print3D.DeleteWindow(handle);   
**&nbsp;m\_Print3D.ReleaseTextures();**  
&nbsp;return true;  
}
  

/\*!\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
&nbsp;@Function&nbsp;&nbsp;RenderScene  
&nbsp;@Return&nbsp;&nbsp;bool&nbsp;&nbsp;true if no error occured  
&nbsp;@Description&nbsp;Main rendering loop function of the program. The shell will  
&nbsp;&nbsp;&nbsp;&nbsp;call this function every frame.  
&nbsp;&nbsp;&nbsp;&nbsp;eglSwapBuffers() will be performed by PVRShell automatically.  
&nbsp;&nbsp;&nbsp;&nbsp;PVRShell will also manage important OS events.  
&nbsp;&nbsp;&nbsp;&nbsp;Will also manage relevent OS events. The user has access to  
&nbsp;&nbsp;&nbsp;&nbsp;these events through an abstraction layer provided by PVRShell.  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/  
bool OGLESBasicTnL::RenderScene()  
{  
&nbsp;float aModelViewIT[] =  
&nbsp;{  
&nbsp;&nbsp;cos(m\_fAngle),&nbsp;0,&nbsp;sin(m\_fAngle),  
&nbsp;&nbsp;0,&nbsp;&nbsp;&nbsp;&nbsp;1,&nbsp;0,  
&nbsp;&nbsp;-sin(m\_fAngle),&nbsp;0,&nbsp;cos(m\_fAngle)  
&nbsp;};
  

&nbsp;// Clears the color and depth buffer  
&nbsp;glClear(GL\_COLOR\_BUFFER\_BIT | GL\_DEPTH\_BUFFER\_BIT);
  

&nbsp;/\*  
&nbsp;&nbsp;Bind the projection model view matrix (PMVMatrix) to the  
&nbsp;&nbsp;corresponding uniform variable in the shader.  
&nbsp;&nbsp;This matrix is used in the vertex shader to transform the vertices.  
&nbsp;\*/  
&nbsp;float aPMVMatrix[] =  
&nbsp;{  
&nbsp;&nbsp;cos(m\_fAngle),&nbsp;0,&nbsp;sin(m\_fAngle),&nbsp;0,  
&nbsp;&nbsp;0,&nbsp;&nbsp;&nbsp;&nbsp;1,&nbsp;0,&nbsp;&nbsp;&nbsp;&nbsp;0,  
&nbsp;&nbsp;-sin(m\_fAngle),&nbsp;0,&nbsp;cos(m\_fAngle),&nbsp;0,  
&nbsp;&nbsp;0,&nbsp;&nbsp;&nbsp;&nbsp;0,&nbsp;0,&nbsp;&nbsp;&nbsp;&nbsp;1  
&nbsp;};  
&nbsp;int i32Location = glGetUniformLocation(m\_uiProgramObject, "myPMVMatrix");  
&nbsp;glUniformMatrix4fv( i32Location, 1, GL\_FALSE, aPMVMatrix);
  

&nbsp;/\*  
&nbsp;&nbsp;Bind the Model View Inverse Transpose matrix to the shader.  
&nbsp;&nbsp;This matrix is used in the vertex shader to transform the normals.  
&nbsp;\*/  
&nbsp;i32Location = glGetUniformLocation(m\_uiProgramObject, "myModelViewIT");  
&nbsp;glUniformMatrix3fv( i32Location, 1, GL\_FALSE, aModelViewIT);
  

&nbsp;// Bind the Light Direction vector to the shader  
&nbsp;i32Location = glGetUniformLocation(m\_uiProgramObject, "myLightDirection");  
&nbsp;glUniform3f( i32Location, 0, 0, 1);
  

&nbsp;// Increments the angle of the view  
&nbsp;m\_fAngle += .02f;
  

&nbsp;/\*  
&nbsp;&nbsp;Draw a triangle.  
&nbsp;&nbsp;Please refer to the training course IntroducingPVRShell for a detailed explanation.  
&nbsp;\*/
  

&nbsp;// Bind the VBO  
&nbsp;glBindBuffer(GL\_ARRAY\_BUFFER, m\_ui32Vbo);
  

&nbsp;// Pass the vertex data  
&nbsp;glEnableVertexAttribArray(VERTEX\_ARRAY);  
&nbsp;glVertexAttribPointer(VERTEX\_ARRAY, 3, GL\_FLOAT, GL\_FALSE, m\_ui32VertexStride, 0);
  

&nbsp;// Pass the texture coordinates data  
&nbsp;glEnableVertexAttribArray(TEXCOORD\_ARRAY);  
&nbsp;glVertexAttribPointer(TEXCOORD\_ARRAY, 2, GL\_FLOAT, GL\_FALSE, m\_ui32VertexStride, (void\*) (3 \* sizeof(GLfloat)) /\* Uvs start after the vertex position \*/);
  

&nbsp;// Pass the normals data  
&nbsp;glEnableVertexAttribArray(NORMAL\_ARRAY);  
&nbsp;glVertexAttribPointer(NORMAL\_ARRAY, 3, GL\_FLOAT, GL\_FALSE, m\_ui32VertexStride, (void\*) (5 \* sizeof(GLfloat)) /\* Normals start after the position and uvs \*/);
  

&nbsp;// Draws a non-indexed triangle array  
&nbsp;glDrawArrays(GL\_TRIANGLES, 0, 3);
  

&nbsp;// Unbind the VBO  
&nbsp;glBindBuffer(GL\_ARRAY\_BUFFER, 0);
  

**&nbsp;m\_Print3D.DisplayDefaultTitle("Window test", "", 0);  
&nbsp;m\_Print3D.Flush();**
  

  
&nbsp;return true;  
}
  

/\*!\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
&nbsp;@Function&nbsp;&nbsp;NewDemo  
&nbsp;@Return&nbsp;&nbsp;PVRShell\*&nbsp;&nbsp;The demo supplied by the user  
&nbsp;@Description&nbsp;This function must be implemented by the user of the shell.  
&nbsp;&nbsp;&nbsp;&nbsp;The user should return its PVRShell object defining the  
&nbsp;&nbsp;&nbsp;&nbsp;behaviour of the application.  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/  
PVRShell\* NewDemo()  
{  
&nbsp;return new OGLESBasicTnL();  
}
  

/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
&nbsp;End of file (OGLESBasicTnL.cpp)  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
  

  
&nbsp;
  

  
&nbsp;
  

&nbsp;
renaissance2010-06-17 22:25:08

---

<div class="post-metadata">

**Author:** ![Scott](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.imgtec.com/scott/32/256_2.png) [@Scott](https://forums.imgtec.com/u/Scott)\
**Post date:** [June 18, 2010, 8:03am UTC](https://forums.imgtec.com/t/cpvrtprint3d-made-rotating-content-disappear/739/2 "2010-06-18T08:03:18Z")

</div>

Hi,

&nbsp;
  

When Print3D draws the text it changes various GL render states and doesn't put them back. If you have a look at the APIRenderStates function that is part of the Print3D code you'll be able to see the states that it changes. This function should give you an idea of what to set after your call to m\_Print3D.Flush() to put things back the way they were.
  

&nbsp;
  

I haven't tried to compile your code but my first suggestion would be to move 
  

&nbsp;
  

// Actually use the created program  
&nbsp;glUseProgram(m\_uiProgramObject);
  

&nbsp;
  

to the beginning of your RenderScene as Print3D uses its own shaders so you need to switch back to yours.
  

&nbsp;
  

Thanks,
  

&nbsp;
  

Scott

---

<div class="post-metadata">

**Author:** ![renaissance](https://avatars.discourse-cdn.com/v4/letter/r/b19c9b/32.png) [@renaissance](https://forums.imgtec.com/u/renaissance)\
**Post date:** [June 18, 2010, 3:29pm UTC](https://forums.imgtec.com/t/cpvrtprint3d-made-rotating-content-disappear/739/3 "2010-06-18T15:29:02Z")

</div>

Thank you so much, Scott.

Your method works partially. I do have the rotating triangle back. However, the texture and color is gone. In the attached image, you will see what happend. I am just wondering, when I call&nbsp;&nbsp;glUseProgram(m\_uiProgramObject) again, where did I pass the texture or color information? 
  

&nbsp;
  

Thank you,
  

Renaissance ![]()

---

<div class="post-metadata">

**Author:** ![Scott](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.imgtec.com/scott/32/256_2.png) [@Scott](https://forums.imgtec.com/u/Scott)\
**Post date:** [June 22, 2010, 8:13am UTC](https://forums.imgtec.com/t/cpvrtprint3d-made-rotating-content-disappear/739/4 "2010-06-22T08:13:37Z")

</div>

renaissance wrote:

where did I pass the texture or color information? 
  

  

&nbsp;
  

I'm afraid I can't view your screenshots as you need to upload them somewhere and link to them. Anyway, you bind your texture in your InitView but this is another thing that Print3D changes so you need to add
  

Code:

glBindTexture(GL\_TEXTURE\_2D, m\_uiTexture);  

  

to your RenderScene so your texture is used.

---

<div class="post-metadata">

**Author:** ![renaissance](https://avatars.discourse-cdn.com/v4/letter/r/b19c9b/32.png) [@renaissance](https://forums.imgtec.com/u/renaissance)\
**Post date:** [June 22, 2010, 9:25pm UTC](https://forums.imgtec.com/t/cpvrtprint3d-made-rotating-content-disappear/739/5 "2010-06-22T21:25:30Z")

</div>

Thank you very much, Scott. What you suggested works well in my test.

&nbsp;
  

 ![Thumbs%20Up](https://www.imgtec.com/forum/smileys/smiley20.gif)

---

<div class="post-metadata">

**Author:** ![ernasty](https://avatars.discourse-cdn.com/v4/letter/e/b9bd4f/32.png) [@ernasty](https://forums.imgtec.com/u/ernasty)\
**Post date:** [November 9, 2010, 6:55am UTC](https://forums.imgtec.com/t/cpvrtprint3d-made-rotating-content-disappear/739/6 "2010-11-09T06:55:47Z")

</div>

One really hard to find thing I just figured out is that the Flush() function&nbsp;leaves culling to front faces with clockwise winding.

&nbsp;
  

glEnable(GL\_CULL\_FACE);
  

glFrontFace(GL\_CW);
  

glCullFace(GL\_FRONT);
  

&nbsp;
  

This seems to be the opposite of the winding order I am seeing from my 3ds max exported POD file.&nbsp; When I add:
  

&nbsp;
  

glFrontFace(GL\_CCW);
  

&nbsp;
  

my front faces show up again.
  

&nbsp;
