Code:
#pragma once
#define _UNICODE
#define UNICODE
#define _USE_MATH_DEFINES
#define _WIN32_WINNT 0x500
#define WIN32_LEAN_AND_MEAN
#define WIN32_WINNT
#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <cstdio>
#include <cmath>
LRESULT CALLBACK WindowProcedure( HWND, UINT, WPARAM, LPARAM );
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, INT );
class CWindowClassEx
{
public:
CWindowClassEx
( LPCTSTR szClassName,
WNDPROC fnWindowProc,
UINT uiStyle = CS_HREDRAW | CS_VREDRAW,
HICON hIcon = ::LoadIcon( 0, IDI_APPLICATION ),
HCURSOR hCursor = ::LoadCursor( 0, IDC_ARROW ),
HBRUSH hbrBackground = (HBRUSH) ::GetStockObject( WHITE_BRUSH ),
int iClassExtra = 0,
int iWndExtra = 0,
LPCTSTR szMenuName = 0 );
~CWindowClassEx( void );
operator const WNDCLASSEX & ( void ) const;
LPCTSTR getClassName( void ) const;
HINSTANCE getHinstance( void ) const;
private:
WNDCLASSEX m_windowClass;
};
class CWindow
{
private:
CWindowClassEx m_windowClass;
HWND m_window;
DWORD m_style;
DWORD m_exStyle;
LPCTSTR m_windowName;
int m_width, m_height;
public:
CWindow
(
int width,
int height,
LPCTSTR className,
WNDPROC windowProc = 0,
LPCTSTR windowName = TEXT(""),
DWORD windowStyle = WS_OVERLAPPEDWINDOW,
DWORD windowExStyle = WS_EX_OVERLAPPEDWINDOW,
LPVOID createParams = 0,
UINT classStyle = CS_VREDRAW | CS_HREDRAW,
HICON icon = ::LoadIcon( 0, IDI_APPLICATION ),
HCURSOR cursor = ::LoadCursor( 0, IDC_ARROW )
);
virtual ~CWindow( void );
HWND getHwnd( void ) const;
const CWindowClassEx & getWindowClass( void ) const;
HDC getDC( void ) const;
int getWidth( void ) const;
int getHeight( void ) const;
bool isFullscreen( void ) const;
bool show( int showCommand );
virtual void resize( int width, int height );
};
class COGL : public CWindow
{
private:
HGLRC m_hRC;
HDC m_hDC;
HICON m_hIcon;
bool m_bFullscreen;
public:
explicit COGL( int width, int height, bool fullscreen );
virtual ~COGL( void );
bool showWindow( int nCmdShow );
bool isFullscreen( void ) const;
void swap( void ) const;
virtual void resize( int width, int height );
virtual void initialize( void );
virtual void kill( void );
};
class CGame
{
public:
CGame( int width, int height );
~CGame( void );
void draw( void ) const;
void update( double dt );
private:
int m_width, m_height;
int m_gameStateNum;
double m_rgb[3][800];
double m_rgbRates[3][800];
GLUquadricObj * m_x;
};
Main.cpp
Code:
#include "Main.h"
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, INT )
{
COGL * window = 0; // Our Open GL enabled window
CGame * game = 0; // Our pong game
LARGE_INTEGER
current, // Performance time
prevupdate, // Last update time
prevrender, // Last render time
frame, // F.P.S.
freq; // Performance frequency
MSG msg = { 0 };
window = new COGL( 1024, 768, true );
game = new CGame( 1024, 768 );
::QueryPerformanceFrequency( &freq );
::QueryPerformanceCounter( ¤t );
frame.QuadPart = freq.QuadPart / 30; // 40 FPS
prevrender = prevupdate = current; // We're in the now
while( msg.message != WM_QUIT )
{
if( ::PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )
{
::TranslateMessage( &msg );
::DispatchMessage( &msg );
}
::QueryPerformanceCounter( ¤t );
// If elapsed > frame rate - render and swap the buffers out
if( current.QuadPart - prevrender.QuadPart > frame.QuadPart )
{
game->draw();
prevrender = current;
window->swap();
}
//
// Otherwise, just do some updating.
// o Recieves deltatime, keyboard status
//
game->update
( double(current.QuadPart - prevupdate.QuadPart) /
double(freq.QuadPart) );
prevupdate = current;
}
delete window;
delete game;
return 0;
}
LRESULT CALLBACK WindowProcedure
( HWND hWindow, UINT uMessage,
WPARAM wParam, LPARAM lParam )
{
static COGL * fogl = 0;
switch( uMessage )
{
case WM_USER + 4337:
{
if( !lParam || !wParam )
return -1;
fogl = reinterpret_cast< COGL * >( lParam );
fogl->initialize();
fogl->show( SW_SHOW );
break;
}
case WM_SIZE:
{
if(fogl)
fogl->resize( LOWORD(lParam), HIWORD(lParam) );
break;
}
case WM_CLOSE:
{
::PostQuitMessage( 0 );
break;
}
case WM_DESTROY:
break;
default:
return ::DefWindowProc( hWindow, uMessage, wParam, lParam );
}
return 0;
}
CWindow::CWindow
(
int width,
int height,
LPCTSTR className,
WNDPROC windowProc /* = 0 */,
LPCTSTR windowName /* = TEXT("") */,
DWORD windowStyle /* = WS_OVERLAPPEDWINDOW */,
DWORD windowExStyle /* = WS_EX_OVERLAPPEDWINDOW */,
LPVOID createParams /* = 0 */,
UINT classStyle /* = CS_VREDRAW | CS_HREDRAW */,
HICON icon /* = ::LoadIcon( 0, IDI_APPLICATION ) */,
HCURSOR cursor /* = ::LoadCursor( 0, IDC_ARROW ) */
) :
m_window( 0 ),
m_windowClass( className, windowProc, classStyle, icon, cursor ),
m_windowName( windowName ),
m_width( width ),
m_height( height ),
m_style( windowStyle ),
m_exStyle( windowExStyle )
{
RECT wr = { 0 };
wr.left = 0;
wr.right = width;
wr.top = 0;
wr.bottom = height;
::AdjustWindowRectEx( &wr, m_style, false, m_exStyle );
m_window = ::CreateWindowEx( m_exStyle, m_windowClass.getClassName(),
m_windowName, m_style | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
CW_USEDEFAULT, CW_USEDEFAULT, wr.right - wr.left, wr.bottom - wr.top,
0, 0, ::GetModuleHandle( 0 ), createParams );
}
CWindow::~CWindow( void ) { ::DestroyWindow( m_window ); }
HWND CWindow::getHwnd( void ) const { return m_window; }
HDC CWindow::getDC( void ) const { return ::GetDC( m_window ); }
int CWindow::getWidth( void ) const { return m_width; }
int CWindow::getHeight( void ) const { return m_height; }
void CWindow::resize( int width, int height )
{
m_width = width;
m_height = height;
}
bool CWindow::show( int showCommand )
{
::SetForegroundWindow( m_window );
return ::ShowWindow( m_window, showCommand ) == TRUE;
}
CWindowClassEx::CWindowClassEx
(
LPCTSTR className,
WNDPROC windowProc,
UINT classStyle /* = CS_HREDRAW | CS_VREDRAW */,
HICON icon /* = ::LoadIcon( 0, IDI_APPLICATION ) */,
HCURSOR cursor /* = ::LoadCursor( 0, IDC_ARROW ) */,
HBRUSH background /* = (HBRUSH) ::GetStockObject( WHITE_BRUSH ) */,
int classExtra /* = 0 */,
int windowExtra /* = 0 */,
LPCTSTR menuName /* = 0 */
) :
m_windowClass()
{
m_windowClass.cbSize = sizeof(WNDCLASSEX);
m_windowClass.hInstance = ::GetModuleHandle( 0 );
m_windowClass.hIcon = icon;
m_windowClass.hIconSm = icon;
m_windowClass.hCursor = cursor;
m_windowClass.lpfnWndProc = windowProc;
m_windowClass.cbWndExtra = windowExtra;
m_windowClass.cbClsExtra = classExtra;
m_windowClass.style = classStyle;
m_windowClass.hbrBackground = background;
m_windowClass.lpszClassName = className;
m_windowClass.lpszMenuName = menuName;
::RegisterClassEx( &m_windowClass );
}
CWindowClassEx::~CWindowClassEx( void )
{
::UnregisterClass( m_windowClass.lpszClassName, m_windowClass.hInstance );
}
CWindowClassEx::operator const WNDCLASSEX & ( void ) const { return m_windowClass; }
LPCTSTR CWindowClassEx::getClassName( void ) const { return m_windowClass.lpszClassName; }
HINSTANCE CWindowClassEx::getHinstance( void ) const { return m_windowClass.hInstance; }
COGL::COGL( int width, int height, bool fullscreen )
:
CWindow
(
width,
height,
TEXT("GLTESTING"),
&WindowProcedure,
TEXT("GHETTO"),
fullscreen ? WS_POPUP | WS_MAXIMIZE : WS_OVERLAPPEDWINDOW,
WS_EX_APPWINDOW | (fullscreen ? 0 : WS_EX_WINDOWEDGE),
0,
CS_VREDRAW | CS_HREDRAW | (fullscreen ? CS_OWNDC : 0)
),
m_hRC( 0 ),
m_hDC( 0 ),
m_bFullscreen( fullscreen )
{
initialize();
show( SW_SHOW );
}
COGL::~COGL( void ) { kill(); }
void COGL::swap( void ) const { ::SwapBuffers( m_hDC ); }
void COGL::initialize( void )
{
PIXELFORMATDESCRIPTOR pfd = { 0 };
unsigned int pf = 0;
if( isFullscreen() )
{
DEVMODE dm = { 0 };
LONG ret = 0; DWORD i = 0;
dm.dmSize = sizeof(DEVMODE);
dm.dmDriverExtra = 0;
while( ::EnumDisplaySettings( 0, i, &dm ) )
{
if( dm.dmPelsHeight == DWORD(getHeight()) &&
dm.dmPelsWidth == DWORD(getWidth()) &&
dm.dmBitsPerPel == 32 )
{
ret = 1;
break;
}
i++;
}
if(ret)
{
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
ret = ::ChangeDisplaySettings( &dm, CDS_FULLSCREEN );
}
}
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 = 32;
pfd.cDepthBits = 24;
m_hDC = getDC();
pf = ::ChoosePixelFormat( m_hDC, &pfd );
::SetPixelFormat( m_hDC, pf, &pfd );
m_hRC = ::wglCreateContext( m_hDC );
::wglMakeCurrent( m_hDC, m_hRC );
resize( getWidth(), getHeight() );
}
void COGL::kill( void )
{
::ChangeDisplaySettings( 0, 0 );
::ReleaseDC( getHwnd(), m_hDC );
::wglMakeCurrent( 0, 0 );
::wglDeleteContext( m_hRC );
}
void COGL::resize( int width, int height )
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective
( 45, double(width) / double(height), 0.0f, 2000.0f );
glViewport( 0, 0, width, height );
glMatrixMode( GL_MODELVIEW );
CWindow::resize( width, height );
}
bool COGL::isFullscreen( void ) const { return m_bFullscreen; }
CGame::CGame( int width, int height )
:
m_width( width / 2 ),
m_height( height / 2 ),
m_x( gluNewQuadric() )
{
for( int i = 0; i < 800; ++i )
{
m_rgbRates[0][i] = 0.008;
m_rgbRates[1][i] = 0.01;
m_rgbRates[2][i] = 0.005;
m_rgb[0][i] = i / 4000.0 + 0.1;
m_rgb[1][i] = i / 4000.0 + 0.1;
m_rgb[2][i] = i / 4000.0 + 0.1;
}
}
CGame::~CGame( void )
{
gluDeleteQuadric( m_x );
}
void CGame::update( double dt )
{
for( int i = 0; i < 800; ++i )
{
for( int j = 0; j < 3; ++j )
{
if( m_rgb[j][i] >= 0.3 || m_rgb[j][i] <= 0.1 )
{
m_rgbRates[j][i] = -m_rgbRates[j][i];
}
m_rgb[j][i] += m_rgbRates[j][i];
}
}
}
void CGame::draw( void ) const
{
static double m = 0, rm = 10.0, k = 0, rk = 0.5;
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
gluLookAt( 0, 0, 800 - m, 0, 0, 0, 0, 1, 0 );
glRotatef( k, 1, 1, 1 );
k += rk;
m += rm;
if( abs(m) > 800 )
rm = -rm;
for( double i = 1.0; i < 800; i += 2.5 )
{
glColor3d(
m_rgb[0][ int(i) ],
m_rgb[1][ int(i) ],
m_rgb[2][ int(i) ] );
gluDisk( m_x, i, i+1, 1000, 2 );
}
}