I'm trying to write a simple OpenGL program that draws a simple line on the screen.
All OpenGL functions are dwelling inside a class named Engine.
class Engine
{
public:
~Engine();
static Engine * GI();
void Run();
static void WmPaint();
private:
Engine();
static Engine * m_Instance;
HANDLE m_hTimerQueue;
ULONG_PTR m_GdiPlusToken;
static VOID CALLBACK WaitOrTimerCallback(_In_ PVOID lpParameter, _In_ BOOLEAN TimerOrWaitFired);
static void InitializeOpenGL();
static void DestroyOpenGL();
};
I used my OpenGL text book to write this program. I don't understand what I wrote with OpenGL functions. I just copied them from my textbook. The OpenGL related class methods are:
Engine::WmPaint() : Called every time the window receives WM_PAINT message.
Engine::InitializeOpenGL() : Does initial operations.
Engine::DestroyOpenGL() : Does some necessary final operations before closing.
The class method definitions are as seen below.
#include "Engine.h"
#include <windows.h>
//#include <gdiplus.h>
#include <GL/GL.h>
#include <GL/GLU.h>
#pragma comment (lib, "opengl32.lib")
#include "Settings.h"
#include "Status.h"
Engine * Engine::m_Instance = 0;
Engine::Engine()
{
WaitForSingleObject(Status::hEvent_GuiInitialized, INFINITE);
HANDLE hTimer;
m_hTimerQueue = CreateTimerQueue();
BOOL bOk = CreateTimerQueueTimer( /*_Out_ (PHANDLE)*/ &hTimer,
/*_In_opt_ (HANDLE)*/ m_hTimerQueue,
/*_In_ (WAITORTIMERCALLBACK)*/ WaitOrTimerCallback,
/*_In_opt_ (PVOID)*/ NULL,
/*_In_ (DWORD)*/ 0,
/*_In_ (DWORD)*/ Settings::RefreshPeriod_ms,
/*_In_ (ULONG)*/ WT_EXECUTEDEFAULT);
//Gdiplus::GdiplusStartupInput GdiPlusStartupInput;
//Gdiplus::GdiplusStartup(&m_GdiPlusToken, &GdiPlusStartupInput, NULL);
InitializeOpenGL();
}
Engine::~Engine()
{
DeleteTimerQueue(m_hTimerQueue);
//Gdiplus::GdiplusShutdown(m_GdiPlusToken);
DestroyOpenGL();
}
Engine * Engine::GI()
{
if (m_Instance == 0)
{
m_Instance = new Engine();
}
return m_Instance;
}
void Engine::Run()
{
}
void Engine::WmPaint()
{
//glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glColor3ub(255, 128, 80);
glBegin(GL_POINTS);
//for (int i=1; i<200; i++)
//glVertex3i(i, i, 0);
for (float i=-1.0; i<+1.0; i+=0.001)
glVertex3f(i, i, 0);
glEnd();
}
/*void Engine::WmPaint()
{
static PAINTSTRUCT Ps;
static HBRUSH hBrush1 = CreateSolidBrush(RGB(50,100,255));
static HBRUSH hBrush2 = CreateSolidBrush(RGB(255,100,50));
static Gdiplus::Image img(L"images\\myimage.png");
static Gdiplus::SolidBrush brBlack(Gdiplus::Color::Black);
HDC hDc = 0;
PAINTSTRUCT ps;
HDC hdc = BeginPaint(Status::hWndGraph, &ps);
Gdiplus::Graphics g(hdc);
//g.FillRectangle(&brBlack, 0, 0, Settings::GRAPHAREA_WIDTH, Settings::GRAPHAREA_HEIGHT);
g.Clear(Gdiplus::Color(0, 0, 0));
g.DrawImage(&img, Gdiplus::Rect(5, 5, 5 + img.GetWidth(), 5 + img.GetHeight()));
EndPaint(Status::hWndGraph, &ps);
}*/
VOID CALLBACK Engine::WaitOrTimerCallback(_In_ PVOID lpParameter, _In_ BOOLEAN TimerOrWaitFired)
{
//RedrawWindow(Gui::GI()->MainWnd.GetGraphHandle(), NULL, NULL, RDW_UPDATENOW);
//InvalidateRect(Status::hWndGraph, NULL, FALSE);
//SendMessageW(Status::hWndGraph, WM_PRINT, 0, PRF_CLIENT);
//UpdateWindow(Status::hWndGraph);
//MessageBoxW(NULL, L"Timer", L"Timer", NULL);
}
void Engine::InitializeOpenGL()
{
Status::hDC = GetDC(Status::hWndMain);
if (Status::hDC == NULL) throw(1);
PIXELFORMATDESCRIPTOR Pfd;
ZeroMemory(&Pfd, sizeof(Pfd));
Pfd.nSize = sizeof(Pfd);
Pfd.nVersion = 1;
Pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
Pfd.iPixelType = PFD_TYPE_RGBA;
Pfd.cColorBits = 24;
Pfd.cDepthBits = 16;
Pfd.iLayerType = PFD_MAIN_PLANE;
int iFormat = ChoosePixelFormat(Status::hDC, &Pfd);
if (iFormat == 0) throw(2);
bool bOK = SetPixelFormat(Status::hDC, iFormat, &Pfd);
if (bOK == FALSE) throw(3);
Status::hGLRC = wglCreateContext(Status::hDC);
if (Status::hGLRC == NULL) throw(4);
bool bReturn = wglMakeCurrent(Status::hDC, Status::hGLRC);
if (bReturn == FALSE) throw(5);
//std::string version = (char*)glGetString(GL_VERSION);
// Outputs: 2.1.0
///////////////////
glEnable(GL_DEPTH_TEST);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glViewport(0, 0, Settings::GRAPHAREA_WIDTH, Settings::GRAPHAREA_HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(52.0f, (GLfloat) Settings::GRAPHAREA_WIDTH / (GLfloat) Settings::GRAPHAREA_HEIGHT, 1.0f, 1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void Engine::DestroyOpenGL()
{
bool bReturn = wglMakeCurrent(Status::hDC, NULL);
if (bReturn == FALSE) throw(1);
bReturn = wglDeleteContext(Status::hGLRC);
if (bReturn == FALSE) throw(2);
}
I am handling the WM_PAINT message like this:
case WM_PAINT:
if (hWnd == Status::hWndGraph) // The graphic area
{
Engine::GI()->WmPaint();
return TRUE;
//lResult = DefWindowProc(hWnd, uMsg, wParam, lParam);
//return lResult;
}
else if (hWnd == Status::hWndMain) // The main window
{
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
else
{
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
break;
The graphic area is a second window which is embedded (child) inside the main window.
Main Window
Class Styles : CS_HREDRAW | CS_VREDRAW
Window Styles : WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_TABSTOP | WS_GROUP | WS_VISIBLE
Window Ex-Styles : WS_EX_ACCEPTFILES | WS_EX_CONTROLPARENT | WS_EX_LEFT | WS_EX_LTRREADING
Graphic Area
Class Styles : CS_HREDRAW | CS_VREDRAW | CS_OWNDC
Window Styles : WS_CHILD | WS_VISIBLE
Window Ex-Styles : 0
Yesterday, I was able to run GDI+ code in the program structure. The GDI+ code is still there, commented out. Today, I'm trying to run OpenGL code. Whatever I did, I wasn't successful. Can you please find what I'm doing wrong here?