- this exposed a bizarre issue on Mac where dragging in <AGL/agl.h> in extensions.hxx was pulling in all of Carbon to the global namespace - very scary. As a result, I now need to explicitly include CoreFoundation in fg_init.cxx. - change SG_USING_STD(x) to using std::x Issues: - the logic for X11 and Win32 in RenderTexture and extensions is tortured, please see if you agree I got all the ifdefs correct.
349 lines
9.7 KiB
C++
349 lines
9.7 KiB
C++
|
|
#ifdef HAVE_CONFIG_H
|
|
# include <simgear/simgear_config.h>
|
|
#endif
|
|
|
|
#ifdef HAVE_WINDOWS_H
|
|
# include <windows.h>
|
|
#endif
|
|
|
|
#include <simgear/compiler.h>
|
|
|
|
#include <osg/GL>
|
|
|
|
#ifdef __APPLE__
|
|
# include <GLUT/glut.h>
|
|
#else
|
|
# include <GL/glut.h>
|
|
#endif
|
|
|
|
#include <simgear/screen/extensions.hxx>
|
|
#include <simgear/screen/RenderTexture.h>
|
|
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.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(int argc, char *argv[])
|
|
{
|
|
int argn = argc;
|
|
glutInit(&argn, argv);
|
|
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;
|
|
}
|