Showing Wrong Language in window title and messagebox : win32 application, opengl - c++

I was trying to create a basic window with opengl and win32 application in visual studio 2013.
Everything works fine except the window title and messages in messagebox are not showing English. My code is given below:
#include "stdafx.h"
#include "ThesisProject.h"
#define MAX_LOADSTRING 100
// ================================= Variable Region : All the global variables will be declared here with categorization =========================== //
TCHAR szTitle[MAX_LOADSTRING];
TCHAR szWindowClass[MAX_LOADSTRING];
HDC hDC = NULL; // Private GDI Device Context. GDI : http://en.wikipedia.org/wiki/Graphics_Device_Interface
HWND hWnd = NULL; // holds our window handle.
HINSTANCE hInstance; // holds the instance of the application
HGLRC hRC = NULL; // Permanent Rendering Context
bool keys[256]; // Array Used for the keyboard routine. this will help us to track multiple key press, like : "Ctrl + s"
bool active = TRUE; // window active flag. set to true by default.
bool fullscreen = TRUE; // fullscreen flag. set to true by default. indicates whether the screen should be windowed or fullscreen.
// ================================================================================================================================================== //
// ================================ Function prototype declaration region : all the function prototype declaration will go here. ====================== //
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // a call back function to process window action.
int InitGL(GLvoid); // this function is used for setting up opengl components.
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag); // creates the window.
int DrawGLScene(GLvoid); // this is where all the drawing goes.
GLvoid ReSizeGLScene(GLsizei width, GLsizei height); // this function is used to handle the properties when the window is resized when full screen mode is not used.
GLvoid KillGLWindow(GLvoid); // this function is called before closing the window.
// =================================================================================================================================================== //
// this function is the entry point of this project . what ever this program does, it starts from here.
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
MSG msg; // Windows Message Structure
BOOL done = FALSE; // Bool Variable To Exit Loop
// Create Our OpenGL Window
if (!CreateGLWindow("OpenGL Testing", 640, 480, 16, fullscreen))
{
return 0; // Quit If Window Was Not Created
}
while (!done) // Loop That Runs Until done=TRUE
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) // Is There A Message Waiting?
{
if (msg.message == WM_QUIT) // Have We Received A Quit Message?
{
done = TRUE; // If So done=TRUE
}
else // If Not, Deal With Window Messages
{
TranslateMessage(&msg); // Translate The Message
DispatchMessage(&msg); // Dispatch The Message
}
}
else // If There Are No Messages
{
// Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene()
if (active) // Program Active?
{
if (keys[VK_ESCAPE]) // Was ESC Pressed?
{
done = TRUE; // ESC Signalled A Quit
}
else // Not Time To Quit, Update Screen
{
DrawGLScene(); // Draw The Scene
SwapBuffers(hDC); // Swap Buffers (Double Buffering)
}
}
if (keys[VK_F1]) // Is F1 Being Pressed?
{
keys[VK_F1] = FALSE; // If So Make Key FALSE
KillGLWindow(); // Kill Our Current Window
fullscreen = !fullscreen; // Toggle Fullscreen / Windowed Mode
// Recreate Our OpenGL Window
if (!CreateGLWindow("Aqib", 640, 480, 16, fullscreen))
{
return 0; // Quit If Window Was Not Created
}
}
}
}
// Shutdown
KillGLWindow(); // Kill The Window
return (msg.wParam); // Exit The Program
}
// this function is used to initialize all the opengl components.
int InitGL(GLvoid){
glShadeModel(GL_SMOOTH); // enabling smooth shader
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // black background
glClearDepth(1.0f); // depth buffer setup
glEnable(GL_DEPTH_TEST); // enable depth testing
glDepthFunc(GL_LEQUAL); // the type of depth test to do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // really nice perspective calculations
return TRUE; // initialization went ok
}
// this function creates and registers the window to the OS.
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag){
GLuint PixelFormat; // Holds The Results After Searching For A Match
WNDCLASS wc; // Windows Class Structure
DWORD dwExStyle; // Window Extended Style
DWORD dwStyle; // Window Style
RECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values
WindowRect.left = (long)0; // Set Left Value To 0
WindowRect.right = (long)width; // Set Right Value To Requested Width
WindowRect.top = (long)0; // Set Top Value To 0
WindowRect.bottom = (long)height; // Set Bottom Value To Requested Height
fullscreen = fullscreenflag; // Set The Global Fullscreen Flag
hInstance = GetModuleHandle(NULL); // Grab An Instance For Our Window
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Move, And Own DC For Window
wc.lpfnWndProc = (WNDPROC)WndProc; // WndProc Handles Messages
wc.cbClsExtra = 0; // No Extra Window Data
wc.cbWndExtra = 0; // No Extra Window Data
wc.hInstance = hInstance; // Set The Instance
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load The Default Icon
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load The Arrow Pointer
wc.hbrBackground = NULL; // No Background Required For GL
wc.lpszMenuName = NULL; // We Don't Want A Menu
wc.lpszClassName = (LPCWSTR)"OpenGLTesting"; // Set The Class Name
if (!RegisterClass(&wc)) // Attempt To Register The Window Class
{
MessageBox(NULL, (LPCWSTR)"Failed To Register The Window Class.", (LPCWSTR)"ERROR", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // Exit And Return FALSE
}
if (fullscreen){ // Attempt Fullscreen Mode?
DEVMODE dmScreenSettings; // Device Mode
memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared
dmScreenSettings.dmSize = sizeof(dmScreenSettings); // Size Of The Devmode Structure
dmScreenSettings.dmPelsWidth = width; // Selected Screen Width
dmScreenSettings.dmPelsHeight = height; // Selected Screen Height
dmScreenSettings.dmBitsPerPel = bits; // Selected Bits Per Pixel
dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
// Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL){
// If The Mode Fails, Offer Two Options. Quit Or Run In A Window.
fullscreen = FALSE;
}
}
if (fullscreen){ // Are We Still In Fullscreen Mode?
dwExStyle = WS_EX_APPWINDOW; // Window Extended Style
dwStyle = WS_POPUP; // Windows Style
ShowCursor(TRUE); // Hide Mouse Pointer
}
else{
dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style
dwStyle = WS_OVERLAPPEDWINDOW; // Windows Style
}
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requested Size
if (!(hWnd = CreateWindowEx(dwExStyle, // Extended Style For The Window
(LPCWSTR)"OpenGLTesting", // Class Name
(LPCWSTR)title, // Window Title
WS_CLIPSIBLINGS | // Required Window Style
WS_CLIPCHILDREN | // Required Window Style
dwStyle, // Selected Window Style
0, 0, // Window Position
WindowRect.right - WindowRect.left, // Calculate Adjusted Window Width
WindowRect.bottom - WindowRect.top, // Calculate Adjusted Window Height
NULL, // No Parent Window
NULL, // No Menu
hInstance, // Instance
NULL)))
{
KillGLWindow(); // Reset The Display
MessageBox(NULL, (LPCWSTR)"Window Creation Error.", (LPCWSTR)"ERROR", MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
static PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be
{
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
bits, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // No Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
16, // 16Bit Z-Buffer (Depth Buffer)
0, // No Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
if (!(hDC = GetDC(hWnd))) // Did We Get A Device Context?
{
KillGLWindow(); // Reset The Display
MessageBox(NULL, (LPCWSTR)"Can't Create A GL Device Context.", (LPCWSTR)"ERROR", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) // Did Windows Find A Matching Pixel Format?
{
KillGLWindow(); // Reset The Display
MessageBox(NULL, (LPCWSTR)"Can't Find A Suitable PixelFormat.", (LPCWSTR)"ERROR", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if (!SetPixelFormat(hDC, PixelFormat, &pfd)) // Are We Able To Set The Pixel Format?
{
KillGLWindow(); // Reset The Display
MessageBox(NULL, (LPCWSTR)"Can't Set The PixelFormat.", (LPCWSTR)"ERROR", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if (!(hRC = wglCreateContext(hDC))) // Are We Able To Get A Rendering Context?
{
KillGLWindow(); // Reset The Display
MessageBox(NULL, (LPCWSTR)"Can't Create A GL Rendering Context.", (LPCWSTR)"ERROR", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if (!wglMakeCurrent(hDC, hRC)) // Try To Activate The Rendering Context
{
KillGLWindow(); // Reset The Display
MessageBox(NULL, (LPCWSTR)"Can't Activate The GL Rendering Context.", (LPCWSTR)"ERROR", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
ShowWindow(hWnd, SW_SHOW); // Show The Window
SetForegroundWindow(hWnd); // Slightly Higher Priority
SetFocus(hWnd); // Sets Keyboard Focus To The Window
ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen
if (!InitGL()) // Initialize Our Newly Created GL Window
{
KillGLWindow(); // Reset The Display
MessageBox(NULL, (LPCWSTR)"Initialization Failed.", (LPCWSTR)"ERROR", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
return TRUE; // Success
}
// this function is used to draw objects in the scene.
int DrawGLScene(GLvoid){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The Current Modelview Matrix
glTranslatef(-1.5f, 0.0f, -6.0f); // Move into space 6 units and -1.5 to the left
glColor3f(0.0f, 0.0f, 1.0f);
glBegin(GL_TRIANGLES); // Begin drawing triagle
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 1.0f, 0.0f); // Top
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f); // Bottom Right
glEnd(); // Finished Drawing The Triangle
glTranslatef(3.0f, 0.0f, 0.0f); // Move Right 3 Units
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_QUADS); // Draw A Quad
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 0.0f); // Top Left
glColor3f(0.0f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 0.0f); // Top Right
glColor3f(1.0f, 0.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 0.0f); // Bottom Right
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left
glEnd(); // Done Drawing The Quad
return TRUE; // Everything Went OK
}
// this function resizes and reinitializes the property of the opengl window when window is resized.
GLvoid ReSizeGLScene(GLsizei width, GLsizei height){
if (height == 0){ // prevent a divide by zero
height = 1; // Making height equal one
}
glViewport(0, 0, width, height); // Resize the current viewport
glMatrixMode(GL_PROJECTION); // select the projection matrix
glLoadIdentity(); // reset the projection matrix
// Calculate theaspect ratio of the window
gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW); // select the model view matrix
glLoadIdentity(); // reset the modelview matrix
}
// this function is called before closing the application to properly close the window.
GLvoid KillGLWindow(GLvoid)
{
if (fullscreen)
{
ChangeDisplaySettings(NULL, 0); // If so Switch back to the Desktop.
ShowCursor(TRUE); // Show the mouse pointer.
}
if (hRC)
{
if (!wglMakeCurrent(NULL, NULL))
{
MessageBox(NULL, (LPCWSTR)"Release of DC and RC Failed", (LPCWSTR)"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
}
if (!wglDeleteContext(hRC)) // Are we able to delete the rendering context?
{
MessageBox(NULL, (LPCWSTR)"Release of Rendering Context Failed", (LPCWSTR)"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
}
hRC = NULL; // set rendering context to null.
}
if (hDC && !ReleaseDC(hWnd, hDC)) // Are We Able To Release The DC
{
MessageBox(NULL, (LPCWSTR)"Release Device Context Failed.", (LPCWSTR)"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
hDC = NULL; // Set DC To NULL
}
if (hWnd && !DestroyWindow(hWnd)) // Are We Able To Destroy The Window?
{
MessageBox(NULL, (LPCWSTR)"Could Not Release hWnd.", (LPCWSTR)"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
hWnd = NULL; // Set hWnd To NULL
}
if (!UnregisterClass((LPCWSTR)"OpenGL", hInstance)) // Are We Able To Unregister Class
{
MessageBox(NULL, (LPCWSTR)"Could Not Unregister Class.", (LPCWSTR)"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
hInstance = NULL; // Set hInstance To NULL
}
}
LRESULT CALLBACK WndProc(HWND hWnd, // Handle For This Window
UINT uMsg, // Message For This Window
WPARAM wParam, // Additional Message Information
LPARAM lParam) // Additional Message Information
{
switch (uMsg) // Check For Windows Messages
{
case WM_ACTIVATE: // Watch For Window Activate Message
{
if (!HIWORD(wParam)) // Check Minimization State
{
active = TRUE; // Program Is Active
}
else
{
active = FALSE; // Program Is No Longer Active
}
return 0; // Return To The Message Loop
}
case WM_SYSCOMMAND: // Intercept System Commands
{
switch (wParam) // Check System Calls
{
case SC_SCREENSAVE: // Screensaver Trying To Start?
case SC_MONITORPOWER: // Monitor Trying To Enter Powersave?
return 0; // Prevent From Happening
}
break; // Exit
}
case WM_CLOSE: // Did We Receive A Close Message?
{
PostQuitMessage(0); // Send A Quit Message
return 0; // Jump Back
}
case WM_KEYDOWN: // Is A Key Being Held Down?
{
keys[wParam] = TRUE; // If So, Mark It As TRUE
return 0; // Jump Back
}
case WM_KEYUP: // Has A Key Been Released?
{
keys[wParam] = FALSE; // If So, Mark It As FALSE
return 0; // Jump Back
}
case WM_SIZE: // Resize The OpenGL Window
{
ReSizeGLScene(LOWORD(lParam), HIWORD(lParam)); // LoWord=Width, HiWord=Height
return 0; // Jump Back
}
}
// Pass All Unhandled Messages To DefWindowProc
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

The problem you're most likely running into is, that the Windows APIs you use expect wide character strings, but the string literals you have in your source code are standard (narrow) characters. So for every 2 consecutive characters in your strings, Windows interprets it as a single wide character; which will very likely end up in some asian script if every two bytes of a wchar are nonzero.
Solution: Use the _TEXT(…) macro to surround your string literals, turning them into wide character strings.

Related

Should I use Direct3D or just Windows GDI for a fancy/high-perf Win32 app UI? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Looking for the right general approach for making a UI really snappy.
I'm thinking of developing a UI tool that might go beyond just some "in house" tool. It would involve elaborate and custom 2d elements and would need to support fast scrolling of a big virtual surface, which would likely entail redrawing tons of custom things really quickly.
I've done some GDI programming back when XP was new, and I ran into some perf issues with lots of full screen blitting (it was a slow computer anyway). I understand GDI has some degree of acceleration, but I have difficulty ascertaining what exactly I can expect to be accelerated here.
I've only used Direct3D in games. Is it reasonable to make D3D to power a windowed GUI application? Also, if I use D3D, do I have to do everything from scratch, or can I make some kind of GDI/D3D hybrid, for example, using Direct3D calls inside WM_PAINT or something, in order to leverage some Win32 stuff like menu bars or listboxes side-by-side with a panel full of D3D rendered stuff? Does anyone have an example of mixing D3D with Win32 gui junk? Or is this not really the right approach?
What do programs like AutoCad or 3ds Max or Photoshop, or other major Win32 applications with similarly elaborate UI's do?
If your GUI involves 3D manipulation of 3D scenes, Direct3D or OpenGL would probably be a win. If you are just trying to give your GUI a "non-boring" look where the controls are stylized and drawn with alpha blended bitmaps and so-on, then you're best sticking to the traditional windowing system (i.e. GDI) as the bottom-most rendering layer. However, the easiest way to achieve such a "look and feel" is to use a higher-level toolkit like wxWidgets or Qt in order to achieve the theming and customization that will make your GUI look "modern" and not like a boring corporate application.
Another option is to use XAML/WPF from a native application and use the tools that are available for creating XAML-based GUIs like Microsoft's Expression. I haven't explored that myself, but it should be feasible using the technique from this article in the March, 2013 issue of MSDN Magazine.
Simple C style D3D9 app code (display mesh).
////////////////////////////////////////////////////////////////
// Defines main Direct3D rendering funcions
#include <windows.h>
#include <mmsystem.h>
#include <d3d9.h>
#include "d3dx9.h"
#include "cube_prim.h"
#ifndef __D3D_RENDERER_H__
#define __D3D_RENDERER_H__
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#pragma comment(lib,"winmm.lib")
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)
LPDIRECT3D9 pDirect3D = NULL;
LPDIRECT3DDEVICE9 pDirect3DDevice = NULL;
LPDIRECT3DVERTEXBUFFER9 pDirect3DVertexBuffer = NULL;
LPDIRECT3DINDEXBUFFER9 pDirect3DIndexBuffer = NULL;
LPDIRECT3DTEXTURE9 pDirect3DTexture01 = NULL;
LPDIRECT3DTEXTURE9 pDirect3DTexture02 = NULL;
LPD3DXMESH pD3DXMesh = NULL;
D3DMATERIAL9* pDirect3DMaterial = NULL;
LPDIRECT3DTEXTURE9* pDirect3DTexture = NULL;
DWORD Subsets = 0;
FLOAT XRot = 0.0f;
FLOAT YRot = 0.0f;
HRESULT InitializeD3D(HWND hWnd)
{
D3DDISPLAYMODE dispMode;
D3DPRESENT_PARAMETERS parameters;
pDirect3D = Direct3DCreate9(D3D_SDK_VERSION);
if (pDirect3D == NULL)
return E_FAIL;
if (FAILED(pDirect3D->GetAdapterDisplayMode(
D3DADAPTER_DEFAULT,&dispMode)))
return E_FAIL;
ZeroMemory(&parameters,sizeof(D3DPRESENT_PARAMETERS));
parameters.Windowed = FALSE;
parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
parameters.BackBufferFormat = dispMode.Format;
parameters.BackBufferWidth = dispMode.Width;
parameters.BackBufferHeight = dispMode.Height;
parameters.BackBufferCount = 2;
parameters.EnableAutoDepthStencil = TRUE;
parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
if (FAILED(pDirect3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,hWnd,D3DCREATE_HARDWARE_VERTEXPROCESSING,
&parameters,&pDirect3DDevice)))
return E_FAIL;
pDirect3DDevice->SetRenderState(D3DRS_LIGHTING,TRUE);
pDirect3DDevice->SetRenderState(D3DRS_AMBIENT,RGB(180,180,180));
pDirect3DDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_CCW);
pDirect3DDevice->SetRenderState(D3DRS_ZENABLE,TRUE);
//pDirect3DDevice->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE,D3DMCS_COLOR2);
//pDirect3DDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE,D3DMCS_COLOR2);
pDirect3DDevice->SetRenderState(D3DRS_SPECULARENABLE,TRUE);
return S_OK;
}
HRESULT InitializeD3DBufferObject(void)
{
VOID* pVertices = NULL;
VOID* pIndicies = NULL;
if (pDirect3DDevice != NULL)
{
if (FAILED(pDirect3DDevice->CreateVertexBuffer(
sizeof(vertices),0,D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT,&pDirect3DVertexBuffer,NULL)))
return E_FAIL;
if (FAILED(pDirect3DVertexBuffer->Lock(0,
sizeof(vertices),(void**)&pVertices,NULL)))
return E_FAIL;
memcpy(pVertices,vertices,sizeof(vertices));
pDirect3DVertexBuffer->Unlock();
if (FAILED(pDirect3DDevice->CreateIndexBuffer(
sizeof(indices),0,D3DFMT_INDEX32,D3DPOOL_DEFAULT,
&pDirect3DIndexBuffer,NULL)))
return E_FAIL;
if (FAILED(pDirect3DIndexBuffer->Lock(0,
sizeof(indices),(void**)&pIndicies,NULL)))
return E_FAIL;
memcpy(pIndicies,indices,sizeof(indices));
pDirect3DIndexBuffer->Unlock();
if (FAILED(D3DXCreateTextureFromFile(pDirect3DDevice,
_T("wood.tga"),&pDirect3DTexture01)))
return E_FAIL;
if (FAILED(D3DXCreateTextureFromFile(pDirect3DDevice,
_T("stripes.tga"),&pDirect3DTexture02)))
return E_FAIL;
return S_OK;
}
else
return E_FAIL;
}
HRESULT InitialMesh(void)
{
LPD3DXBUFFER pMeshObj = NULL;
LPD3DXMATERIAL pMaterial = NULL;
char buffer[255];
if (pDirect3DDevice != NULL)
{
if (FAILED(D3DXLoadMeshFromX(_T("Dwarf\\Dwarf.x"),
D3DXMESH_SYSTEMMEM,
pDirect3DDevice,
NULL,
&pMeshObj,
NULL,
&Subsets,
&pD3DXMesh)))
return E_FAIL;
pMaterial = (D3DXMATERIAL*)pMeshObj->GetBufferPointer();
pDirect3DMaterial = new D3DMATERIAL9[Subsets];
pDirect3DTexture = new LPDIRECT3DTEXTURE9[Subsets];
for (INT i = 0; i < Subsets; i++)
{
pDirect3DMaterial[i] = pMaterial[i].MatD3D;
sprintf(buffer,"Dwarf\\");
strcat(buffer,pMaterial[i].pTextureFilename);
if (FAILED(D3DXCreateTextureFromFileA(
pDirect3DDevice,buffer,&pDirect3DTexture[i])))
return E_FAIL;
}
pMeshObj->Release();
return S_OK;
}
else
return E_FAIL;
}
VOID ChangeSize(INT cx,INT cy)
{
D3DXMATRIX projMatrix;
if (pDirect3DDevice != NULL)
{
if (cy == 0)
cy = 1;
FLOAT aspectRatio = static_cast<FLOAT>(cx) /
static_cast<FLOAT>(cy);
D3DXMatrixPerspectiveFovLH(&projMatrix,45.0f,
aspectRatio,1.0f,150.0f);
pDirect3DDevice->SetTransform(D3DTS_PROJECTION,&projMatrix);
}
}
VOID RotateScene(void)
{
if (GetAsyncKeyState(VK_ESCAPE))
exit(0);
if (GetAsyncKeyState(VK_UP))
XRot -= 0.1f;
if (GetAsyncKeyState(VK_DOWN))
XRot += 0.1f;
if (GetAsyncKeyState(VK_LEFT))
YRot -= 0.1f;
if (GetAsyncKeyState(VK_RIGHT))
YRot += 0.1f;
}
VOID RenderScene(void)
{
D3DXMATRIX worldMatrix;
D3DMATERIAL9 material;
D3DLIGHT9 light;
D3DCAPS9 caps;
D3DCOLORVALUE ambientLight = { 0.0f, 0.0f, 0.0f, 1.0f };
D3DCOLORVALUE diffuseLight = { 0.7f, 0.7f, 0.7f, 1.0f };
D3DCOLORVALUE specularLight = { 1.0f, 1.0f, 1.0f, 1.0f };
D3DCOLORVALUE materialColor = { 1.0f, 1.0f, 1.0f, 1.0f };
ZeroMemory(&material,sizeof(D3DMATERIAL9));
material.Ambient = materialColor;
material.Diffuse = materialColor;
material.Specular = specularLight;
material.Power = 20.0f;
ZeroMemory(&light,sizeof(D3DLIGHT9));
light.Ambient = ambientLight;
light.Diffuse = diffuseLight;
light.Specular = specularLight;
light.Range = 300.0f;
light.Position = D3DXVECTOR3(-30,150,-10);
light.Type = D3DLIGHT_POINT;
light.Attenuation0 = 1.0f;
if (pDirect3DDevice != NULL)
{
D3DXMatrixIdentity(&worldMatrix);
pDirect3DDevice->SetTransform(D3DTS_WORLD,&worldMatrix);
D3DXMatrixTranslation(&worldMatrix,0.0f,0.0f,4.0f);
pDirect3DDevice->MultiplyTransform(D3DTS_WORLD,&worldMatrix);
D3DXMatrixRotationX(&worldMatrix,XRot);
pDirect3DDevice->MultiplyTransform(D3DTS_WORLD,&worldMatrix);
D3DXMatrixRotationY(&worldMatrix,YRot);
pDirect3DDevice->MultiplyTransform(D3DTS_WORLD,&worldMatrix);
pDirect3DDevice->Clear(0,0,D3DCLEAR_TARGET |
D3DCLEAR_ZBUFFER,D3DCOLOR_ARGB(255,0,0,0),1.0f,0);
pDirect3DDevice->SetMaterial(&material);
pDirect3DDevice->SetLight(0,&light);
pDirect3DDevice->LightEnable(0,TRUE);
pDirect3DDevice->SetTexture(0,pDirect3DTexture01);
//pDirect3DDevice->SetTexture(1,pDirect3DTexture02);
pDirect3DDevice->SetTextureStageState(0,
D3DTSS_COLORARG1,D3DTA_TEXTURE);
pDirect3DDevice->SetTextureStageState(0,
D3DTSS_COLORARG2,D3DTA_DIFFUSE);
pDirect3DDevice->SetTextureStageState(0,
D3DTSS_COLOROP,D3DTOP_MODULATE);
pDirect3DDevice->SetTextureStageState(1,
D3DTSS_TEXCOORDINDEX,0);
pDirect3DDevice->SetTextureStageState(1,
D3DTSS_COLORARG1,D3DTA_TEXTURE);
pDirect3DDevice->SetTextureStageState(1,
D3DTSS_COLORARG1,D3DTA_TEXTURE);
pDirect3DDevice->SetTextureStageState(1,
D3DTSS_COLOROP,D3DTOP_MODULATE);
pDirect3DDevice->GetDeviceCaps(&caps);
pDirect3DDevice->SetSamplerState(0,D3DSAMP_MAXANISOTROPY,caps.MaxAnisotropy);
pDirect3DDevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_ANISOTROPIC);
pDirect3DDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_ANISOTROPIC);
pDirect3DDevice->SetSamplerState(0,D3DSAMP_MIPFILTER,D3DTEXF_ANISOTROPIC);
pDirect3DDevice->SetSamplerState(1,D3DSAMP_MAXANISOTROPY,caps.MaxAnisotropy);
pDirect3DDevice->SetSamplerState(1,D3DSAMP_MINFILTER,D3DTEXF_ANISOTROPIC);
pDirect3DDevice->SetSamplerState(1,D3DSAMP_MAGFILTER,D3DTEXF_ANISOTROPIC);
pDirect3DDevice->SetSamplerState(1,D3DSAMP_MIPFILTER,D3DTEXF_ANISOTROPIC);
pDirect3DDevice->BeginScene();
{
pDirect3DDevice->SetStreamSource(0,pDirect3DVertexBuffer,0,
sizeof(CUSTOMVERTEX));
pDirect3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
pDirect3DDevice->SetIndices(pDirect3DIndexBuffer);
/*pDirect3DDevice->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST,0,0,36,0,12);*/
for (int i = 0; i < Subsets; i++)
{
pDirect3DDevice->SetMaterial(&pDirect3DMaterial[i]);
pDirect3DDevice->SetTexture(0,pDirect3DTexture[i]);
pD3DXMesh->DrawSubset(i);
}
}
pDirect3DDevice->EndScene();
pDirect3DDevice->Present(NULL,NULL,NULL,NULL);
}
}
VOID ReleaseD3D(void)
{
if (pDirect3DTexture)
{
for (int i = 0; i < 0; i++)
pDirect3DTexture[i]->Release();
}
if (pDirect3DMaterial)
{
delete [] pDirect3DMaterial;
}
if (pD3DXMesh)
pD3DXMesh->Release();
if (pDirect3DTexture02)
pDirect3DTexture02->Release();
if (pDirect3DTexture01)
pDirect3DTexture01->Release();
if (pDirect3DIndexBuffer)
pDirect3DIndexBuffer->Release();
if (pDirect3DVertexBuffer)
pDirect3DVertexBuffer->Release();
if (pDirect3DDevice)
pDirect3DDevice->Release();
if (pDirect3D)
pDirect3D->Release();
}
#endif
App use simple Win32 framework with WinMain etc...
Sample code in MFC classes
#include "MainWnd.h"
#include "d3d_renderer.h"
CMainWnd::CMainWnd(void)
{
}
CMainWnd::~CMainWnd(void)
{
}
BEGIN_MESSAGE_MAP(CMainWnd, CWnd)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_SIZE()
ON_WM_TIMER()
ON_WM_PAINT()
END_MESSAGE_MAP()
// WM_CREATE
int CMainWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (FAILED(InitializeD3D(m_hWnd)))
exit(0);
if (FAILED(InitializeD3DBufferObject()))
exit(0);
if (FAILED(InitialMesh()))
exit(0);
SetTimer(33,1,NULL);
return 0;
}
// WM_DESTROY
void CMainWnd::OnDestroy()
{
CWnd::OnDestroy();
KillTimer(101);
ReleaseD3D();
}
// WM_SIZE
void CMainWnd::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
ChangeSize(cx,cy);
}
// WM_TIMER
void CMainWnd::OnTimer(UINT_PTR nIDEvent)
{
InvalidateRect(NULL,FALSE);
CWnd::OnTimer(nIDEvent);
}
// WM_PAINT
void CMainWnd::OnPaint()
{
RotateScene();
RenderScene();
ValidateRect(NULL);
}
so decide what you want to use (D3D is significaly faster than GDI)
you can also use OpenGL to draw accelerated graphics (little bit slower than D3D) with less code amount.
Displaying 3D text with OpenGL and pure Win32 UI
#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>
// Palette Handle
HPALETTE hPalette = NULL;
static LPCTSTR lpszAppName = "Text3D";
GLint nFontList;
// Light values and coordinates
GLfloat whiteLight[] = { 0.4f, 0.4f, 0.4f, 1.0f };
GLfloat diffuseLight[] = { 0.8f, 0.8f, 0.8f, 1.0f };
GLfloat specular[] = { 0.9f, 0.9f, 0.9f, 1.0f};
GLfloat lightPos[] = { -100.0f, 200.0f, 50.0f, 1.0f };
// Declaration for Window procedure
LRESULT CALLBACK WndProc( HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
// Set Pixel Format function - forward declaration
void SetDCPixelFormat(HDC hDC);
void ChangeSize(GLsizei w, GLsizei h)
{
GLfloat nRange = 100.0f;
GLfloat fAspect;
// Prevent a divide by zero
if(h == 0)
h = 1;
fAspect = (GLfloat)w/(GLfloat)h;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
// Reset coordinate system
glLoadIdentity();
// Setup perspective for viewing
gluPerspective(17.5f,fAspect,1,300);
// Viewing transformation
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(-1.8f, 0.0f, -15.0f);
glRotatef(-20.0f, 0.0f, 1.0f,0.0f);
glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
}
void RenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Blue 3D Text
glColor3ub(0, 0, 255);
glPushMatrix();
glListBase(nFontList);
glCallLists (6, GL_UNSIGNED_BYTE, "OpenGL");
glPopMatrix();
}
void SetupRC(HDC hDC)
{
// Setup the Font characteristics
HFONT hFont;
GLYPHMETRICSFLOAT agmf[128]; // Throw away
LOGFONT logfont;
logfont.lfHeight = -10;
logfont.lfWidth = 0;
logfont.lfEscapement = 0;
logfont.lfOrientation = 0;
logfont.lfWeight = FW_BOLD;
logfont.lfItalic = FALSE;
logfont.lfUnderline = FALSE;
logfont.lfStrikeOut = FALSE;
logfont.lfCharSet = ANSI_CHARSET;
logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
logfont.lfQuality = DEFAULT_QUALITY;
logfont.lfPitchAndFamily = DEFAULT_PITCH;
strcpy(logfont.lfFaceName,"Arial");
// Create the font and display list
hFont = CreateFontIndirect(&logfont);
SelectObject (hDC, hFont);
//create display lists for glyphs 0 through 128 with 0.1 extrusion
// and default deviation.
nFontList = glGenLists(128);
wglUseFontOutlines(hDC, 0, 128, nFontList, 0.0f, 0.5f,
WGL_FONT_POLYGONS, agmf);
DeleteObject(hFont);
glEnable(GL_DEPTH_TEST); // Hidden surface removal
glEnable(GL_COLOR_MATERIAL);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0,GL_AMBIENT,whiteLight);
glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);
glLightfv(GL_LIGHT0,GL_SPECULAR,specular);
glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
glEnable(GL_LIGHT0);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glMaterialfv(GL_FRONT, GL_SPECULAR,specular);
glMateriali(GL_FRONT,GL_SHININESS,128);
}
// If necessary, creates a 3-3-2 palette for the device context listed.
HPALETTE GetOpenGLPalette(HDC hDC)
{
HPALETTE hRetPal = NULL; // Handle to palette to be created
PIXELFORMATDESCRIPTOR pfd; // Pixel Format Descriptor
LOGPALETTE *pPal; // Pointer to memory for logical palette
int nPixelFormat; // Pixel format index
int nColors; // Number of entries in palette
int i; // Counting variable
BYTE RedRange,GreenRange,BlueRange;
// Range for each color entry (7,7,and 3)
// Get the pixel format index and retrieve the pixel format description
nPixelFormat = GetPixelFormat(hDC);
DescribePixelFormat(hDC, nPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
// Does this pixel format require a palette? If not, do not create a
// palette and just return NULL
if(!(pfd.dwFlags & PFD_NEED_PALETTE))
return NULL;
// Number of entries in palette. 8 bits yeilds 256 entries
nColors = 1 << pfd.cColorBits;
// Allocate space for a logical palette structure plus all the palette entries
pPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +nColors*sizeof(PALETTEENTRY));
// Fill in palette header
pPal->palVersion = 0x300; // Windows 3.0
pPal->palNumEntries = nColors; // table size
// Build mask of all 1's. This creates a number represented by having
// the low order x bits set, where x = pfd.cRedBits, pfd.cGreenBits, and
// pfd.cBlueBits.
RedRange = (1 << pfd.cRedBits) -1;
GreenRange = (1 << pfd.cGreenBits) - 1;
BlueRange = (1 << pfd.cBlueBits) -1;
// Loop through all the palette entries
for(i = 0; i < nColors; i++)
{
// Fill in the 8-bit equivalents for each component
pPal->palPalEntry[i].peRed = (i >> pfd.cRedShift) & RedRange;
pPal->palPalEntry[i].peRed = (unsigned char)(
(double) pPal->palPalEntry[i].peRed * 255.0 / RedRange);
pPal->palPalEntry[i].peGreen = (i >> pfd.cGreenShift) & GreenRange;
pPal->palPalEntry[i].peGreen = (unsigned char)(
(double)pPal->palPalEntry[i].peGreen * 255.0 / GreenRange);
pPal->palPalEntry[i].peBlue = (i >> pfd.cBlueShift) & BlueRange;
pPal->palPalEntry[i].peBlue = (unsigned char)(
(double)pPal->palPalEntry[i].peBlue * 255.0 / BlueRange);
pPal->palPalEntry[i].peFlags = (unsigned char) NULL;
}
// Create the palette
hRetPal = CreatePalette(pPal);
// Go ahead and select and realize the palette for this device context
SelectPalette(hDC,hRetPal,FALSE);
RealizePalette(hDC);
// Free the memory used for the logical palette structure
free(pPal);
// Return the handle to the new palette
return hRetPal;
}
// Select the pixel format for a given device context
void SetDCPixelFormat(HDC hDC)
{
int nPixelFormat;
static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // Size of this structure
1, // Version of this structure
PFD_DRAW_TO_WINDOW | // Draw to Window (not to bitmap)
PFD_SUPPORT_OPENGL | // Support OpenGL calls in window
PFD_DOUBLEBUFFER, // Double buffered mode
PFD_TYPE_RGBA, // RGBA Color mode
32, // Want 32 bit color
0,0,0,0,0,0, // Not used to select mode
0,0, // Not used to select mode
0,0,0,0,0, // Not used to select mode
16, // Size of depth buffer
0, // Not used to select mode
0, // Not used to select mode
0, // Draw in main plane
0, // Not used to select mode
0,0,0 }; // Not used to select mode
// Choose a pixel format that best matches that described in pfd
nPixelFormat = ChoosePixelFormat(hDC, &pfd);
// Set the pixel format for the device context
SetPixelFormat(hDC, nPixelFormat, &pfd);
}
// Entry point of all Windows programs
int APIENTRY WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg; // Windows message structure
WNDCLASS wc; // Windows class structure
HWND hWnd; // Storeage for window handle
// Register Window style
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
// No need for background brush for OpenGL window
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = lpszAppName;
// Register the window class
if(RegisterClass(&wc) == 0)
return FALSE;
// Create the main application window
hWnd = CreateWindow(
lpszAppName,
lpszAppName,
// OpenGL requires WS_CLIPCHILDREN and WS_CLIPSIBLINGS
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
// Window position and size
100, 100,
250, 250,
NULL,
NULL,
hInstance,
NULL);
// If window was not created, quit
if(hWnd == NULL)
return FALSE;
// Display the window
ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);
// Process application messages until the application closes
while( GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
// Window procedure, handles all messages for this program
LRESULT CALLBACK WndProc( HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
static HGLRC hRC; // Permenant Rendering context
static HDC hDC; // Private GDI Device context
switch (message)
{
// Window creation, setup for OpenGL
case WM_CREATE:
// Store the device context
hDC = GetDC(hWnd);
// Select the pixel format
SetDCPixelFormat(hDC);
// Create the rendering context and make it current
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
// Create the palette
hPalette = GetOpenGLPalette(hDC);
SetupRC(hDC);
break;
// Window is being destroyed, cleanup
case WM_DESTROY:
// Kill the timer that we created
KillTimer(hWnd,101);
glDeleteLists(nFontList, 128);
// Deselect the current rendering context and delete it
wglMakeCurrent(hDC,NULL);
wglDeleteContext(hRC);
// Delete the palette
if(hPalette != NULL)
DeleteObject(hPalette);
// Tell the application to terminate after the window
// is gone.
PostQuitMessage(0);
break;
// Window is resized.
case WM_SIZE:
// Call our function which modifies the clipping
// volume and viewport
ChangeSize(LOWORD(lParam), HIWORD(lParam));
break;
// The painting function. This message sent by Windows
// whenever the screen needs updating.
case WM_PAINT:
{
// Call OpenGL drawing code
RenderScene();
// Call function to swap the buffers
SwapBuffers(hDC);
ValidateRect(hWnd,NULL);
}
break;
// Windows is telling the application that it may modify
// the system palette. This message in essance asks the
// application for a new palette.
case WM_QUERYNEWPALETTE:
// If the palette was created.
if(hPalette)
{
int nRet;
// Selects the palette into the current device context
SelectPalette(hDC, hPalette, FALSE);
// Map entries from the currently selected palette to
// the system palette. The return value is the number
// of palette entries modified.
nRet = RealizePalette(hDC);
// Repaint, forces remap of palette in current window
InvalidateRect(hWnd,NULL,FALSE);
return nRet;
}
break;
// This window may set the palette, even though it is not the
// currently active window.
case WM_PALETTECHANGED:
// Don't do anything if the palette does not exist, or if
// this is the window that changed the palette.
if((hPalette != NULL) && ((HWND)wParam != hWnd))
{
// Select the palette into the device context
SelectPalette(hDC,hPalette,FALSE);
// Map entries to system palette
RealizePalette(hDC);
// Remap the current colors to the newly realized palette
UpdateColors(hDC);
return 0;
}
break;
default: // Passes it on if unproccessed
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0L);
}
can work without reseting palette
AS window handle you may use every legal window handles (panel, listbox, buttons etc...) so you can display 3d content almost everywhere
Photoshop use OpenGL, 3DS Max optional (OpenGL, Direct3D), AutoCad it is hard to say: GDI older versions, newest using .NET too.

OpenGL - restricting Arcball rotation

I have a simple red rectangle rendered in a window, and I created an arcball in order to rotate it in any direction. I was following the code from NeHe's Arcball Rotation tutorial.
The problem is that once the rectangle is rendered and the left mouse button is clicked, it spins like a top in the window. The mouse click-drag-stop update happens every time the mouse is moved, which is the reason why it spins that way. I am not able to figure out a way to restrict the rotation only for the duration of the click-drag-stop. How do I restrict the rotation? I have been trying to debug this for about 4-5 days now with no luck.
I added the original Arcball.h and Arcball.cpp files to my project, with one change to to the header file; I simply created a default constructor for the Arcball_t class with this line -
ArcBall_t() {};
The only other changes from the original project are that I threw the Update() function call into my code:
// ==========================================================================================
// function declarations
#define GET_PROC_ADDRESS( str ) wglGetProcAddress( str )
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void DrawOpenGLScene(HDC hDC);
void Update();
HGLRC SetUpOpenGLContext(HWND hWnd);
// ==========================================================================================
// Trackball declarations
const float PI2 = 2.0*3.1415926535f; // PI Squared
GLUquadricObj *quadratic;
Point2fT MousePt; // NEW: Current Mouse Point
bool isClicked = false; // NEW: Clicking The Mouse?
bool isRClicked = false; // NEW: Clicking The Right Mouse Button?
bool isDragging = false; // NEW: Dragging The Mouse?
Matrix4fT Transform = { 1.0f, 0.0f, 0.0f, 0.0f, // NEW: Final Transform
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f };
Matrix3fT LastRot = { 1.0f, 0.0f, 0.0f, // NEW: Last Rotation
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f };
Matrix3fT ThisRot = { 1.0f, 0.0f, 0.0f, // NEW: This Rotation
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f };
// ==========================================================================================
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
static char szClassName[] = "Myclass";
static char szTitle[]="A Simple Win32 API OpenGL Program";
WNDCLASS wc;
MSG msg;
HWND hWnd;
wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject (BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = szClassName;
if (!RegisterClass (&wc))
return 0;
hWnd = CreateWindow(szClassName, szTitle,
WS_OVERLAPPEDWINDOW |
// NEED THESE for OpenGL calls to work!
WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
0, 0, 1024, 256,
NULL, NULL, hInstance, NULL);
ArcBall_t ArcBall(1024.0f, 256.0f); // NEW: ArcBall Instance
ShowWindow(hWnd, nCmdShow);
UpdateWindow( hWnd );
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
return(msg.wParam);
}
// ==========================================================================================
//*******************************************************
// This is the brain of the loop
// Checks for a new key press or mouse movement
// renders when something is detected
//*******************************************************
LRESULT CALLBACK WndProc( HWND hWnd, UINT msg,
WPARAM wParam, LPARAM lParam )
{
HDC hDC;
static HGLRC hRC; // Note this is STATIC!
PAINTSTRUCT ps;
switch (msg)
{
case WM_CREATE:
// Select a pixel format and create a rendering context
hRC = SetUpOpenGLContext(hWnd);
break;
case WM_PAINT:
// Draw the scene
// Get a DC, make RC current & associate it with this DC
hDC = BeginPaint(hWnd, &ps);
wglMakeCurrent(hDC, hRC);
DrawOpenGLScene(hDC); // Draw
// We're done with the RC, so deselect it
wglMakeCurrent(NULL, NULL);
EndPaint(hWnd, &ps);
break;
//*NEW* Mouse based messages for arcball
case WM_LBUTTONUP:
isClicked = false;
break;
case WM_RBUTTONUP:
isRClicked = false;
break;
case WM_LBUTTONDOWN:
isClicked = true;
break;
case WM_RBUTTONDOWN:
isRClicked = true;
break;
case WM_MOUSEMOVE:
MousePt.s.X = (GLfloat)LOWORD(lParam);
MousePt.s.Y = (GLfloat)HIWORD(lParam);
isClicked = (LOWORD(wParam) & MK_LBUTTON) ? true : false;
isRClicked = (LOWORD(wParam) & MK_RBUTTON) ? true : false;
Update();
RedrawWindow(hWnd, NULL, NULL, RDW_INTERNALPAINT);
break;
case WM_DESTROY:
// Clean up and terminate
wglDeleteContext(hRC);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
return (0);
}
// ==========================================================================================
//*******************************************************
// SetUpOpenGL sets the pixel format and a rendering
// context then returns the RC
//*******************************************************
HGLRC SetUpOpenGLContext(HWND hWnd)
{
static PIXELFORMATDESCRIPTOR pfd = {
sizeof (PIXELFORMATDESCRIPTOR), // strcut size
1, // Version number
PFD_DRAW_TO_WINDOW | // Flags, draw to a window,
PFD_SUPPORT_OPENGL | // use OpenGL
PFD_DOUBLEBUFFER, // Use a double buffer
PFD_TYPE_RGBA, // RGBA pixel values
32, // 24-bit color
0, 0, 0, // RGB bits & shift sizes.
0, 0, 0, // Don't care about them
0, 0, // No alpha buffer info
0, 0, 0, 0, 0, // No accumulation buffer
32, // 32-bit depth buffer
8, // No stencil buffer
0, // No auxiliary buffers
PFD_MAIN_PLANE, // Layer type
0, // Reserved (must be 0)
0, // No layer mask
0, // No visible mask
0 // No damage mask
};
int nMyPixelFormatID;
HDC hDC;
HGLRC hRC;
hDC = GetDC(hWnd);
nMyPixelFormatID = ChoosePixelFormat(hDC, &pfd);
SetPixelFormat(hDC, nMyPixelFormatID, &pfd);
hRC = wglCreateContext(hDC);
ReleaseDC(hWnd, hDC);
quadratic=gluNewQuadric(); // Create A Pointer To The Quadric Object
gluQuadricNormals(quadratic, GLU_SMOOTH); // Create Smooth Normals
gluQuadricTexture(quadratic, GL_TRUE); // Create Texture Coords
return hRC;
}
// ==========================================================================================
// simple test code - rectangle/triangle
void DrawOpenGLScene(HDC hDC)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode( GL_MODELVIEW );
glTranslatef(0.0f, 0.0f, 0.0f);
glColor3f(1.0, 0.0, 0.0); // drawing color
glBegin(GL_POLYGON); // define the rectangle
glVertex2f(-0.5,-0.5);
glVertex2f(-0.5,0.5);
glVertex2f(0.5,0.5);
glVertex2f(0.5,-0.5);
glEnd();
glMultMatrixf(Transform.M);
glFlush(); // force execution
SwapBuffers(hDC);
}
// ==========================================================================================
void Update () // Perform Motion Updates Here
{
ArcBall_t ArcBall;
if (isRClicked) // If Right Mouse Clicked, Reset All Rotations
{
Matrix3fSetIdentity(&LastRot); // Reset Rotation
Matrix3fSetIdentity(&ThisRot); // Reset Rotation
Matrix4fSetRotationFromMatrix3f(&Transform, &ThisRot); // Reset Rotation
}
if (!isDragging) // Not Dragging
{
if (isClicked) // First Click
{
isDragging = true; // Prepare For Dragging
LastRot = ThisRot; // Set Last Static Rotation To Last Dynamic One
ArcBall.click(&MousePt); // Update Start Vector And Prepare For Dragging
}
}
else
{
if (isClicked) // Still Clicked, So Still Dragging
{
Quat4fT ThisQuat;
ArcBall.drag(&MousePt, &ThisQuat); // Update End Vector And Get Rotation As Quaternion
Matrix3fSetRotationFromQuat4f(&ThisRot, &ThisQuat); // Convert Quaternion Into Matrix3fT
Matrix3fMulMatrix3f(&ThisRot, &LastRot); // Accumulate Last Rotation Into This One
Matrix4fSetRotationFromMatrix3f(&Transform, &ThisRot); // Set Our Final Transform's Rotation From This One
}
else // No Longer Dragging
isDragging = false;
}
}
EDIT: I fixed the issue with the uncontrollable scene rotation by inserting a check within the case WM_MOUSEMOVE: handler of the WndProc() routine. The check was: if(isClicked == true) { //code }, and that seemed to do the trick. It no longer spins like a top. However, I still do not have fine control over the rotation; it still spins like a top within the click-drag-release duration.
Assuming your arcball.drag and arcball.click functions are correct, the only problem with your code is that you are applying the rotation after you draw and your need to do it before.
Your Code:
glTranslatef(0.0f, 0.0f, 0.0f);
glColor3f(1.0, 0.0, 0.0); // drawing color
glBegin(GL_POLYGON); // define the rectangle
glVertex2f(-0.5,-0.5);
glVertex2f(-0.5,0.5);
glVertex2f(0.5,0.5);
glVertex2f(0.5,-0.5);
glEnd();
glMultMatrixf(Transform.M);
Try changing it to:
glTranslatef(0.0f, 0.0f, 0.0f);
glMultMatrixf(Transform.M);
glColor3f(1.0, 0.0, 0.0); // drawing color
glBegin(GL_POLYGON); // define the rectangle
glVertex2f(-0.5,-0.5);
glVertex2f(-0.5,0.5);
glVertex2f(0.5,0.5);
glVertex2f(0.5,-0.5);
glEnd();
Although, based on the code you have provided, I dont think your image should rotate at all BECAUSE you are applying the rotation after. I think more code might be needed to find your issue.

OpenGL Quad not drawing

I am using visual c++ 2012 and opengl and I can't get my quad to draw, I haven't been getting any errors. Is it because I don't have an update method? Here is my code:
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <gl/GL.h>
HWND hwnd;
int clientWidth = 800;
int clientHeight = 600;
bool InitMainWindow(HINSTANCE hInstance);
LRESULT CALLBACK MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
if(!InitMainWindow(hInstance))
{
return 1;
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 800, 0, 600, 1, -1);
glMatrixMode(GL_MODELVIEW);
MSG msg = {0};
while(WM_QUIT != msg.message)
{
if(PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(0.5f,0.5f,1.0f);
glPushMatrix();
glTranslatef(0,0,-20.0f);
glBegin(GL_QUADS);
glVertex3f(-10.0f, -10.0f, 5.0f);
glVertex3f(-10.0f, 10.0f, 5.0f);
glVertex3f(10.0f, 10.0f, 5.0f);
glVertex3f(10.0f, -10.0f, 5.0f);
glEnd();
glPopMatrix();
}
}
return static_cast<int>(msg.wParam);
}
bool InitMainWindow(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
ZeroMemory(&wcex, sizeof(WNDCLASSEX));
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.hInstance = hInstance;
wcex.lpfnWndProc = MsgProc;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wcex.lpszClassName = "Project2DClass";
wcex.lpszMenuName = NULL;
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wcex))
{
MessageBox(NULL, "Failed to register window class", NULL, NULL);
return false;
}
RECT r = { 0, 0, clientWidth, clientHeight };
DWORD style = WS_OVERLAPPEDWINDOW;
AdjustWindowRect(&r, style, false);
int width = r.right - r.left;
int height = r.bottom - r.top;
int x = GetSystemMetrics(SM_CXSCREEN)/2 - width/2;
int y = GetSystemMetrics(SM_CYSCREEN)/2 - height/2;
hwnd = CreateWindow("Project2DClass", "Project 2D", style, x, y, width, height, NULL, NULL, hInstance, NULL);
if(!hwnd)
{
MessageBox(NULL, "Failed to create window", NULL, NULL);
return false;
}
ShowWindow(hwnd, SW_SHOW);
return true;
}
LRESULT CALLBACK MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
How can I fix this and what have I done wrong?
Also how do I create an update and sync method?
I fixed it!!!
Here is my code:
/*
* This Code Was Created By Jeff Molofee 2000
* A HUGE Thanks To Fredric Echols For Cleaning Up
* And Optimizing This Code, Making It More Flexible!
* If You've Found This Code Useful, Please Let Me Know.
* Visit My Site At nehe.gamedev.net
*/
#include <windows.h> // Header File For Windows
#include <gl\gl.h> // Header File For The OpenGL32 Library
#include <gl\glu.h> // Header File For The GLu32 Library
HDC hDC=NULL; // Private GDI Device Context
HGLRC hRC=NULL; // Permanent Rendering Context
HWND hWnd=NULL; // Holds Our Window Handle
HINSTANCE hInstance; // Holds The Instance Of The Application
bool keys[256]; // Array Used For The Keyboard Routine
bool active=TRUE; // Window Active Flag Set To TRUE By Default
bool fullscreen=TRUE; // Fullscreen Flag Set To Fullscreen Mode By Default
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc
GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window
{
if (height==0) // Prevent A Divide By Zero By
{
height=1; // Making Height Equal One
}
glViewport(0,0,width,height); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
}
int InitGL(GLvoid) // All Setup For OpenGL Goes Here
{
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
return TRUE; // Initialization Went OK
}
int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity(); // Reset The Current Modelview Matrix
//glClearColor(0.5f, 0.5f, 0, 0);
glColor3f(0.5f,0.5f,0);
glPushMatrix();
glTranslatef(0,0,-20.0f);
glBegin(GL_QUADS);
glVertex3f(-5.0f, -5.0f, 2.5f);
glVertex3f(-5.0f, 5.0f, 2.5f);
glVertex3f(5.0f, 5.0f, 2.5f);
glVertex3f(5.0f, -5.0f, 2.5f);
glEnd();
glPopMatrix();
return TRUE; // Everything Went OK
}
GLvoid KillGLWindow(GLvoid) // Properly Kill The Window
{
if (fullscreen) // Are We In Fullscreen Mode?
{
ChangeDisplaySettings(NULL,0); // If So Switch Back To The Desktop
ShowCursor(TRUE); // Show Mouse Pointer
}
if (hRC) // Do We Have A Rendering Context?
{
if (!wglMakeCurrent(NULL,NULL)) // Are We Able To Release The DC And RC Contexts?
{
MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC?
{
MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
hRC=NULL; // Set RC To NULL
}
if (hDC && !ReleaseDC(hWnd,hDC)) // Are We Able To Release The DC
{
MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hDC=NULL; // Set DC To NULL
}
if (hWnd && !DestroyWindow(hWnd)) // Are We Able To Destroy The Window?
{
MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hWnd=NULL; // Set hWnd To NULL
}
if (!UnregisterClass("OpenGL",hInstance)) // Are We Able To Unregister Class
{
MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hInstance=NULL; // Set hInstance To NULL
}
}
/* This Code Creates Our OpenGL Window. Parameters Are: *
* title - Title To Appear At The Top Of The Window *
* width - Width Of The GL Window Or Fullscreen Mode *
* height - Height Of The GL Window Or Fullscreen Mode *
* bits - Number Of Bits To Use For Color (8/16/24/32) *
* fullscreenflag - Use Fullscreen Mode (TRUE) Or Windowed Mode (FALSE) */
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
GLuint PixelFormat; // Holds The Results After Searching For A Match
WNDCLASS wc; // Windows Class Structure
DWORD dwExStyle; // Window Extended Style
DWORD dwStyle; // Window Style
RECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values
WindowRect.left=(long)0; // Set Left Value To 0
WindowRect.right=(long)width; // Set Right Value To Requested Width
WindowRect.top=(long)0; // Set Top Value To 0
WindowRect.bottom=(long)height; // Set Bottom Value To Requested Height
fullscreen=fullscreenflag; // Set The Global Fullscreen Flag
hInstance = GetModuleHandle(NULL); // Grab An Instance For Our Window
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Size, And Own DC For Window.
wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc Handles Messages
wc.cbClsExtra = 0; // No Extra Window Data
wc.cbWndExtra = 0; // No Extra Window Data
wc.hInstance = hInstance; // Set The Instance
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load The Default Icon
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load The Arrow Pointer
wc.hbrBackground = NULL; // No Background Required For GL
wc.lpszMenuName = NULL; // We Don't Want A Menu
wc.lpszClassName = "OpenGL"; // Set The Class Name
if (!RegisterClass(&wc)) // Attempt To Register The Window Class
{
MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if (fullscreen) // Attempt Fullscreen Mode?
{
DEVMODE dmScreenSettings; // Device Mode
memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared
dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Size Of The Devmode Structure
dmScreenSettings.dmPelsWidth = width; // Selected Screen Width
dmScreenSettings.dmPelsHeight = height; // Selected Screen Height
dmScreenSettings.dmBitsPerPel = bits; // Selected Bits Per Pixel
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
// Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
{
// If The Mode Fails, Offer Two Options. Quit Or Use Windowed Mode.
if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
{
fullscreen=FALSE; // Windowed Mode Selected. Fullscreen = FALSE
}
else
{
// Pop Up A Message Box Letting User Know The Program Is Closing.
MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP);
return FALSE; // Return FALSE
}
}
}
if (fullscreen) // Are We Still In Fullscreen Mode?
{
dwExStyle=WS_EX_APPWINDOW; // Window Extended Style
dwStyle=WS_POPUP; // Windows Style
ShowCursor(FALSE); // Hide Mouse Pointer
}
else
{
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style
dwStyle=WS_OVERLAPPEDWINDOW; // Windows Style
}
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requested Size
// Create The Window
if (!(hWnd=CreateWindowEx( dwExStyle, // Extended Style For The Window
"OpenGL", // Class Name
title, // Window Title
dwStyle | // Defined Window Style
WS_CLIPSIBLINGS | // Required Window Style
WS_CLIPCHILDREN, // Required Window Style
0, 0, // Window Position
WindowRect.right-WindowRect.left, // Calculate Window Width
WindowRect.bottom-WindowRect.top, // Calculate Window Height
NULL, // No Parent Window
NULL, // No Menu
hInstance, // Instance
NULL))) // Dont Pass Anything To WM_CREATE
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be
{
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
bits, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // No Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
16, // 16Bit Z-Buffer (Depth Buffer)
0, // No Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
if (!(hDC=GetDC(hWnd))) // Did We Get A Device Context?
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) // Did Windows Find A Matching Pixel Format?
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if(!SetPixelFormat(hDC,PixelFormat,&pfd)) // Are We Able To Set The Pixel Format?
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if (!(hRC=wglCreateContext(hDC))) // Are We Able To Get A Rendering Context?
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if(!wglMakeCurrent(hDC,hRC)) // Try To Activate The Rendering Context
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
ShowWindow(hWnd,SW_SHOW); // Show The Window
SetForegroundWindow(hWnd); // Slightly Higher Priority
SetFocus(hWnd); // Sets Keyboard Focus To The Window
ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen
if (!InitGL()) // Initialize Our Newly Created GL Window
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
return TRUE; // Success
}
LRESULT CALLBACK WndProc( HWND hWnd, // Handle For This Window
UINT uMsg, // Message For This Window
WPARAM wParam, // Additional Message Information
LPARAM lParam) // Additional Message Information
{
switch (uMsg) // Check For Windows Messages
{
case WM_ACTIVATE: // Watch For Window Activate Message
{
if (!HIWORD(wParam)) // Check Minimization State
{
active=TRUE; // Program Is Active
}
else
{
active=FALSE; // Program Is No Longer Active
}
return 0; // Return To The Message Loop
}
case WM_SYSCOMMAND: // Intercept System Commands
{
switch (wParam) // Check System Calls
{
case SC_SCREENSAVE: // Screensaver Trying To Start?
case SC_MONITORPOWER: // Monitor Trying To Enter Powersave?
return 0; // Prevent From Happening
}
break; // Exit
}
case WM_CLOSE: // Did We Receive A Close Message?
{
PostQuitMessage(0); // Send A Quit Message
return 0; // Jump Back
}
case WM_KEYDOWN: // Is A Key Being Held Down?
{
keys[wParam] = TRUE; // If So, Mark It As TRUE
return 0; // Jump Back
}
case WM_KEYUP: // Has A Key Been Released?
{
keys[wParam] = FALSE; // If So, Mark It As FALSE
return 0; // Jump Back
}
case WM_SIZE: // Resize The OpenGL Window
{
ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord=Width, HiWord=Height
return 0; // Jump Back
}
}
// Pass All Unhandled Messages To DefWindowProc
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
int WINAPI WinMain( HINSTANCE hInstance, // Instance
HINSTANCE hPrevInstance, // Previous Instance
LPSTR lpCmdLine, // Command Line Parameters
int nCmdShow) // Window Show State
{
MSG msg; // Windows Message Structure
BOOL done=FALSE; // Bool Variable To Exit Loop
// Ask The User Which Screen Mode They Prefer
if (MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO)
{
fullscreen=FALSE; // Windowed Mode
}
// Create Our OpenGL Window
if (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16,fullscreen))
{
return 0; // Quit If Window Was Not Created
}
while(!done) // Loop That Runs While done=FALSE
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Is There A Message Waiting?
{
if (msg.message==WM_QUIT) // Have We Received A Quit Message?
{
done=TRUE; // If So done=TRUE
}
else // If Not, Deal With Window Messages
{
TranslateMessage(&msg); // Translate The Message
DispatchMessage(&msg); // Dispatch The Message
}
}
else // If There Are No Messages
{
// Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene()
if (active) // Program Active?
{
if (keys[VK_ESCAPE]) // Was ESC Pressed?
{
done=TRUE; // ESC Signalled A Quit
}
else // Not Time To Quit, Update Screen
{
DrawGLScene(); // Draw The Scene
SwapBuffers(hDC); // Swap Buffers (Double Buffering)
}
}
if (keys[VK_F1]) // Is F1 Being Pressed?
{
keys[VK_F1]=FALSE; // If So Make Key FALSE
KillGLWindow(); // Kill Our Current Window
fullscreen=!fullscreen; // Toggle Fullscreen / Windowed Mode
// Recreate Our OpenGL Window
if (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16,fullscreen))
{
return 0; // Quit If Window Was Not Created
}
}
}
}
// Shutdown
KillGLWindow(); // Kill The Window
return (msg.wParam); // Exit The Program
}
http://nehe.gamedev.net/tutorial/creating_an_opengl_window_%28win32%29/13001/

OpenGL window always busy

I have a small framework which displays a texture in borderless screen window, but when I start it, the application is showing a busy mouse icon when I activate the OpenGL window, and I cannot seem to understand where it is coming from.
The following code is the complete solution (Visual Studio 2010) and should compile as is.
Unfortunately I don't even know where to start looking, thus I copied the complete code here.
BasicProject creates a random texture, and pipes that into the OpenGL window.
Can anyone see why the code is stuck into a busy window?
The OpenGL Callbacks are never reached, but I do not see why not.
BasicProject.cpp (entry point):
/** Sample Project for OpenGL-Display functionality
*
* Anton Roth, 2013
*/
#include "stdafx.h"
#include <conio.h>
#include <process.h>
#include <vector>
#include <Windows.h>
#include <cstdlib>
#include <ctime>
#include "OpenGL-Display.h"
void RunOpenGL(void* pParams);
bool applicationRunning = true;
HANDLE threadOGL;
int _tmain(int argc, _TCHAR* argv[]) {
OGD::OpenGLDisplay_Init(640, 480, 200, 200, 0, "First Display");
threadOGL = (HANDLE)_beginthread(RunOpenGL, 0, NULL);
while(!_kbhit()) {
Sleep(500);
}
applicationRunning = false;
WaitForSingleObject( threadOGL, 500 );
return 0;
}
void RunOpenGL(void* pParams) {
std::vector<char> texture;
texture.resize(640 * 480 * 3);
std::srand(time(0));
while(applicationRunning) {
for(int i = 0; i < 640 * 480 * 3; ++i) {
texture.at(i) = std::rand() % 255;
}
OGD::OpenGLDisplay_Wrapper(&texture.at(0), 640, 480, false, 24, 0);
int x, y;
OGD::OpenGLDisplay_MousePos(x, y, 0);
Sleep(300);
}
}
OpenGL-Display.h:
#ifndef __OPENGLDISPLAY
#define __OPENGLDISPLAY
#include <windows.h> // Header File For Windows
#include <stdio.h> // Header File For Standard Input/Output
#include <gl\gl.h> // Header File For The OpenGL32 Library
#include <gl\glu.h> // Header File For The GLu32 Library
#include <vector>
namespace OGD
{
class OpenGL_Display
{
public:
OpenGL_Display(int newId);
~OpenGL_Display();
void Init_Display(int width, int height, int posX, int posY, LPCSTR className);
void DrawNewImage(int width, int height, char* imageData, bool flip, int bpp);
void GetMouseCords(int& x, int& y);
int ID;
protected:
bool CreateGLWindow(char* title, int bits, int posX, int posY, LPCSTR className);
GLvoid ReSizeGLScene(GLsizei width, GLsizei height);
int LoadGLTextures();
int InitGL(GLvoid);
void UpdateGLBuffers(int width, int height, char* imageData, int bpp);
int DrawGLScene(bool flip);
GLvoid KillGLWindow(GLvoid);
HDC hDC; // Private GDI Device Context
static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc
HGLRC hRC; // Permanent Rendering Context
HWND hWnd; // Holds Our Window Handle
HINSTANCE hInstance; // Holds The Instance Of The Application
bool keys[256]; // Array Used For The Keyboard Routine
bool active; // Window Active Flag Set To TRUE By Default
bool fullscreen; // Fullscreen Flag Set To Fullscreen Mode By Default
bool g_bExitThread; // end thread
GLuint texture; // Bitmap image buffer
int g_iCounter; // Current buffer being grabbed to
bool g_GLdone; // Counter to make sure no unnecessary updates are made which cause CPU load
int xPos;
int yPos;
int xPos_right;
int yPos_right;
int width;
int height;
};
static std::vector<OGD::OpenGL_Display*> oglDisp;
void OpenGLDisplay_Wrapper(char* image, int width, int height, bool flip, int bpp, int ID);
void OpenGLDisplay_Init(int width, int height, int posX, int posY, int ID, LPCSTR className);
void OpenGLDisplay_MousePos(int&x, int&y, int ID);
};
#endif
OpenGL-Display.cpp:
/** Based on code by NeHe tutorials
Adapted to display live camera display with OpenGL
*/
#include "OpenGL-Display.h"
using namespace OGD;
OpenGL_Display::OpenGL_Display(int newId)
{
xPos = -1;
yPos = -1;
ID = newId;
width = 1;
height = 1;
}
OpenGL_Display::~OpenGL_Display()
{
KillGLWindow();
}
void OpenGL_Display::Init_Display(int newWidth, int newHeight, int posX, int posY, LPCSTR inputName)
{
width = newWidth;
height = newHeight;
className = inputName;
if (!CreateGLWindow((char*)className, 24, posX, posY, className))
{
throw;
}
}
LRESULT CALLBACK OpenGL_Display::WndProc( HWND hWnd, // Handle For This Window
UINT uMsg, // Message For This Window
WPARAM wParam, // Additional Message Information
LPARAM lParam) // Additional Message Information
{
switch (uMsg) // Check For Windows Messages
{
case WM_SYSCOMMAND: // Intercept System Commands
{
switch (wParam) // Check System Calls
{
case SC_SCREENSAVE: // Screensaver Trying To Start?
case SC_MONITORPOWER: // Monitor Trying To Enter Powersave?
return 0; // Prevent From Happening
}
break; // Exit
}
case WM_CLOSE: // Did We Receive A Close Message?
{
PostQuitMessage(0); // Send A Quit Message
return 0; // Jump Back
}
case WM_SIZE: // Resize The OpenGL Window
{
oglDisp.at(0)->ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord=Width, HiWord=Height
return 0; // Jump Back
}
}
// Pass All Unhandled Messages To DefWindowProc
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
bool OpenGL_Display::CreateGLWindow(char* title, int bits, int posX, int posY, LPCSTR className)
{
GLuint PixelFormat; // Holds The Results After Searching For A Match
WNDCLASS wc; // Windows Class Structure
DWORD dwExStyle; // Window Extended Style
DWORD dwStyle; // Window Style
RECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values
WindowRect.left=(long)0; // Set Left Value To 0
WindowRect.right=(long)width; // Set Right Value To Requested Width
WindowRect.top=(long)0; // Set Top Value To 0
WindowRect.bottom=(long)height; // Set Bottom Value To Requested Height
hInstance = GetModuleHandle(NULL); // Grab An Instance For Our Window
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Size, And Own DC For Window.
wc.lpfnWndProc = WndProc; // WndProc Handles Messages
wc.cbClsExtra = 0; // No Extra Window Data
wc.cbWndExtra = 0; // No Extra Window Data
wc.hInstance = hInstance; // Set The Instance
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load The Default Icon
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load The Arrow Pointer
wc.hbrBackground = NULL; // No Background Required For GL
wc.lpszMenuName = NULL; // We Don't Want A Menu
wc.lpszClassName = className; // Set The Class Name
RegisterClass(&wc); // Return FALSE
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style
dwStyle=WS_VISIBLE | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;; // Windows Style
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requested Size
//HWND hwndC = GetConsoleWindow();
// Create The Window
hWnd=CreateWindowEx( dwExStyle, // Extended Style For The Window
className, // Class Name
title, // Window Title
//WS_OVERLAPPEDWINDOW,
dwStyle | // Defined Window Style
WS_CLIPSIBLINGS | // Required Window Style
WS_CLIPCHILDREN, // Required Window Style
posX, posY, // Window Position
WindowRect.right-WindowRect.left, // Calculate Window Width
WindowRect.bottom-WindowRect.top, // Calculate Window Height
NULL, // No Parent Window
NULL, // No Menu
hInstance, // Instance
NULL);
static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be
{
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
bits, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // No Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
16, // 16Bit Z-Buffer (Depth Buffer)
0, // No Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
hDC=GetDC(hWnd);
PixelFormat=ChoosePixelFormat(hDC,&pfd);
SetPixelFormat(hDC,PixelFormat,&pfd);
hRC=wglCreateContext(hDC);
wglMakeCurrent(hDC,hRC);
ShowWindow(hWnd,SW_SHOW); // Show The Window
SetForegroundWindow(hWnd); // Slightly Higher Priority
SetFocus(hWnd); // Sets Keyboard Focus To The Window
ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen
InitGL();
return TRUE; // Success
}
int OpenGL_Display::LoadGLTextures() // Load Bitmaps And Convert To Textures
{
// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
glGenTextures(1, &texture); // Create The Texture
// Typical Texture Generation Using Data From The Bitmap
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); // Minimizing filter, in case display is smaller image size
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); // Magnifying filter, in case display is smaller image size
return 1; // Return The Status
}
GLvoid OpenGL_Display::ReSizeGLScene(GLsizei newWidth, GLsizei newHeight) // Resize And Initialize The GL Window
{
width = newWidth;
height = newHeight;
}
int OpenGL_Display::InitGL(GLvoid) // All Setup For OpenGL Goes Here
{
if (!LoadGLTextures()) // Jump To Texture Loading Routine
{
return FALSE; // If Texture Didn't Load Return FALSE
}
return TRUE; // Initialization Went OK
}
void OpenGL_Display::GetMouseCords(int& x, int& y) // All Setup For OpenGL Goes Here
{
x = xPos;
y = yPos;
}
void OpenGL_Display::UpdateGLBuffers(int width, int height, char* imageData, int bpp) {
glBindTexture(GL_TEXTURE_2D, texture);
switch(bpp) {
case 8: glTexImage2D(GL_TEXTURE_2D, 0, GL_INTENSITY, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, imageData); break;
case 16: glTexImage2D(GL_TEXTURE_2D, 0, GL_INTENSITY, width, height, 0, GL_RED, GL_UNSIGNED_SHORT, imageData); break;
case 24: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, imageData); break;
default: return;
}
GLenum mError = glGetError();
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
}
int OpenGL_Display::DrawGLScene(bool flip) // Here's Where We Do All The Drawing
{
if (height==0) // Prevent A Divide By Zero
{
height=1; // Making Height Equal One
}
glViewport(0,0,width,height); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(25.0f,1.0f,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glDisable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
GLenum mError = glGetError();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View
glTranslatef(0.0f,0.0f,-5.0f);
mError = glGetError();
glBindTexture(GL_TEXTURE_2D, texture);
mError = glGetError();
glColor4f(1.0, 1.0, 1.0, 1.0);
mError = glGetError();
if(flip)
{
glBegin(GL_QUADS);
// Front Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.5f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 0.5f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 0.5f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.5f);
glEnd();
mError = glGetError();
}
else
{
glBegin(GL_QUADS);
// Front Face
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 0.5f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, -1.0f, 0.5f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 0.5f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 0.5f);
glEnd();
mError = glGetError();
}
mError = glGetError();
return TRUE; // Keep Going
}
GLvoid OpenGL_Display::KillGLWindow(GLvoid) // Properly Kill The Window
{
if (fullscreen) // Are We In Fullscreen Mode?
{
ChangeDisplaySettings(NULL,0); // If So Switch Back To The Desktop
ShowCursor(TRUE); // Show Mouse Pointer
}
if (hRC) // Do We Have A Rendering Context?
{
wglMakeCurrent(NULL,NULL);
wglDeleteContext(hRC);
hRC=NULL; // Set RC To NULL
}
ReleaseDC(hWnd,hDC);
DestroyWindow(hWnd);
UnregisterClass("OpenGL_Display",hInstance);
}
void OpenGL_Display::DrawNewImage(int width, int height, char* imageData, bool flip, int bpp)
{
BOOL returnVal = wglMakeCurrent(hDC, hRC);
UpdateGLBuffers(width, height, imageData, bpp);
DrawGLScene(flip);
SwapBuffers(hDC);
wglMakeCurrent(NULL, NULL);
}
void OGD::OpenGLDisplay_Init(int width, int height, int posX, int posY, int ID, LPCSTR className)
{
for(unsigned int i = 0; i < oglDisp.size(); ++i) {
if(oglDisp.at(i)->ID == ID) {
return;
}
}
oglDisp.push_back(new OGD::OpenGL_Display(ID));
oglDisp.at(oglDisp.size()-1)->Init_Display(width, height, posX, posY, className); //by default this ID is latest
wglMakeCurrent(NULL, NULL);
GLenum mError = glGetError();
}
void OGD::OpenGLDisplay_Wrapper(char* image, int width, int height, bool flip, int bpp, int ID)
{
for(unsigned int i = 0; i < oglDisp.size(); ++i) {
if(oglDisp.at(i)->ID == ID) {
oglDisp.at(i)->DrawNewImage(width, height, image, flip, bpp);
return;
}
}
}
Even though your window is OpenGL-based, you should create a message loop and repeatedly call GetMessage, TranslateMessage and DispatchMessage. Handle WM_PAINT even though it doesn't need to draw anything. If you don't do this, Windows will think your application doesn't respond, and shows the busy cursor (or worse, shows the 'Application not responding' dialogue.)

