#include #include //toto mozes mozna mat ako GL/gl.h keby daco //forward deklaracie LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); void EnableOpenGL(HWND hWnd, HDC * hDC, HGLRC * hRC); void DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC); //main funkcia int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow) { WNDCLASS wc; //window class HWND hWnd; //handle na window HDC hDC; //handle na device context HGLRC hRC; //handle na GL rendering context MSG msg; //WinApi je message based paradigma, troska sa zda byt za vlasy pritiahnuta, ale je to okej BOOL quit = FALSE; float theta = 0.0f; //premenna na zmenu stavu //zaregistrujeme window clasu wc.style = CS_OWNDC; wc.lpfnWndProc = WndProc; //window procedura, ktoru sme zadefinovali nizsie wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; //handle instancu programu, ktoru namapujeme na samotny window wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH ); wc.lpszMenuName = NULL; wc.lpszClassName = "OpenGL"; //class name windowu co spravime RegisterClass( &wc ); //zaregistrujeme na dalsie pouzivanie // vytvorime samotne okno hWnd = CreateWindow( "OpenGL", "Opengl is great but DirectX rocks!!!", //class name a window title v tomto poradi to je //definovane WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE, 0, 0, 256, 256, //sirka a vyska windowu tych 256, 256 NULL, NULL, hInstance, NULL ); //namapujeme OpenGL na okno a na render/device context EnableOpenGL( hWnd, &hDC, &hRC ); //tu prebieha hlavny uzol programu while ( !quit ) { //zistime, ci su nejake messages v message loope, ak su, tak handle them, if not tak vykreslujeme if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { //ak doslo quit message, tak vypne aplikaciu, ak nie, posunie message dalej if ( msg.message == WM_QUIT ) { quit = TRUE; } else { TranslateMessage( &msg ); DispatchMessage( &msg ); } } else { // //sem ide veskery rendrovaci loop, toto vsetko z else mozes aj vymazat ak chces //a nahradit vlastnym :) (az na glClearColor a glClear, tie treba hocijak...a SwapBuffers) // glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); //vymaz celeho framebufferu na nejaku solid farbu //vo formate RGBA...nemusi byt cierne, odporucam //vyskusat aj cornflower blue na debugovacie ucely //R: 0.258824f G: 0.258824f B: 0.435294f A: 1.0f glClear( GL_COLOR_BUFFER_BIT ); //vymazeme color buffer (cize vsetko co sme nakreslili vo frame //neskor sa ti tu objavia aj ine parametre ako depth a stencil buffer //az budes robit normal a shadow mapping glPushMatrix(); //ulozime stav projekcnej matice glRotatef( theta, 0.0f, 0.0f, 1.0f ); //pootocime po X ovej osi o theta obrazec glBegin( GL_TRIANGLES ); //tymto prikazom povies OpenGL ze chces zacat vykreslovanie { //trojuholnikov...existuje viacero typov, ako GL_LINES alebo //GL_POINTS alebo GL_TRIANDGLE_STRIP/GL_TRIANGLE_FAN //ale v ziadnom pripade nepouzi GL_QUAD...je to uz deprecated davno glColor3f( 1.0f, 0.0f, 0.0f ); //v OpenGL nastavujes vzdy dany stav, nez sa to vykona //cize tu mas nastavenu farbu pre dany vertex, ak robis //per vertex lighting ako v tomto pripade glVertex2f( 0.0f, 1.0f ); //tu si das vykreslit dany vertex s poziciami udanymi X a Y glColor3f( 0.0f, 1.0f, 0.0f ); glVertex2f( 0.87f, -0.5f ); glColor3f( 0.0f, 0.0f, 1.0f ); glVertex2f( -0.87f, -0.5f ); } glEnd(); //touto funkciou povies OpenGL ze si dokoncila vykreslovanie pre dany utvar glPopMatrix(); //obnovis stav projekcnej matice SwapBuffers( hDC ); //zamenis frontbuffer za backbuffer, kde sa ti zatial vsetko vykreslilo v pozadi theta += 1.0f; //inkrementujes tetu :D } } //vycistis OpenGL a vypnes DisableOpenGL( hWnd, hDC, hRC ); //explicitne zavres okno DestroyWindow( hWnd ); return msg.wParam; } //window procedura LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: return 0; case WM_CLOSE: PostQuitMessage( 0 ); return 0; case WM_DESTROY: return 0; case WM_KEYDOWN: switch ( wParam ) { //tu mozes definovat vstupy z klavesnice, napr VK_ENTER tusim na stlacenie entra case VK_ESCAPE: PostQuitMessage(0); //tu sa posle message na vypnutie okna return 0; } return 0; default: return DefWindowProc( hWnd, message, wParam, lParam ); } } //funkcia na nastavenie opengl void EnableOpenGL(HWND hWnd, HDC * hDC, HGLRC * hRC) { PIXELFORMATDESCRIPTOR pfd; //pixel format descriptor nam udava hlbku farieb a udava paletu int format; //ziskame device context z handlu na window *hDC = GetDC( hWnd ); //tu sa nastavuje pixel format pre OpenGL ZeroMemory( &pfd, sizeof( pfd ) ); pfd.nSize = sizeof( pfd ); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; //doublebuffered pre znizenie flickeringu //support pre opengl //support pre priame kreslenie na window pfd.iPixelType = PFD_TYPE_RGBA; //RGBA format farby, tusim tu si mozes dat aj ARGB32 a ine formaty, ako HSV a tak pfd.cColorBits = 24; //kolko bitov chces na uchovavanie farieb...24 bity mas dost na zopar milionov farieb pfd.cDepthBits = 16; //hlbka farby v bitoch per pixel pfd.iLayerType = PFD_MAIN_PLANE; //netusim popravde co to robi, ale treba to format = ChoosePixelFormat( *hDC, &pfd ); //tu nam priradi system potrebny pixel format SetPixelFormat( *hDC, format, &pfd ); //ktory potom nastavime na ten window *hRC = wglCreateContext( *hDC ); //tu sa nam vytvori render context wglMakeCurrent( *hDC, *hRC ); //ktory hned priradime a zapneme } //Funkcia na uvolnenie contextu, a vypnutie okna void DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC) { wglMakeCurrent( NULL, NULL ); wglDeleteContext( hRC ); ReleaseDC( hWnd, hDC ); }