// // GLSAMPLE.CPP // by Blaine Hodge // // Includes #include <windows.h> #include <gl/glew.h> #include <gl/wglew.h> #include <time.h> unsigned int m_vaoID[2]; // two vertex array objects, one for each drawn object unsigned int m_vboID[3]; // three VBOs void init() { // First simple object float* vert = new float[9]; // vertex array float* col = new float[9]; // color array unsigned char* idx = new unsigned char[3]; // element index array vert[0] =-0.3f; vert[1] = 0.5f; vert[2] =-1.0f; vert[3] =-0.8f; vert[4] =-0.5f; vert[5] =-1.0f; vert[6] = 0.2f; vert[7] =-0.5f; vert[8]= -1.0f; col[0] = 1.0f; col[1] = 0.0f; col[2] = 0.0f; col[3] = 0.0f; col[4] = 1.0f; col[5] = 0.0f; col[6] = 0.0f; col[7] = 0.0f; col[8] = 1.0f; idx[0] = 0; idx[1] = 1; idx[2] = 2; // Second simple object float* vert2 = new float[9]; // vertex array vert2[0] =-0.2f; vert2[1] = 0.5f; vert2[2] =-1.0f; vert2[3] = 0.3f; vert2[4] =-0.5f; vert2[5] =-1.0f; vert2[6] = 0.8f; vert2[7] = 0.5f; vert2[8]= -1.0f; // Two VAOs allocation glGenVertexArrays(2, &m_vaoID[0]); // First VAO setup glBindVertexArray(m_vaoID[0]); glGenBuffers(2, m_vboID); glBindBuffer(GL_ARRAY_BUFFER, m_vboID[0]); glBufferData(GL_ARRAY_BUFFER, 9*sizeof(GLfloat), vert, GL_STATIC_DRAW); glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, m_vboID[1]); glBufferData(GL_ARRAY_BUFFER, 9*sizeof(GLfloat), col, GL_STATIC_DRAW); glVertexAttribPointer((GLuint)1, 3, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(1); // Second VAO setup glBindVertexArray(m_vaoID[1]); glGenBuffers(1, &m_vboID[2]); glBindBuffer(GL_ARRAY_BUFFER, m_vboID[2]); glBufferData(GL_ARRAY_BUFFER, 9*sizeof(GLfloat), vert2, GL_STATIC_DRAW); glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(0); glBindVertexArray(0); delete [] vert; delete [] vert2; delete [] col; delete [] idx; // TODO: prepare data/objects needed for rendering } void draw() { glBindVertexArray(m_vaoID[0]); // select first VAO glDrawElements(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, NULL); glDrawArrays(GL_TRIANGLES, 0, 3); // draw first object glBindVertexArray(m_vaoID[1]); // select second VAO glVertexAttrib3f((GLuint)1, 1.0, 0.0, 0.0); // set constant color attribute glDrawArrays(GL_TRIANGLES, 0, 3); // draw second object glBindVertexArray(0); // TODO: execute rendering commands } #pragma region Non-important stuff // Function Declarations 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); // We use console application type to be able to output debug info // and thus need main() function. This is simply a wrapper around // WinMain. int main() { return WinMain(GetModuleHandle(NULL), NULL, "", SW_SHOW); } // WinMain int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow) { WNDCLASS wc; HWND hWnd; HDC hDC; HGLRC hRC; MSG msg; BOOL quit = FALSE; // register window class wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon( NULL, IDI_APPLICATION ); wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH ); wc.lpszMenuName = NULL; wc.lpszClassName = TEXT("OpenGL 3.0 Strict Test"); RegisterClass( &wc ); // create main window hWnd = CreateWindow( TEXT("OpenGL 3.0 Strict Test"), TEXT("OpenGL 3.0 Strict Test"), WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE, 100, 100, 500, 500, NULL, NULL, hInstance, NULL ); // enable OpenGL for the window EnableOpenGL( hWnd, &hDC, &hRC ); // prepare rendering init(); // program main loop while ( !quit ) { // check for messages if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { // handle or dispatch messages if ( msg.message == WM_QUIT ) { quit = TRUE; } else { TranslateMessage( &msg ); DispatchMessage( &msg ); } } else { // OpenGL animation code goes here glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); glClear( GL_COLOR_BUFFER_BIT ); draw(); glFlush(); SwapBuffers( hDC ); } } // shutdown OpenGL DisableOpenGL( hWnd, hDC, hRC ); // destroy the window explicitly DestroyWindow( hWnd ); return msg.wParam; } // Window Procedure 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 ) { case VK_ESCAPE: PostQuitMessage(0); return 0; } return 0; default: return DefWindowProc( hWnd, message, wParam, lParam ); } } // Enable OpenGL void EnableOpenGL(HWND hWnd, HDC * hDC, HGLRC * hRC) { PIXELFORMATDESCRIPTOR pfd; int format; // get the device context (DC) *hDC = GetDC( hWnd ); // set the pixel format for the DC 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; format = ChoosePixelFormat( *hDC, &pfd ); SetPixelFormat( *hDC, format, &pfd ); // create forward-compatible OpenGL 3.3 context HGLRC tempContext = wglCreateContext(*hDC); wglMakeCurrent(*hDC, tempContext); int attribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, // we want a 3.3 context WGL_CONTEXT_MINOR_VERSION_ARB, 3, // and it shall be forward compatible so that we can only use up to date functionality WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, 0}; // zero indicates the end of the array wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) wglGetProcAddress("wglCreateContextAttribsARB"); if(wglCreateContextAttribsARB == NULL) //OpenGL 3.0 is not supported { MessageBox(NULL, TEXT("Cannot get procedure address for wglCreateContextAttribs."), TEXT("ERROR"), MB_OK | MB_ICONERROR); wglDeleteContext(tempContext); exit(-1); } if (!(*hRC = wglCreateContextAttribsARB(*hDC, 0, attribs))) { wglDeleteContext(tempContext); MessageBox(NULL, TEXT("Can not create OpenGL rendering context."), TEXT("ERROR"), MB_OK | MB_ICONERROR); exit(-1); } wglMakeCurrent(*hDC, *hRC); wglDeleteContext(tempContext); //glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) wglGetProcAddress("glGenVertexArrays"); //glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) wglGetProcAddress("glBindVertexArray"); //glGenBuffers = (PFNGLGENBUFFERSPROC) wglGetProcAddress("glGenBuffers"); //glBindBuffer = (PFNGLBINDBUFFERPROC) wglGetProcAddress("glBindBuffer"); //glBufferData = (PFNGLBUFFERDATAPROC) wglGetProcAddress("glBufferData"); //glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) wglGetProcAddress("glVertexAttribPointer"); //glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) wglGetProcAddress("glEnableVertexAttribArray"); //glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) wglGetProcAddress("glVertexAttrib3f"); glewInit(); } // Disable OpenGL void DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC) { wglMakeCurrent( NULL, NULL ); wglDeleteContext( hRC ); ReleaseDC( hWnd, hDC ); } #pragma endregion