Jump to content
  • Advertisement
Sign in to follow this  
hkBattousai

My "Hello World" OpenGL application doesn't display anything

This topic is 1444 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

 

sicEzrX.png

 

 

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?

Edited by hkBattousai

Share this post


Link to post
Share on other sites
Advertisement
Is Engine::InitializeOpenGL called at all?

Also why is the error handling so horrible? Why do you throw ints instead of std::runtime_errors with an actually readable string?

The first thing I would try is getting a non-black color during glClear (via an appropriate call to glClearColor). The rendering code I see won't be any use. Even if the setup of the projection/model matrices and the other states actually worked like that, you are rendering degenerate triangles which will be either culled completely or likely invisible.

Well, you are rendering points, not triangles. But you are rendering them at z=0 and that's outside of your view frustum unless I missed something else. Since I seem to suffer from a caffeine undersupply this morning that looks decidedly possible. I'd start with trying to get a non-black clear color and then see where things are going. Edited by BitMaster

Share this post


Link to post
Share on other sites

Is Engine::InitializeOpenGL called at all?

Also why is the error handling so horrible? Why do you throw ints instead of std::runtime_errors with an actually readable string?

 

Engine::InitializeOpenGL() is called in the constructor.

 

Some parts may look horrible. This is just a start up project to learn how to use OpenGL.

Share this post


Link to post
Share on other sites

Your perspective matrix has a znear of 1. Your modelview is identity. Your points are at z=0. They are outside of your view area. Try placing your points at z>=1. z <= -1. (Thanks Brother Bob!)

 

On another note you should probably invalidate your window somewhere. Windows are only redrawn if necessary. Look up InvalidateRect. To check if this is your culprit, try resizing your window with the mouse and see if something is displayed afterwards.

 

This checks if your general OpenGL setup is correct:

[quote name='BitMaster' timestamp='1417683122' post='5196204']
The first thing I would try is getting a non-black color during glClear (via an appropriate call to glClearColor).
[/quote

Edited by duckflock

Share this post


Link to post
Share on other sites

Your perspective matrix has a znear of 1. Your modelview is identity. Your points are at z=0. They are outside of your view area. Try placing your points at z>=1.

The symptom is correct, but it has to be z <= -1, because the Z-axis is pointing out from the screen towards you. It may be confusing, but the clip plane values are the distances along the negative Z-axis, which mean that a near clip plane value of 1 places the near clip plane value at Z = -1.

Share this post


Link to post
Share on other sites

 

Your perspective matrix has a znear of 1. Your modelview is identity. Your points are at z=0. They are outside of your view area. Try placing your points at z>=1.

The symptom is correct, but it has to be z <= -1, because the Z-axis is pointing out from the screen towards you. It may be confusing, but the clip plane values are the distances along the negative Z-axis, which mean that a near clip plane value of 1 places the near clip plane value at Z = -1.

 

Doh, that's rightrolleyes.gif . Fixed.

Share this post


Link to post
Share on other sites


On another note you should probably invalidate your window somewhere. Windows are only redrawn if necessary. Look up InvalidateRect. To check if this is your culprit, try resizing your window with the mouse and see if something is displayed afterwards.

 

I enabled that line in the timer function. Now it is called periodically. (I had it disabled, because GDI+ was running alright without it.)

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);
}


Your perspective matrix has a znear of 1. Your modelview is identity. Your points are at z=0. They are outside of your view area. Try placing your points at z <= -1.

 

I hope, I did it correctly:

// Previous:
gluPerspective(52.0f, (GLfloat) Settings::GRAPHAREA_WIDTH / (GLfloat) Settings::GRAPHAREA_HEIGHT, 1.0f, 1000.0f);

// Now:
gluPerspective(52.0f, (GLfloat) Settings::GRAPHAREA_WIDTH / (GLfloat) Settings::GRAPHAREA_HEIGHT, -2.0f, 5.0f);


I'd start with trying to get a non-black clear color and then see where things are going.

 

I changed the arguments of glClearColor() in the initialization method.

// Previous:
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

// Now:
glClearColor(0.0f, 0.5f, 0.5f, 0.0f);

Result:

 

Nothing changed. Nothing.

Share this post


Link to post
Share on other sites

 

 


Your perspective matrix has a znear of 1. Your modelview is identity. Your points are at z=0. They are outside of your view area. Try placing your points at z <= -1.

 

I hope, I did it correctly:

// Previous:
gluPerspective(52.0f, (GLfloat) Settings::GRAPHAREA_WIDTH / (GLfloat) Settings::GRAPHAREA_HEIGHT, 1.0f, 1000.0f);

// Now:
gluPerspective(52.0f, (GLfloat) Settings::GRAPHAREA_WIDTH / (GLfloat) Settings::GRAPHAREA_HEIGHT, -2.0f, 5.0f);

You did not. The clip plane distances have to be positive. You have to change the coordinates of your vertices, either by setting the Z-coordinates directly or indirectly by translating the model view matrix.

Share this post


Link to post
Share on other sites


You did not. The clip plane distances have to be positive. You have to change the coordinates of your vertices, either by setting the Z-coordinates directly or indirectly by translating the model view matrix.

 

I'm sorry, I don't understand what you are saying. I'm a total newbie and this is my hello world project in OpenGL. Can you please tell me what do I have to do exactly by adding some sample code?

Share this post


Link to post
Share on other sites

The call to gluPerspective in your first post was fine. What you need to change is the actual coordinates you pass to glVertex. The last parameter is the Z-coordinarte, which you set to zero in your first post. Set the Z-coordinate to something else, for example:

glVertex3f(i, i, -2);

instead of

glVertex3f(i, i, 0);

But even if this is a problem, your object probably won't show up anyway. You said that changing the clear color didn't work either, so there are other more fundamental problems as well.

Edited by Brother Bob

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!