3D C/C++ tutorials -> OpenGL 1.5 -> Cube rendering, rotating and lighting
Use for personal or educational purposes only. Commercial and other profit uses strictly prohibited. Exploitation of content on a website or in a publication prohibited.
win32_opengl_window.h
#include <windows.h>
#include "string.h"
#include <gl/glew.h> // http://glew.sourceforge.net/
#include <gl/wglew.h>
// ----------------------------------------------------------------------------------------------------------------------------
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "glew32.lib")
// ----------------------------------------------------------------------------------------------------------------------------
extern CString ErrorLog;
// ----------------------------------------------------------------------------------------------------------------------------
class COpenGLRenderer
{
protected:
int Width, Height;
public:
COpenGLRenderer();
~COpenGLRenderer();
bool Init();
void Render(float FrameTime);
void Resize(int Width, int Height);
void Destroy();
};
// ----------------------------------------------------------------------------------------------------------------------------
class COpenGLView
{
protected:
char *Title;
int Width, Height;
HWND hWnd;
HGLRC hGLRC;
public:
COpenGLView();
~COpenGLView();
bool Init(HINSTANCE hInstance, char *Title, int Width, int Height);
void Show(bool Maximized = false);
void MessageLoop();
void Destroy();
void OnPaint();
void OnSize(int Width, int Height);
};
// ----------------------------------------------------------------------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
// ----------------------------------------------------------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR sCmdLine, int iShow);
win32_opengl_window.cpp
#include "win32_opengl_window.h"
// ----------------------------------------------------------------------------------------------------------------------------
COpenGLRenderer::COpenGLRenderer()
{
}
COpenGLRenderer::~COpenGLRenderer()
{
}
bool COpenGLRenderer::Init()
{
GLfloat LightModelAmbient[] = {0.0f, 0.0f, 0.0f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, LightModelAmbient);
GLfloat LightAmbient[] = {0.25f, 0.25f, 0.25f, 1.0f};
glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);
GLfloat LightDiffuse[] = {0.75f, 0.75f, 0.75f, 1.0f};
glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
GLfloat MaterialAmbient[] = {1.0f, 1.0f, 1.0f, 1.0f};
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, MaterialAmbient);
GLfloat MaterialDiffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialDiffuse);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
return true;
}
void COpenGLRenderer::Render(float FrameTime)
{
static float LightPosition[] = {0.0f, 0.0f, 2.5f, 1.0f}, a = 0.0f;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0f, 0.0f, 2.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);
glRotatef(a, 0.0f, 1.0f, 0.0f);
glRotatef(a, 1.0f, 0.0f, 0.0f);
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glNormal3f( 0.0f, 0.0f, 1.0f);
glVertex3f(-0.5f, -0.5f, 0.5f);
glVertex3f( 0.5f, -0.5f, 0.5f);
glVertex3f( 0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glNormal3f( 0.0f, 0.0f, -1.0f);
glVertex3f( 0.5f, -0.5f, -0.5f);
glVertex3f(-0.5f, -0.5f, -0.5f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glVertex3f( 0.5f, 0.5f, -0.5f);
glNormal3f( 1.0f, 0.0f, 0.0f);
glVertex3f( 0.5f, -0.5f, 0.5f);
glVertex3f( 0.5f, -0.5f, -0.5f);
glVertex3f( 0.5f, 0.5f, -0.5f);
glVertex3f( 0.5f, 0.5f, 0.5f);
glNormal3f(-1.0f, 0.0f, 0.0f);
glVertex3f(-0.5f, -0.5f, -0.5f);
glVertex3f(-0.5f, -0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glNormal3f( 0.0f, 1.0f, 0.0f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f( 0.5f, 0.5f, 0.5f);
glVertex3f( 0.5f, 0.5f, -0.5f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glNormal3f( 0.0f, -1.0f, 0.0f);
glVertex3f(-0.5f, -0.5f, -0.5f);
glVertex3f( 0.5f, -0.5f, -0.5f);
glVertex3f( 0.5f, -0.5f, 0.5f);
glVertex3f(-0.5f, -0.5f, 0.5f);
glEnd();
a += 22.5f * FrameTime;
}
void COpenGLRenderer::Resize(int Width, int Height)
{
this->Width = Width;
this->Height = Height;
glViewport(0, 0, Width, Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (float)Width / (Height > 0 ? (float)Height : 1.0f), 0.125f, 512.0f);
}
void COpenGLRenderer::Destroy()
{
}
// ----------------------------------------------------------------------------------------------------------------------------
COpenGLRenderer OpenGLRenderer;
// ----------------------------------------------------------------------------------------------------------------------------
CString ErrorLog;
// ----------------------------------------------------------------------------------------------------------------------------
COpenGLView::COpenGLView()
{
}
COpenGLView::~COpenGLView()
{
}
bool COpenGLView::Init(HINSTANCE hInstance, char *Title, int Width, int Height)
{
this->Title = Title;
this->Width = Width;
this->Height = Height;
WNDCLASSEX WndClassEx;
memset(&WndClassEx, 0, sizeof(WNDCLASSEX));
WndClassEx.cbSize = sizeof(WNDCLASSEX);
WndClassEx.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
WndClassEx.lpfnWndProc = WndProc;
WndClassEx.hInstance = hInstance;
WndClassEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClassEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
WndClassEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClassEx.lpszClassName = "Win32OpenGLWindow";
if(RegisterClassEx(&WndClassEx) == 0)
{
ErrorLog.Set("RegisterClassEx failed!");
return false;
}
DWORD Style = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
hWnd = CreateWindowEx(WS_EX_APPWINDOW, WndClassEx.lpszClassName, Title, Style, 0, 0, Width, Height, NULL, NULL, hInstance, NULL);
if(hWnd == NULL)
{
ErrorLog.Set("CreateWindowEx failed!");
return false;
}
HDC hDC = GetDC(hWnd);
if(hDC == NULL)
{
ErrorLog.Set("GetDC failed!");
return false;
}
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 = 32;
pfd.cDepthBits = 24;
pfd.iLayerType = PFD_MAIN_PLANE;
int PixelFormat = ChoosePixelFormat(hDC, &pfd);
if(PixelFormat == 0)
{
ErrorLog.Set("ChoosePixelFormat failed!");
return false;
}
if(SetPixelFormat(hDC, PixelFormat, &pfd) == FALSE)
{
ErrorLog.Set("SetPixelFormat failed!");
return false;
}
hGLRC = wglCreateContext(hDC);
if(hGLRC == NULL)
{
ErrorLog.Set("wglCreateContext failed!");
return false;
}
if(wglMakeCurrent(hDC, hGLRC) == FALSE)
{
ErrorLog.Set("wglMakeCurrent failed!");
return false;
}
if(glewInit() != GLEW_OK)
{
ErrorLog.Set("glewInit failed!");
return false;
}
if(WGLEW_EXT_swap_control)
{
wglSwapIntervalEXT(0);
}
return OpenGLRenderer.Init();
}
void COpenGLView::Show(bool Maximized)
{
RECT dRect, wRect, cRect;
GetWindowRect(GetDesktopWindow(), &dRect);
GetWindowRect(hWnd, &wRect);
GetClientRect(hWnd, &cRect);
wRect.right += Width - cRect.right;
wRect.bottom += Height - cRect.bottom;
wRect.right -= wRect.left;
wRect.bottom -= wRect.top;
wRect.left = dRect.right / 2 - wRect.right / 2;
wRect.top = dRect.bottom / 2 - wRect.bottom / 2;
MoveWindow(hWnd, wRect.left, wRect.top, wRect.right, wRect.bottom, FALSE);
ShowWindow(hWnd, Maximized ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL);
}
void COpenGLView::MessageLoop()
{
MSG Msg;
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
void COpenGLView::Destroy()
{
OpenGLRenderer.Destroy();
wglDeleteContext(hGLRC);
DestroyWindow(hWnd);
}
void COpenGLView::OnPaint()
{
static DWORD LastFPSTime = GetTickCount(), LastFrameTime = LastFPSTime, FPS = 0;
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hWnd, &ps);
DWORD Time = GetTickCount();
float FrameTime = (Time - LastFrameTime) * 0.001f;
LastFrameTime = Time;
if(Time - LastFPSTime > 1000)
{
CString Text = Title;
Text.Append(" - %dx%d", Width, Height);
Text.Append(", FPS: %d", FPS);
Text.Append(" - %s", (char*)glGetString(GL_RENDERER));
SetWindowText(hWnd, Text);
LastFPSTime = Time;
FPS = 0;
}
else
{
FPS++;
}
OpenGLRenderer.Render(FrameTime);
SwapBuffers(hDC);
EndPaint(hWnd, &ps);
InvalidateRect(hWnd, NULL, FALSE);
}
void COpenGLView::OnSize(int Width, int Height)
{
this->Width = Width;
this->Height = Height;
OpenGLRenderer.Resize(Width, Height);
}
// ----------------------------------------------------------------------------------------------------------------------------
COpenGLView OpenGLView;
// ----------------------------------------------------------------------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
switch(uiMsg)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_PAINT:
OpenGLView.OnPaint();
break;
case WM_SIZE:
OpenGLView.OnSize(LOWORD(lParam), HIWORD(lParam));
break;
default:
return DefWindowProc(hWnd, uiMsg, wParam, lParam);
}
return 0;
}
// ----------------------------------------------------------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR sCmdLine, int iShow)
{
char *AppName = "Cube rendering, rotating and lighting";
if(OpenGLView.Init(hInstance, AppName, 800, 600))
{
OpenGLView.Show();
OpenGLView.MessageLoop();
}
else
{
MessageBox(NULL, ErrorLog, AppName, MB_OK | MB_ICONERROR);
}
OpenGLView.Destroy();
return 0;
}
Download
|