--- /dev/null
+
+#include <simgear/compiler.h>
+
+#include SG_GL_H
+#include <GL/glut.h>
+#include <simgear/screen/RenderTexture.h>
+#include <simgear/screen/extensions.hxx>
+
+#include <assert.h>
+#include <stdio.h>
+
+void Reshape(int w, int h);
+
+GLuint iTextureProgram = 0;
+GLuint iPassThroughProgram = 0;
+
+RenderTexture *rt = NULL;
+
+float rectAngle = 0;
+float torusAngle = 0;
+bool bTorusMotion = true;
+bool bRectMotion = true;
+bool bShowDepthTexture = false;
+
+static const char *g_modeTestStrings[] =
+{
+ "rgb tex2D",
+ "rgba tex2D depthTex2D",
+ "rgba=8 depthTexRECT ctt",
+ "rgba samples=4 tex2D ctt",
+ "rgba=8 tex2D mipmap",
+ "rgb=5,6,5 tex2D",
+ "rgba=16f texRECT",
+ "rgba=32f texRECT depthTexRECT",
+ "rgba=16f texRECT depthTexRECT ctt",
+ "r=32f texRECT depth ctt",
+ "rgb double tex2D",
+ "r=32f texRECT ctt aux=4"
+};
+
+static int g_numModeTestStrings = sizeof(g_modeTestStrings) / sizeof(char*);
+static int g_currentString = 0;
+
+//---------------------------------------------------------------------------
+// Function : PrintGLerror
+// Description :
+//---------------------------------------------------------------------------
+void PrintGLerror( char *msg )
+{
+ GLenum errCode;
+ const GLubyte *errStr;
+
+ if ((errCode = glGetError()) != GL_NO_ERROR)
+ {
+ errStr = gluErrorString(errCode);
+ fprintf(stderr,"OpenGL ERROR: %s: %s\n", errStr, msg);
+ }
+}
+
+//---------------------------------------------------------------------------
+// Function : CreateRenderTexture
+// Description :
+//---------------------------------------------------------------------------
+RenderTexture* CreateRenderTexture(const char *initstr)
+{
+ printf("\nCreating with init string: \"%s\"\n", initstr);
+
+ int texWidth = 256, texHeight = 256;
+
+ // Test deprecated interface
+ //RenderTexture *rt2 = new RenderTexture(texWidth, texHeight);
+ //if (!rt2->Initialize(true,false,false,false,false,8,8,8,0))
+
+ RenderTexture *rt2 = new RenderTexture();
+ rt2->Reset(initstr);
+ if (!rt2->Initialize(texWidth, texHeight))
+ {
+ fprintf(stderr, "RenderTexture Initialization failed!\n");
+ }
+
+ // for shadow mapping we still have to bind it and set the correct
+ // texture parameters using the SGI_shadow or ARB_shadow extension
+ // setup the rendering context for the RenderTexture
+ if (rt2->BeginCapture())
+ {
+ Reshape(texWidth, texHeight);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ gluLookAt(0, 0, 3, 0, 0, 0, 0, 1, 0);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_COLOR_MATERIAL);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_DEPTH_TEST);
+ glClearColor(0.2, 0.2, 0.2, 1);
+ rt2->EndCapture();
+ }
+
+ // enable linear filtering if available
+ if (rt2->IsTexture() || rt2->IsDepthTexture())
+ {
+ if (rt2->IsMipmapped())
+ {
+ // Enable trilinear filtering so we can see the mipmapping
+ if (rt2->IsTexture())
+ {
+ rt2->Bind();
+ glTexParameteri(rt2->GetTextureTarget(),
+ GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(rt2->GetTextureTarget(),
+ GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(rt2->GetTextureTarget(),
+ GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
+ }
+
+ if (rt2->IsDepthTexture())
+ {
+ rt2->BindDepth();
+ glTexParameteri(rt2->GetTextureTarget(),
+ GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(rt2->GetTextureTarget(),
+ GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(rt2->GetTextureTarget(),
+ GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
+ }
+ }
+ else if (!(rt2->IsRectangleTexture() || rt2->IsFloatTexture()))
+ {
+ if (rt2->IsTexture())
+ {
+ rt2->Bind();
+ glTexParameteri(rt2->GetTextureTarget(),
+ GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(rt2->GetTextureTarget(),
+ GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
+
+ if (rt2->IsDepthTexture())
+ {
+ rt2->BindDepth();
+ glTexParameteri(rt2->GetTextureTarget(),
+ GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(rt2->GetTextureTarget(),
+ GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
+ }
+ }
+
+ if (rt2->IsDepthTexture())
+ {
+ fprintf(stderr,
+ "\nPress the spacebar to toggle color / depth textures.\n");
+ if (!rt2->IsTexture())
+ bShowDepthTexture = true;
+ }
+ else
+ {
+ if (rt2->IsTexture())
+ bShowDepthTexture = false;
+ }
+
+ PrintGLerror("Create");
+ return rt2;
+}
+
+//---------------------------------------------------------------------------
+// Function : DestroyRenderTexture
+// Description :
+//---------------------------------------------------------------------------
+void DestroyRenderTexture(RenderTexture *rt2)
+{
+ delete rt2;
+}
+
+//---------------------------------------------------------------------------
+// Function : Keyboard
+// Description :
+//---------------------------------------------------------------------------
+void Keyboard(unsigned char key, int x, int y)
+{
+ switch(key)
+ {
+ case 27:
+ case 'q':
+ exit(0);
+ break;
+ case ' ':
+ bShowDepthTexture = !bShowDepthTexture;
+ break;
+ case 13:
+ ++g_currentString%=g_numModeTestStrings;
+ DestroyRenderTexture(rt);
+ rt = CreateRenderTexture(g_modeTestStrings[g_currentString]);
+ break;
+ case 't':
+ bTorusMotion = !bTorusMotion;
+ break;
+ case 'r':
+ bRectMotion = !bRectMotion;
+ break;
+ default:
+ return;
+ }
+}
+
+//---------------------------------------------------------------------------
+// Function : Idle
+// Description :
+//---------------------------------------------------------------------------
+void Idle()
+{
+ // make sure we don't try to display nonexistent textures
+ if (!rt->IsDepthTexture())
+ bShowDepthTexture = false;
+
+ if (bRectMotion) rectAngle += 1;
+ if (bTorusMotion) torusAngle += 1;
+ glutPostRedisplay();
+}
+
+//---------------------------------------------------------------------------
+// Function : Reshape
+// Description :
+//---------------------------------------------------------------------------
+void Reshape(int w, int h)
+{
+ if (h == 0) h = 1;
+
+ glViewport(0, 0, w, h);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ gluPerspective(60.0, (GLfloat)w/(GLfloat)h, 1, 5.0);
+}
+
+//---------------------------------------------------------------------------
+// Function : Display
+// Description :
+//---------------------------------------------------------------------------
+void _Display()
+{
+ if (rt->IsInitialized() && rt->BeginCapture())
+ {
+ if (rt->IsDoubleBuffered()) glDrawBuffer(GL_BACK);
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+
+ glRotatef(torusAngle, 1, 0, 0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glColor3f(1,1,0);
+
+ glutSolidTorus(0.25, 1, 32, 64);
+
+ glPopMatrix();
+ PrintGLerror("RT Update");
+
+ rt->EndCapture();
+ }
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glColor3f(1, 1, 1);
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glRotatef(rectAngle / 10, 0, 1, 0);
+
+ if(bShowDepthTexture && rt->IsDepthTexture())
+ rt->BindDepth();
+ else if (rt->IsTexture()) {
+ rt->Bind();
+ }
+
+ rt->EnableTextureTarget();
+
+ int maxS = rt->GetMaxS();
+ int maxT = rt->GetMaxT();
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(-1, -1);
+ glTexCoord2f(maxS, 0); glVertex2f( 1, -1);
+ glTexCoord2f(maxS, maxT); glVertex2f( 1, 1);
+ glTexCoord2f(0, maxT); glVertex2f(-1, 1);
+ glEnd();
+
+ rt->DisableTextureTarget();
+
+ glPopMatrix();
+
+ PrintGLerror("display");
+ glutSwapBuffers();
+}
+
+
+
+
+//---------------------------------------------------------------------------
+// Function : main
+// Description :
+//---------------------------------------------------------------------------
+int main()
+{
+ glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
+ glutInitWindowPosition(50, 50);
+ glutInitWindowSize(512, 512);
+ glutCreateWindow("TestRenderTexture");
+
+ glutDisplayFunc(_Display);
+ glutIdleFunc(Idle);
+ glutReshapeFunc(Reshape);
+ glutKeyboardFunc(Keyboard);
+
+ Reshape(512, 512);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ gluLookAt(0, 0, 2, 0, 0, 0, 0, 1, 0);
+ glDisable(GL_LIGHTING);
+ glEnable(GL_COLOR_MATERIAL);
+ glEnable(GL_DEPTH_TEST);
+ glClearColor(0.4, 0.6, 0.8, 1);
+
+
+ rt = CreateRenderTexture(g_modeTestStrings[g_currentString]);
+
+ printf("Press Enter to change RenderTexture parameters.\n"
+ "Press 'r' to toggle the rectangle's motion.\n"
+ "Press 't' to toggle the torus' motion.\n");
+
+
+ glutMainLoop();
+ return 0;
+}