Skip to main content
GameDev.net gamedev.net
🔒 Locked

2 problems I cant fix

Started by CppNet Jun 16, 2007 at 10:59 AM 4 replies 750+ views
Original Post
CppNet
CppNet
I have 2 problems with my code and I'm having trouble fixing it. And I've only been learning OpenGL for 2 days, so I don't know how to fix it, because obvioulsy I don't know what is causing the problem. The code below is VERY similar to NeHe, I'm learning GL from his tutorials. Anyway, here are my problems:

#include <windows.h> 
#include <gl/gl.h> 
#include <gl/glu.h> 
#include <gl/glaux.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 

HWND hWnd = NULL;
HINSTANCE hInstance = NULL; 
HGLRC hRC = NULL; 
HDC hDC = NULL; 

BOOL keys[256]; 
BOOL active = TRUE; 
GLfloat rotation_3d = 0.0f;

GLvoid ResizeGLScene(GLsizei width, GLsizei height)
{
	if (height == 0)
		height = 1; 

	glViewport(0, 0, width, height); 
	glMatrixMode(GL_PROJECTION); 
	glLoadIdentity(); 
	glMatrixMode(GL_MODELVIEW); 
	glLoadIdentity(); 
	gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f); 
}

BOOL CreateGL()
{
	glShadeModel(GL_SMOOTH); 
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
	glClearDepth(1.0f); 
	glEnable(GL_DEPTH_TEST); 
	glDepthFunc(GL_LEQUAL); 
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 

	return TRUE; 
}

BOOL DrawGLScene()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
	glLoadIdentity(); 

	glTranslatef(0.0f, 0.0f, -6.0f); 

	glBegin(GL_TRIANGLES); 
		glColor3f(1.0f, 0.0f, 0.0f);	
		glVertex3f(0.0f, 1.0f, 0.0f);   //front top
		glColor3f(0.0f, 1.0f, 0.0f);	  
		glVertex3f(-1.0f, -1.0f, 0.0f); //front left
		glVertex3f(1.0f, -1.0f, 0.0f);  //front right
		glColor3f(0.0f, 0.0f, 1.0f); 
	glEnd(); 

	return TRUE; 
}

GLvoid KillGLScene()
{
	if (hRC)
	{
		wglMakeCurrent(NULL, NULL); 
		wglDeleteContext(hRC); 
		hRC = NULL; 
	}

	if (ReleaseDC(hWnd, hDC))
		hDC = NULL; 

	if (!DestroyWindow(hWnd))
		hWnd = NULL; 

	if (!UnregisterClass("OpenGL", hInstance))
		hInstance = NULL; 
}

BOOL CreateGLScene(LPSTR caption, GLsizei width, GLsizei height, GLsizei bits)
{
	WNDCLASSEX wc; 
	RECT window; 
	GLuint pixel_fmt; 

    hInstance = GetModuleHandle(NULL); 

	window.top = 0; 
	window.bottom = height; 
	window.left = 0; 
	window.right = width; 

	wc.cbSize = sizeof (WNDCLASSEX); 
	wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; 
	wc.lpfnWndProc = WndProc; 
	wc.cbClsExtra = 0; 
	wc.cbWndExtra = 0; 
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 
	wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); 
	wc.hCursor = LoadCursor(NULL, IDC_ARROW); 
	wc.hInstance = hInstance; 
	wc.hbrBackground = NULL; 
	wc.lpszClassName = "OpenGL"; 
	wc.lpszMenuName = NULL; 

	if (!RegisterClassEx(&wc))
		return FALSE; 

	AdjustWindowRectEx(&window, WS_OVERLAPPEDWINDOW, FALSE, 0); 

	hWnd = CreateWindowEx (
		0, 
		"OpenGL", 
		caption, 
		WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,  
		200, 
		200, 
		window.right - window.left, 
		window.bottom - window.top, 
		NULL, 
		NULL, 
		hInstance, 
		NULL); 

	if (!hWnd)
	{
		KillGLScene(); 
		return FALSE; 
	}

	PIXELFORMATDESCRIPTOR pfd = 
	{
		sizeof(PIXELFORMATDESCRIPTOR), 
		1, 
		PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 
		PFD_TYPE_RGBA, 
		0, 0, 0, 0, 0, 0, 
		0, 
		0, 
		0, 
		0, 0, 0, 0, 
		16, 
		0, 
		0, 
		PFD_MAIN_PLANE, 
		0,  
		0, 0, 0
	}; 

	if (!(hDC = GetDC(hWnd)))
	{
		KillGLScene(); 
		return FALSE; 
	}

	if (!(pixel_fmt = ChoosePixelFormat(hDC, &pfd)))
	{
		KillGLScene(); 
		return FALSE; 
	}

	if (!SetPixelFormat(hDC, pixel_fmt, &pfd))
	{
		KillGLScene(); 
		return FALSE; 
	}

	if (!(hRC = wglCreateContext(hDC)))
	{
		KillGLScene(); 
		return FALSE; 
	}

	if (!wglMakeCurrent(hDC, hRC))
	{
		KillGLScene(); 
		return FALSE; 
	}

	ShowWindow(hWnd, SW_SHOW); 
	SetForegroundWindow(hWnd);
	SetFocus(hWnd);
	ResizeGLScene(width, height); 

	//create opengl
	if (!CreateGL())
	{
		KillGLScene(); 
		return FALSE; 
	}

	return TRUE; 
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_ACTIVATE:
		{
			if (HIWORD(wParam))
				active = TRUE; 
			else
				active = FALSE; 

			break;
		}

	case WM_CLOSE:
		PostQuitMessage(0); 
		break;

	case WM_KEYDOWN:
		keys[wParam] = TRUE; 
		break;

	case WM_KEYUP:
		keys[wParam] = FALSE; 
		break;

	case WM_SIZE: 
		ResizeGLScene(LOWORD(lParam), HIWORD(lParam)); 
		break;
	}

	return DefWindowProc(hwnd, msg, wParam, lParam); 
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
{
	MSG msg; 
	ZeroMemory(&msg, sizeof(msg)); 

	if (!CreateGLScene("OpenGL 3D Polygons", 640, 480, 16))
		return 1; 

	while (msg.message != WM_QUIT)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg); 
			DispatchMessage(&msg); 
		}

		else
		{
			if (active)
			{
				DrawGLScene(); 
				SwapBuffers(hDC); 
			}
		}
	}

	KillGLScene(); 
	return 0; 
}