OpenGL won't draw my quad

I've learnt a bit of OpenGL using java. Now I'm trying to transition to C++.
I'm trying to setup a window and render a quad, but its not showing up. I just get a black screen.
I'm using an example from the OpenGL Superbible as a start.
Here is my code:
#include <stdio.h>
#define GLEW_STATIC
#include "include\GL\glew.h"
#include "include\GL\wglew.h"
#pragma comment(lib, "lib\\glew32s.lib")
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
HWND g_hWnd;
HGLRC g_hRC;
HDC g_hDC;
HINSTANCE g_hInstance;
WNDCLASS g_windClass;
RECT g_windowRect;
bool g_ContinueRendering;
void RenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glVertex3f(-10.0f, -10.0f, 5.0f);
glVertex3f(-10.0f, 10.0f, 5.0f);
glVertex3f(10.0f, 10.0f, 5.0f);
glVertex3f(10.0f, -10.0f, 5.0f);
glEnd();
printf("%s", gluErrorString(glGetError()));
SwapBuffers(g_hDC);
}
///////////////////////////////////////////////////////////////////////////////
// Window has changed size, or has just been created. In either case, we need
// to use the window dimensions to set the viewport and the projection matrix.
void ChangeSize(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.0f, float(w) / float(h), 1.0f, 500.0f);
}
///////////////////////////////////////////////////////////////////////////////
// Callback functions to handle all window functions this app cares about.
// Once complete, pass message on to next app in the hook chain.
LRESULT CALLBACK WndProc( HWND hWnd, // Handle For This Window
UINT uMsg, // Message For This Window
WPARAM wParam, // Additional Message Information
LPARAM lParam) // Additional Message Information
{
unsigned int key = 0;
// Handle relevant messages individually
switch(uMsg)
{
case WM_ACTIVATE:
case WM_SETFOCUS:
RenderScene();
return 0;
case WM_SIZE:
ChangeSize(LOWORD(lParam),HIWORD(lParam));
RenderScene();
break;
case WM_CLOSE:
g_ContinueRendering = false;
PostQuitMessage(0);
return 0;
default:
// Nothing to do now
break;
}
// Pass All Unhandled Messages To DefWindowProc
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
bool setupWindow(int nWidth, int nHeight)
{
bool bRetVal = true;
int nWindowX = 0;
int nWindowY = 0;
int nPixelFormat = -1;
PIXELFORMATDESCRIPTOR pfd;
DWORD dwExtStyle;
DWORD dwWindStyle;
HINSTANCE g_hInstance = GetModuleHandle(NULL);
TCHAR szWindowName[50] = TEXT("Block Redux");
TCHAR szClassName[50] = TEXT("OGL_CLASS");
// setup window class
g_windClass.lpszClassName = szClassName; // Set the name of the Class
g_windClass.lpfnWndProc = (WNDPROC)WndProc;
g_windClass.hInstance = g_hInstance; // Use this module for the module handle
g_windClass.hCursor = LoadCursor(NULL, IDC_ARROW);// Pick the default mouse cursor
g_windClass.hIcon = LoadIcon(NULL, IDI_WINLOGO);// Pick the default windows icons
g_windClass.hbrBackground = NULL; // No Background
g_windClass.lpszMenuName = NULL; // No menu for this window
g_windClass.style = CS_HREDRAW | CS_OWNDC | // set styles for this class, specifically to catch
CS_VREDRAW; // window redraws, unique DC, and resize
g_windClass.cbClsExtra = 0; // Extra class memory
g_windClass.cbWndExtra = 0; // Extra window memory
// Register the newly defined class
if(!RegisterClass( &g_windClass ))
bRetVal = false;
dwExtStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
dwWindStyle = WS_OVERLAPPEDWINDOW;
ShowCursor(TRUE);
g_windowRect.left = nWindowX;
g_windowRect.right = nWindowX + nWidth;
g_windowRect.top = nWindowY;
g_windowRect.bottom = nWindowY + nHeight;
// Setup window width and height
AdjustWindowRectEx(&g_windowRect, dwWindStyle, FALSE, dwExtStyle);
//Adjust for adornments
int nWindowWidth = g_windowRect.right - g_windowRect.left;
int nWindowHeight = g_windowRect.bottom - g_windowRect.top;
// Create window
g_hWnd = CreateWindowEx(dwExtStyle, // Extended style
szClassName, // class name
szWindowName, // window name
dwWindStyle |
WS_CLIPSIBLINGS |
WS_CLIPCHILDREN,// window stlye
nWindowX, // window position, x
nWindowY, // window position, y
nWindowWidth, // height
nWindowHeight, // width
NULL, // Parent window
NULL, // menu
g_hInstance, // instance
NULL); // pass this to WM_CREATE
// now that we have a window, setup the pixel format descriptor
g_hDC = GetDC(g_hWnd);
// Set a dummy pixel format so that we can get access to wgl functions
SetPixelFormat( g_hDC, 1,&pfd);
// Create OGL context and make it current
g_hRC = wglCreateContext( g_hDC );
wglMakeCurrent( g_hDC, g_hRC );
if (g_hDC == 0 ||
g_hDC == 0)
{
bRetVal = false;
printf("!!! An error occured creating an OpenGL window.\n");
}
// Setup GLEW which loads OGL function pointers
GLenum err = glewInit();
if (GLEW_OK != err)
{
/* Problem: glewInit failed, something is seriously wrong. */
bRetVal = false;
printf("Error: %s\n", glewGetErrorString(err));
}
const GLubyte *oglVersion = glGetString(GL_VERSION);
printf("This system supports OpenGL Version %s.\n", oglVersion);
// Now that extensions are setup, delete window and start over picking a real format.
wglMakeCurrent(NULL, NULL);
wglDeleteContext(g_hRC);
ReleaseDC(g_hWnd, g_hDC);
DestroyWindow(g_hWnd);
// Create the window again
g_hWnd = CreateWindowEx(dwExtStyle, // Extended style
szClassName, // class name
szWindowName, // window name
dwWindStyle |
WS_CLIPSIBLINGS |
WS_CLIPCHILDREN,// window stlye
nWindowX, // window position, x
nWindowY, // window position, y
nWindowWidth, // height
nWindowHeight, // width
NULL, // Parent window
NULL, // menu
g_hInstance, // instance
NULL); // pass this to WM_CREATE
g_hDC = GetDC(g_hWnd);
int nPixCount = 0;
// Specify the important attributes we care about
int pixAttribs[] =
{
WGL_SUPPORT_OPENGL_ARB, 1, // Must support OGL rendering
WGL_DRAW_TO_WINDOW_ARB, 1, // pf that can run a window
WGL_COLOR_BITS_ARB, 24, // 8 bits of each R, G and B
WGL_DEPTH_BITS_ARB, 16, // 16 bits of depth precision for window
WGL_DOUBLE_BUFFER_ARB, GL_TRUE, // Double buffered context
WGL_SAMPLE_BUFFERS_ARB, GL_TRUE, // MSAA on
WGL_SAMPLES_ARB, 8, // 8x MSAA
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, // pf should be RGBA type
0 // NULL termination
};
// Ask OpenGL to find the most relevant format matching our attribs
// Only get one format back.
wglChoosePixelFormatARB(g_hDC, &pixAttribs[0], NULL, 1, &nPixelFormat, (UINT*)&nPixCount);
if(nPixelFormat == -1)
{
// Couldn't find a format, perhaps no 3D HW or drivers are installed
g_hDC = 0;
g_hDC = 0;
bRetVal = false;
printf("!!! An error occurred trying to find a pixel format with the requested attribs.\n");
}
else
{
// Got a format, now set it as the current one
SetPixelFormat( g_hDC, nPixelFormat, &pfd );
GLint attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 3,
0 };
g_hRC = wglCreateContextAttribsARB(g_hDC, 0, attribs);
if (g_hRC == NULL)
{
printf("!!! Could not create an OpenGL 3.3 context.\n");
attribs[3] = 2;
g_hRC = wglCreateContextAttribsARB(g_hDC, 0, attribs);
if (g_hRC == NULL)
{
printf("!!! Could not create an OpenGL 3.2 context.\n");
attribs[3] = 1;
g_hRC = wglCreateContextAttribsARB(g_hDC, 0, attribs);
if (g_hRC == NULL)
{
printf("!!! Could not create an OpenGL 3.1 context.\n");
attribs[3] = 0;
g_hRC = wglCreateContextAttribsARB(g_hDC, 0, attribs);
if (g_hRC == NULL)
{
printf("!!! Could not create an OpenGL 3.0 context.\n");
printf("!!! OpenGL 3.0 and higher are not supported on this system.\n");
}
}
}
}
wglMakeCurrent( g_hDC, g_hRC );
}
if (g_hDC == 0 ||
g_hDC == 0)
{
bRetVal = false;
printf("!!! An error occured creating an OpenGL window.\n");
}
// If everything went as planned, display the window
if( bRetVal )
{
ShowWindow( g_hWnd, SW_SHOW );
SetForegroundWindow( g_hWnd );
SetFocus( g_hWnd );
g_ContinueRendering = true;
}
return bRetVal;
}
///////////////////////////////////////////////////////////////////////////////
// Cleanup window, OGL context and related state
// Called on exit and on error
bool KillWindow( )
{
bool bRetVal = true;
//Cleanup OGL RC
if(g_hRC)
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(g_hRC);
g_hRC = NULL;
}
// release the DC
if(g_hDC)
{
ReleaseDC(g_hWnd, g_hDC);
g_hDC = NULL;
}
// Destroy the window
if(g_hWnd)
{
DestroyWindow(g_hWnd);
g_hWnd = NULL;;
}
// Delete the window class
TCHAR szClassName[50] = TEXT("OGL_CLASS");
UnregisterClass(szClassName, g_hInstance);
g_hInstance = NULL;
ShowCursor(TRUE);
return bRetVal;
}
///////////////////////////////////////////////////////////////////////////////
// Main rendering loop
// Check for window messages and handle events, also draw scene
void mainLoop()
{
MSG msg;
// Check for waiting mssgs
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if (msg.message==WM_QUIT)
{
g_ContinueRendering = false;
}
else
{
// Deal with mssgs
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
RenderScene();
}
}
int main(int argc, char **argv)
{
if(setupWindow(800, 600))
{
ChangeSize(800, 600);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
while (g_ContinueRendering)
{
mainLoop();
}
}
KillWindow();
return 0;
}
I'm pretty sure all the window setup stuff is working.
If i change the glClearColor, the windows color changes.
I hope someone can see what's wrong with it.
Looking at your code, you're using OpenGL 3.x.
Try triangles, as GL_QUADS is deprecated.
Also, you should pass CreateContextAttrib the minimum version you require, you will automatically get a newer version if available.
You're drawing them behind you. The z-value of your quad is +5, but in OpenGL, forward is negative in the z direction. Change the z-value to -5 and I think you'll see something.
Or add:
glPushMatrix();
glTranslatef(0,0,-20.0f);
//Your code for drawing.
glBegin(GL_QUADS);
...
glEnd();
//Added
glPopMatrix();
I'm just shooting from the hip here, but have you tried changing the order of the vertices? This could be the culprit of backface culling.