//-----------------------------------------------------------------------------
// Name: ogl_cg_simple.cpp
// Author: Kevin Harris
// Last Modified: 04/21/05
// Description: This sample demonstrates how to write a CG style shader
// with OpenGL
//-----------------------------------------------------------------------------
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <Cg/Cg.h>
#include <Cg/cgGL.h>
#include "resource.h"
//-----------------------------------------------------------------------------
// GLOBALS
//-----------------------------------------------------------------------------
HDC g_hDC = NULL;
HGLRC g_hRC = NULL;
HWND g_hWnd = NULL;
HINSTANCE g_hInstance = NULL;
CGprofile g_CGprofile;
CGcontext g_CGcontext;
CGprogram g_CGprogram;
CGparameter g_CGparam_constColor;
float g_fSpinX = 0.0f;
float g_fSpinY = 0.0f;
struct Vertex
{
float r, g, b;
float x, y, z;
};
Vertex g_quadVertices[] =
{
// r g b x y z
{ 1.0f,1.0f,0.0f, -1.0f,-1.0f, 0.0f },
{ 1.0f,0.0f,0.0f, 1.0f,-1.0f, 0.0f },
{ 0.0f,1.0f,0.0f, 1.0f, 1.0f, 0.0f },
{ 0.0f,0.0f,1.0f, -1.0f, 1.0f, 0.0f },
};
//-----------------------------------------------------------------------------
// PROTOTYPES
//-----------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE g_hInstance,HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow);
LRESULT CALLBACK WindowProc(HWND g_hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void init(void);
void render(void);
void shutDown(void);
void initShader(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 - Simple Vertex Shader Using CG",WS_OVERLAPPEDWINDOW,
0,0, 640,480, NULL, NULL, g_hInstance, NULL );
if( g_hWnd == NULL )
return E_FAIL;
ShowWindow( g_hWnd, nCmdShow );
UpdateWindow( g_hWnd );
init();
initShader();
while( uMsg.message != WM_QUIT )
{
if( PeekMessage( &uMsg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &uMsg );
DispatchMessage( &uMsg );
}
else
render();
}
shutDown();
UnregisterClass( "MY_WINDOWS_CLASS", g_hInstance );
return uMsg.wParam;
}
//-----------------------------------------------------------------------------
// Name: WindowProc()
// Desc: The window's message handler
//-----------------------------------------------------------------------------
LRESULT CALLBACK WindowProc( HWND g_hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam )
{
static POINT ptLastMousePosit;
static POINT ptCurrentMousePosit;
static bool bMousing;
switch( msg )
{
case WM_KEYDOWN:
{
switch( wParam )
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
}
}
break;
case WM_LBUTTONDOWN:
{
ptLastMousePosit.x = ptCurrentMousePosit.x = LOWORD (lParam);
ptLastMousePosit.y = ptCurrentMousePosit.y = HIWORD (lParam);
bMousing = true;
}
break;
case WM_LBUTTONUP:
{
bMousing = false;
}
break;
case WM_MOUSEMOVE:
{
ptCurrentMousePosit.x = LOWORD (lParam);
ptCurrentMousePosit.y = HIWORD (lParam);
if( bMousing )
{
g_fSpinX -= (ptCurrentMousePosit.x - ptLastMousePosit.x);
g_fSpinY -= (ptCurrentMousePosit.y - ptLastMousePosit.y);
}
ptLastMousePosit.x = ptCurrentMousePosit.x;
ptLastMousePosit.y = ptCurrentMousePosit.y;
}
break;
case WM_SIZE:
{
int nWidth = LOWORD(lParam);
int nHeight = HIWORD(lParam);
glViewport(0, 0, nWidth, nHeight);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 45.0, (GLdouble)nWidth / (GLdouble)nHeight, 0.1, 100.0);
}
break;
case WM_CLOSE:
{
PostQuitMessage(0);
}
case WM_DESTROY:
{
PostQuitMessage(0);
}
break;
default:
{
return DefWindowProc( g_hWnd, msg, wParam, lParam );
}
break;
}
return 0;
}
//-----------------------------------------------------------------------------
// Name: init()
// Desc:
//-----------------------------------------------------------------------------
void init( void )
{
GLuint PixelFormat;
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 16;
pfd.cDepthBits = 16;
g_hDC = GetDC( g_hWnd );
PixelFormat = ChoosePixelFormat( g_hDC, &pfd );
SetPixelFormat( g_hDC, PixelFormat, &pfd );
g_hRC = wglCreateContext( g_hDC );
wglMakeCurrent( g_hDC, g_hRC );
glEnable( GL_TEXTURE_2D );
glEnable( GL_DEPTH_TEST );
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 45.0f, 640.0f / 480.0f, 0.1f, 100.0f );
}
//-----------------------------------------------------------------------------
// Name: initShader()
// Desc: Load the CG shader
//-----------------------------------------------------------------------------
void initShader( void )
{
//
// Search for a valid vertex shader profile in this order:
//
// CG_PROFILE_ARBVP1 - GL_ARB_vertex_program
// CG_PROFILE_VP40 - GL_ARB_vertex_program + GL_NV_vertex_program3
//
if( cgGLIsProfileSupported(CG_PROFILE_ARBVP1) )
g_CGprofile = CG_PROFILE_ARBVP1;
else if( cgGLIsProfileSupported(CG_PROFILE_VP40) )
g_CGprofile = CG_PROFILE_VP20;
else
{
MessageBox( NULL,"Failed to initialize vertex shader! Hardware doesn't "
"support any of the required vertex shading extensions!",
"ERROR",MB_OK|MB_ICONEXCLAMATION );
return;
}
// Create the context...
g_CGcontext = cgCreateContext();
//
// Create the vertex shader...
//
g_CGprogram = cgCreateProgramFromFile( g_CGcontext,
CG_SOURCE,
"ogl_cg_simple.cg",
g_CGprofile,
NULL,
NULL );
//
// Load the program using Cg's expanded interface...
//
cgGLLoadProgram( g_CGprogram );
//
// Bind some parameters by name so we can set them later...
//
g_CGparam_constColor = cgGetNamedParameter(g_CGprogram, "constColor");
}
//-----------------------------------------------------------------------------
// Name: shutDown()
// Desc:
//-----------------------------------------------------------------------------
void shutDown( void )
{
cgDestr