[C++ OpenGL] Problem z


(Kamilinformatyka) #1

Witam.

Zacząłem swoją przygodę z OpenGL, ale niestety przepisując kod z ksiązki napodkałem problem:

#define WIN32_LEAN_AND_MEAN

#include 

#include 

#include 

#include 


float angel = 0.0f;

HDC g_HDC;


void SetupPixelFormat(HDC hDC)

{

	int nPixelFormat;

	static PIXELFORMATDESCRIPTOR pfd = 

	{

		sizeof(PIXELFORMATDESCRIPTOR),

		1,

		PFD_DRAW_TO_WINDOW |

		PFD_SUPPORT_OPENGL |

		PFD_DOUBLEBUFFER,

		PFD_TYPE_RGBA,

		32,

		0, 0, 0, 0, 0, 0,

		0,

		0,

		0,

		0, 0, 0, 0,

		16,

		0,

		0,

		PFD_MAIN_PLANE,

		0,

		0, 0, 0  

		};

	nPixelFormat = ChoosePixelFormat(hDC, &pfd);

	SetPixelFormat(hDC, nPixelFormat, &pfd);

}


LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

{

	static HGLRC hRC;

	static HDC hDC;

	int width, height;


	switch(message)

	{

		case WM_CREATE:

			hDC= GetDC(hwnd);

			g_HDC = hDC;

			SetupPixelFormat(hDC);

			hRC = wglCreateContext(hDC);

			wglMakeCurrent(hDC, hRC);

			return 0;

			break;

		case WM_CLOSE:

			wglMakeCurrent(hDC, NULL);

			wglDeleteContext(hRC);

			PostQuitMessage(0);

			return 0;

			break;

		case WM_SIZE:

			height = HIWORD(lParam);

			width = LOWORD(lParam);

			if(height==0) height=1;

			glViewport(0, 0, width, height);

			glMatrixMode(GL_PROJECTION);

			glLoadIdentity();

			return 0;

			break;

		}

		return (DefWindowProc(hwnd, message, wParam, lParam));

}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine)

{

	WNDCLASSEX windowClass;

	HWND hwnd;

	MSG msg;

	bool done;


	windowClass.cbSize = sizeof(WNDCLASSEX);

	windowClass.style = CS_HREDRAW | CS_VREDRAW;

	windowClass.lpfnWndProc = WndProc;

	windowClass.cbClsExtra = 0;

	windowClass.cbWndExtra = 0;

	windowClass.hInstance=hInstance;

	windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);

	windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);

	windowClass.hbrBackground = NULL;

	windowClass.lpszMenuName = NULL;

	windowClass.lpszClassName = "MojaKlasa";

	windowClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);


	if(!RegisterClassEx(&windowClass)) return 0;


	hwnd = CreateWindowEx( NULL, "MojaKlasa", "Aplikacja OpenGL",

	WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_SYSMENU | WS_CLIPCHILDREN|

	WS_CLIPSIBLINGS,

	100, 400,

	400, 400,

	NULL,

	NULL,

	hInstance,

	NULL);


	if(!hwnd) return 0;


	ShowWindow(hwnd, SW_SHOW);

	UpdateWindow(hwnd);


	done = false;


	while (!done)

	{

		PeekMessage(&msg, hwnd, NULL, NULL, PM_REMOVE);


		if(msg.message == WM_QUIT)

		{

			done = true;

			}

		else

		{

			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

			glLoadIdentity();


			angel = angel + 0.1f;

			if (angel >= 360.0f)

				angel = 0.0f;

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

			glRotatef(angel, 0.0f, 0.0f, 1.0f);

			glColor3f(1.0f, 0.0f, 0.0f);

			glBegin(GL_TRIANGLES);

				glVertex3f(0.0f, 0.0f, 0.0f);

				glVertex3f(1.0f, 0.0f, 0.0f);

				glVertex3f(1.0f, 1.0f, 0.0f);

			glEnd();

			SwapBuffers(g_HDC);


			TranslateMessage(&msg);

			DispatchMessage(&msg);

			}

		}

	return msg.wParam;

}

czy mógłby mi ktoś pomóc?

Z góry dzięki :slight_smile:


(Rolek0) #2

Jaki problem?


(Kamilinformatyka) #3

Oj sorki zapomniałem :slight_smile:

In function `main': 

   [Linker error] C:\MinGW\msys\1.0\src\mingwrt/../mingw/main.c:73: undefined reference to `WinMain@16' 

   collect2: ld returned 1 exit status 

  C:\programowanie\trojkat\Makefile.win [Error] [Projekt1.exe] Error 1 (if this is the only error: please check your library includes)

(Rolek0) #4

Brakuje Ci czwartego argumentu w deklaracji funkcji WinMain, ma on być typu int, zwykle jest nazywany nCmdShow i w ramach przyzwoitości powinieneś go przekazywać do ShowWindow dla głównego okna zamiast na sztywno SW_SHOW.


(Kamilinformatyka) #5

Wiesz, przykład jest przepisany żywcem z książki.

Dodałem to int nCmdShow, okno się pokazuje ale nie ma tego co powinno być.


(Rolek0) #6

Na OpenGlu nie bardzo się znam, trochę czytałem, ale nie za dużo. Jeśli się uczysz OpenGla to mógłbym Ci polecić http://www.youtube.com/playlist?list=PLB54F0A8D6792DB82, a konkretnie http://www.youtube.com/watch?v=3QQZOtPK6j4, gdzie jest omówiony framework oparty o SDL+OpenGL, może coś Ci pomoże.

Przejrzałem trochę twój kod, brzydko piszesz :stuck_out_tongue:

Funkcja PeekMessage może, ale nie musi pobrać komunikatu, jeśli kolejka komunikatów jest pusta to zwróci FALSE, powinieneś wywoływać TranslateMessage i DispatchMessage tylko gdy PeekMessage zwróci TRUE (to tak w ogólności bo pętla komunikatów może występować w różnych wersjach i nie wszystkie komunikaty są kierowane do okien, część jest kierowana do samego wątku np. WM_QUIT).

Po za tym zaleca się obsłużenie wszystkich nadesłanych komunikatów przed robieniem czegoś czasochłonnego, np.

while(!done)

{

	while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))

	{

		if(msg.hwnd)

		{

			TranslateMessage(&msg);

			DispatchMessage(&msg);

		}

		else if(msg.message == WM_QUIT)

			done = true;

	}

	/*

	 * Tu renderujesz...

	 */

}

Większość funkcji WinAPI zwraca czy się powiodło czy nie, w OpenGL pewnie podobnie, możesz pododawać do kodu sprawdzanie czy wszystkie funkcje się powiodły, to może Cię nakierować gdzie jest błąd.

Huh, ale się rozpisałem :wink:

PS. Chcesz narysować aniołka(angel)? :wink:


(Kamilinformatyka) #7

Nie, to nie aniołem.

Jak już mówiłem zacząłem dopiero i jest to przykład w 100% z książki przepisany.