This is just the start of a program that renders a 3d pyramid, not complete yet. But when I run the program, it just shows a blank screen. -How can I fix this? -What is causing the problem? -------------------------------------------------------------------------------
[source lang="cpp]
#include <windows.h> 
#include <gl/gl.h> 
#include <gl/glu.h> 
#include <gl/glaux.h> 

HWND hWnd = NULL; 
HINSTANCE hInstance = NULL; 
HGLRC hRC = NULL; 
HDC hDC = NULL; 

BOOL keys[256]; 
BOOL active = TRUE; 
BOOL fullscreen = TRUE; 

const char szClassName[] = "OpenGL"; 

//WndProc reference
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 

GLvoid ResizeGLScene(GLsizei width, GLsizei height)
{
	if (height == 0)   //prevent divide by 0 errors
		height = 1; 

	glViewport(0, 0, width, height); 
	glMatrixMode(GL_PROJECTION); 
	glLoadIdentity(); 
	glMatrixMode(GL_MODELVIEW); 
	glLoadIdentity(); 
	gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);	 //calculate aspect ratio of window
}

int CreateGL()
{
	glShadeModel(GL_SMOOTH);     //enables smooth shading
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);    //black background
	glClearDepth(1.0f);       //depth buffer setup
	glEnable(GL_DEPTH_TEST);  //enables depth testing
	glDepthFunc(GL_LEQUAL);   //type of depth testing to do
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);   //the nicest perspectives
				
	return TRUE; 
}

int DrawGLScene()
{
	static GLfloat size = 0.01f; 
	static GLfloat rtri = 0.0f; 
	static GLfloat rquad = 0.0f; 

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	 //clear color and depth buffers
	glLoadIdentity(); 
	
	glTranslatef(-0.5f, 0.0f, 0.0f); 
	glRotatef(rtri, 1.0f, 1.0f, 1.0f); 

	glBegin(GL_TRIANGLES); 
		glColor3f(1.0f, 0.0f, 0.0f); 
		glVertex3f(0.0f, size, 0.0f);
		glColor3f(0.0f, 1.0f, 0.0f); 
		glVertex3f(-size, -size, 0.0f);
		glColor3f(0.0f, 0.0f, 1.0f); 
		glVertex3f(size, -size, 0.0f); 
	glEnd(); 

	glLoadIdentity();      //reset the axis

	glTranslatef(0.5f, 0.0f, 0.0f); 
	glRotatef(rquad, 1.0f, 1.0f, 1.0f); 

	glBegin(GL_QUADS); 
		glColor3f(1.0f, 0.0f, 0.0f); 
		glVertex3f(-size, size, 0.0f); 
		glColor3f(0.0f, 1.0f, 0.0f); 
		glVertex3f(size, size, 0.0f); 
		glColor3f(0.0f, 0.0f, 1.0f); 
		glVertex3f(size, -size, 0.0f); 
		glColor3f(0.5f, 0.5f, 0.0f); 
		glVertex3f(-size, -size, 0.0f); 
	glEnd(); 

	rtri += fullscreen ? 3.0f : 0.5f;  
	rquad -= fullscreen ? 10.0f : 0.5f; 

	if (size < 0.4)
		size += 0.0001; 

	return TRUE; 
}

