//------------------------------------------------------------------------------
// Name: ogl_frame_buffer_object.cpp
// Author: Kevin Harris (kevin@codesampler.com)
// Last Modified: 07/06/05
// Description: This sample demonstrates how to create dynamic textures
// through off-screen rendering. The off-screen rendering step
// is accomplished using a frame-buffer and render-buffer
// object, which is created using OpenGL's
// EXT_framebuffer_object extension.
//
// As a demonstration, a spinning textured cube is rendered
// to a frame-buffer object, which is in turn, used to create a
// dynamic texture. The dynamic texture is then used to texture
// a second spinning cube, which will be rendered to the
// application's window.
//
// Control Keys: Left Mouse Button - Spin the large, black cube.
// Right Mouse Button - Spin the textured cube being rendered
// into the p-buffer.
//
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// Note: The EXT_framebuffer_object extension is an excellent replacement for
// the WGL_ARB_pbuffer and WGL_ARB_render_texture combo which is normally
// used to create dynamic textures. An example of this older technique
// can be found here:
//
// http://www.codesampler.com/oglsrc/oglsrc_7.htm#ogl_offscreen_rendering
//------------------------------------------------------------------------------
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdlib.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
#include "resource.h"
//------------------------------------------------------------------------------
// FUNCTION POINTERS FOR OPENGL EXTENSIONS
//------------------------------------------------------------------------------
// For convenience, this project ships with its own "glext.h" extension header
// file. If you have trouble running this sample, it may be that this "glext.h"
// file is defining something that your hardware doesn�t actually support.
// Try recompiling the sample using your own local, vendor-specific "glext.h"
// header file.
#include "glext.h" // Sample's header file
//#include <GL/glext.h> // Your local header file
// EXT_framebuffer_object - http://oss.sgi.com/projects/ogl-sample/registry/EXT/framebuffer_object.txt
extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT = NULL;
extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT = NULL;
extern PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT = NULL;
extern PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT = NULL;
extern PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT = NULL;
extern PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glGetRenderbufferParameterivEXT = NULL;
extern PFNGLISFRAMEBUFFEREXTPROC glIsFramebufferEXT = NULL;
extern PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT = NULL;
extern PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT = NULL;
extern PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT = NULL;
extern PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT = NULL;
extern PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glFramebufferTexture1DEXT = NULL;
extern PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT = NULL;
extern PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT = NULL;
extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT = NULL;
extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT = NULL;
extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT = NULL;
//------------------------------------------------------------------------------
// GLOBALS
//------------------------------------------------------------------------------
HWND g_hWnd = NULL;
HDC g_hDC = NULL;
HGLRC g_hRC = NULL;
GLuint g_testTextureID = -1;
GLuint g_dynamicTextureID = -1;
GLuint g_frameBuffer;
GLuint g_depthRenderBuffer;
int g_nWindowWidth = 640;
int g_nWindowHeight = 480;
const int RENDERBUFFER_WIDTH = 256;
const int RENDERBUFFER_HEIGHT = 256;
float g_fSpinX_L = 0.0f;
float g_fSpinY_L = 0.0f;
float g_fSpinX_R = 0.0f;
float g_fSpinY_R = 0.0f;
struct Vertex
{
float tu, tv;
float x, y, z;
};
Vertex g_cubeVertices[] =
{
{ 0.0f,0.0f, -1.0f,-1.0f, 1.0f },
{ 1.0f,0.0f, 1.0f,-1.0f, 1.0f },
{ 1.0f,1.0f, 1.0f, 1.0f, 1.0f },
{ 0.0f,1.0f, -1.0f, 1.0f, 1.0f },
{ 1.0f,0.0f, -1.0f,-1.0f,-1.0f },
{ 1.0f,1.0f, -1.0f, 1.0f,-1.0f },
{ 0.0f,1.0f, 1.0f, 1.0f,-1.0f },
{ 0.0f,0.0f, 1.0f,-1.0f,-1.0f },
{ 0.0f,1.0f, -1.0f, 1.0f,-1.0f },
{ 0.0f,0.0f, -1.0f, 1.0f, 1.0f },
{ 1.0f,0.0f, 1.0f, 1.0f, 1.0f },
{ 1.0f,1.0f, 1.0f, 1.0f,-1.0f },
{ 1.0f,1.0f, -1.0f,-1.0f,-1.0f },
{ 0.0f,1.0f, 1.0f,-1.0f,-1.0f },
{ 0.0f,0.0f, 1.0f,-1.0f, 1.0f },
{ 1.0f,0.0f, -1.0f,-1.0f, 1.0f },
{ 1.0f,0.0f, 1.0f,-1.0f,-1.0f },
{ 1.0f,1.0f, 1.0f, 1.0f,-1.0f },
{ 0.0f,1.0f, 1.0f, 1.0f, 1.0f },
{ 0.0f,0.0f, 1.0f,-1.0f, 1.0f },
{ 0.0f,0.0f, -1.0f,-1.0f,-1.0f },
{ 1.0f,0.0f, -1.0f,-1.0f, 1.0f },
{ 1.0f,1.0f, -1.0f, 1.0f, 1.0f },
{ 0.0f,1.0f, -1.0f, 1.0f,-1.0f }
};
//------------------------------------------------------------------------------
// PROTOTYPES
//------------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow);
LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void loadTexture(void);
void init(void);
void render(void);
void shutDown(void);
//------------------------------------------------------------------------------
// Name: WinMain()
// Desc: The application's entry point
//------------------------------------------------------------------------------
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow )
{
WNDCLASSEX winClass;
MSG uMsg;
memset(&uMsg,0,sizeof(uMsg));
winClass.lpszClassName = "MY_WINDOWS_CLASS";
winClass.cbSize = sizeof(WNDCLASSEX);
winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
winClass.lpfnWndProc = WindowProc;
winClass.hInstance = hInstance;
winClass.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_OPENGL_ICON);
winClass.hIconSm = LoadIcon(hInstance, (LPCTSTR)IDI_OPENGL_ICON);
winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
winClass.lpszMenuName = NULL;
winClass.cbClsExtra = 0;
winClass.cbWndExtra = 0;
if( !RegisterClassEx(&winClass) )
return E_FAIL;
g_hWnd = CreateWindowEx( NULL, "MY_WINDOWS_CLASS",
"OpenGL - Off-Screen Rendering Using Frame Buffer Objects",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0, 0, 640, 480, NULL, NULL, hInstance, NULL );
if( g_hWnd == NULL )
return E_FAIL;
ShowWindow( g_hWnd, nCmdShow );
UpdateWindow( g_hWnd );
init();
while( uMsg.message != WM_QUIT )
{
if( PeekMessage( &uMsg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &uMsg );
DispatchMessage( &uMsg );
}
else
render();
}
shutDown();
UnregisterClass( "MY_WINDOWS_CLASS", winClass.hInstance );
return uMsg.wParam;
}
//------------------------------------------------------------------------------
// Name: WindowProc()
// Desc: The window's message handler
//----------------------------------------------------------------------