GLvoid KillGLWindow()
{
	if (fullscreen)
	{
		ChangeDisplaySettings(NULL, 0);   //switch back to the desktop
		ShowCursor(TRUE);                 //show the cursor
	}

	if (hRC)     //if we have a rendering context
	{
		if (!wglMakeCurrent(NULL, NULL))   //are we able to release the rc and dc contexts? 
			MessageBox(NULL, "Release of RC and DC failed!", "Error", MB_OK | MB_ICONINFORMATION); 

		if (!wglDeleteContext(hRC))    //are we able to release the rc?
			MessageBox(NULL, "Release of RC failed!", "Error", MB_OK | MB_ICONINFORMATION); 

		hRC = NULL;	    //set hRC to null
	}

	if (hDC && !ReleaseDC(hWnd, hDC))  //are we able to release the dc? 
		hDC = NULL; 

	if (hWnd && !DestroyWindow(hWnd))  //are we able to destroy the window? 
		hWnd = NULL; 

	if (!UnregisterClass(szClassName, hInstance))  //are we able to unregister the classes? 
		hInstance = NULL; 
}

BOOL CreateGLWindow(char *title, int width, int height, int bits, bool fullscreen_flags)
{
	GLuint pixel_format; 
	WNDCLASSEX wc; 
	RECT window; 
	DWORD ex_style; 
	DWORD style; 

	window.top = 0; 
	window.bottom = height; 
	window.left = 0; 
	window.right = width; 

	fullscreen = fullscreen_flags;   //set the fullscreen modes
	hInstance = GetModuleHandle(NULL);  //grab an instance for our window

	wc.cbSize = sizeof (WNDCLASSEX); 
	wc.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC;  //redraw on resize and private dc
	wc.lpfnWndProc = WndProc; 
	wc.cbClsExtra = 0; 
	wc.cbWndExtra = 0; 
	wc.hInstance = hInstance; 
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 
	wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); 
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = NULL;       //no background required for gl
	wc.lpszClassName = szClassName; 
	wc.lpszMenuName = NULL; 

	if (!RegisterClassEx(&wc))
		return FALSE; 

	if (fullscreen)     //attempt full screen mode?
	{
		DEVMODE settings; 
		memset(&settings, 0, sizeof(settings));	  //make sure that memory is cleared
		settings.dmSize = sizeof(settings); 
		settings.dmPelsWidth = width; 
		settings.dmPelsHeight = height; 
		settings.dmBitsPerPel = bits; 
		settings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; 

		if (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
		{
			int i = MessageBox(NULL, "Requested fullscreen mode not available for your video card, use windowed mode instead?", "Error", MB_YESNO | MB_ICONEXCLAMATION); 
			
			if (i == IDYES)
				fullscreen = FALSE; 

			else
				return FALSE; 
		}

	}

	if (fullscreen)      //check again for fullscreen mode
	{
		ex_style = WS_EX_APPWINDOW; 
		style = WS_POPUP; 
		ShowCursor(FALSE);
	}

	else	           //no fullscreen mode
	{
		ex_style = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; 
		style = WS_OVERLAPPEDWINDOW; 
	}

	AdjustWindowRectEx(&window, style, FALSE, ex_style); 

	hWnd = CreateWindowEx(
		ex_style, 
		szClassName, 
		title, 
		style | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 
		0, 
		0, 
		window.right - window.left, 
		window.bottom - window.top, 
		NULL, 
		NULL, 
		hInstance, 
		NULL); 

	if (!hWnd)
	{
		KillGLWindow(); 
		return FALSE; 
	}

	//set up a pixel format
	static PIXELFORMATDESCRIPTOR pixel = 
	{
		sizeof(PIXELFORMATDESCRIPTOR), 
		1, 
		PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 
		PFD_TYPE_RGBA, 
		bits, 
		0, 0, 0, 0, 0, 0, 
		0, 
		0, 
		0, 
		0, 0, 0, 0, 
		16, 
		0, 
		0, 
		PFD_MAIN_PLANE, 
		0, 
		0, 0, 0
	}; 

	if (!(hDC = GetDC(hWnd)))    //did we get a device context? 
	{
		KillGLWindow(); 
		return FALSE; 
	}

	if (!(pixel_format = ChoosePixelFormat(hDC, &pixel)))  //did windows find a matching pixel format? 
	{
		KillGLWindow(); 
		return FALSE; 
	}

	if (!SetPixelFormat(hDC, pixel_format, &pixel))   //are we able to set the pixel format? 
	{
		KillGLWindow(); 
		return FALSE; 
	}

	if (!(hRC = wglCreateContext(hDC)))   //are we able to get a rendering context? 
	{
		KillGLWindow(); 
		return FALSE; 
	}

	if (!wglMakeCurrent(hDC, hRC))   //are we able to activate the rendering context? 
	{
		KillGLWindow(); 
		return FALSE; 
	}

	ShowWindow(hWnd, SW_SHOW);    //show the window
	SetForegroundWindow(hWnd);    //higher priority
	SetFocus(hWnd);               //set keyboard focus to window
	ResizeGLScene(width, height); //resize gl scene

	if (!CreateGL())        //create our new gl window
	{
		KillGLWindow(); 
		return FALSE; 
	}

	return TRUE; 
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_ACTIVATE:
		{
			if (!HIWORD(wParam))   //check if program is active
				active = TRUE; 		
			else
				active = FALSE; 

			break; 
		}

	case WM_SYSCOMMAND:         //intercept system commands
		{
			switch (wParam)
			{
			case SC_SCREENSAVE:
			case SC_MONITORPOWER:
				return 0;         //prevent from happening
			}

			break;
		}

	case WM_CLOSE:
		PostQuitMessage(0); 
		return 0; 

	case WM_KEYDOWN:
		keys[wParam] = TRUE; 
		break; 

	case WM_KEYUP:
		keys[wParam] = FALSE; 
		break; 

	case WM_SIZE:       //window resized? 
		ResizeGLScene(LOWORD(lParam), HIWORD(lParam)); 
		break; 
	}

	return DefWindowProc(hwnd, msg, wParam, lParam); 
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
{
	MSG msg; 

	int i = MessageBox(NULL, "Run in fullscreen mode?", "Start Fullscreen?", MB_YESNO | MB_ICONQUESTION); 

	if (i == IDNO)
		fullscreen = FALSE; 

	//create the opengl window
	if (!CreateGLWindow("OpenGL", 640, 480, 16, fullscreen))
		return 1; 

	ZeroMemory(&msg, sizeof(msg)); 
	while (msg.message != WM_QUIT)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg); 
			DispatchMessage(&msg); 
		}

		else
		{
			if (active)      //only draw if window is active
			{
				DrawGLScene(); 
				SwapBuffers(hDC);
			}
		}

		//check for f1 key being pressed
		if (keys[VK_F1])
		{
			keys[VK_F1] = FALSE;   
			KillGLWindow(); 
			fullscreen = !fullscreen; 

			//Recreate the window
			if (!CreateGLWindow("OpenGL", 640, 480, 16, fullscreen))
				return 1; 
		}

		//escape from fullscreen mode
		if (fullscreen && keys[VK_ESCAPE])		//exit 
			break;        
			
	}

	KillGLWindow(); 
	return 0; 
}

This program works, the size of the polygons get bigger and bigger. However... whenever I use 1.0f for the glVertex3f function, the polygon gets so big, that it goes off the screen. When NeHe used 1.0f, it worked fine, but for me, I'm having problems, and I copied most of the code, and I don't see anything wrong with it either. So I have to use 0.4 in order to make it the right size. Also, whenever I use glTranslatef(0.0f, 0.0f, -6.0f), nothing shows, but when I take off the -6.0f, then I can see the polygons. Again, NeHe had no problems with this, but I do. What's wrong??? -How do I fix glTranslate? -And also please explain and tell me how to fix these problems, if you can. Thanks, -CppNet
MARS_999
MARS_999
Do NeHe's examples you download work? And you didn't alter them correct?
Brother Bob
Brother Bob
You have put the projection matrix on the modelview stack. So when calling the drawing function, you call glLoadIdentity and every previous matrix are undone. That includes the projection matrix, effectively leaving you with an identity projection matrix defining a view volume in the range [-1, 1] along all axes. Obviously, drawing something 6 units away with that view volume won't give you anything. Put the projection matrix on... the projection matrix stack.
CppNet
CppNet
Quote:
Original post by Brother Bob
You have put the projection matrix on the modelview stack. So when calling the drawing function, you call glLoadIdentity and every previous matrix are undone. That includes the projection matrix, effectively leaving you with an identity projection matrix defining a view volume in the range [-1, 1] along all axes. Obviously, drawing something 6 units away with that view volume won't give you anything. Put the projection matrix on... the projection matrix stack.


Ummm... and how would I do that?

Brother Bob
Brother Bob
Call gluPerspective when GL_PROJECTION is the active matrix mode, not when GL_MODELVIEW is active.
MARS_999
MARS_999
GLvoid ResizeGLScene(GLsizei width, GLsizei height){	if (height == 0)   //prevent divide by 0 errors		height = 1; 	glViewport(0, 0, width, height); 	glMatrixMode(GL_PROJECTION); 	glLoadIdentity(); 	gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 1.0f, 100.0f);	 	glMatrixMode(GL_MODELVIEW); 	glLoadIdentity(); }


There you go....

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.