LONG WINAPI ScreenSaverProc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam){ // Handles screen saver messages switch(message) { case WM_CREATE: // Creation of the screen saver window hWnd = hwnd; SetupOpenGL(); // Set Timer (Target 60 fps ish (1000/60 = 16) uTimer = SetTimer(hwnd, 1, 16, NULL); return 0; case WM_ERASEBKGND: // Erases the screen saver background // Not needed with OpenGL return 0; case WM_TIMER: // Handles the timer DrawGLScene(); return 0; case WM_DESTROY: // Cleans up the screen saver window KillTimer(hwnd, uTimer); KillGL(); PostQuitMessage(0); return 0; } return DefScreenSaverProc(hwnd,message,wparam,lparam); }
bool VideoOutputOpenGL::Init(int width, int height, float aspect, WId winid, const QRect &win_rect, MythCodecID codec_id) { QMutexLocker locker(&gl_context_lock); bool success = true; // FIXME Mac OS X overlay does not work with preview window.SetAllowPreviewEPG(true); gl_parent_win = winid; VideoOutput::Init(width, height, aspect, winid, win_rect, codec_id); SetProfile(); InitPictureAttributes(); success &= SetupContext(); InitDisplayMeasurements(width, height, false); success &= CreateBuffers(); success &= CreatePauseFrame(); success &= SetupOpenGL(); InitOSD(); MoveResize(); if (!success) TearDown(); return success; }
// Initializes the graphics system void _Graphics::Init(const _WindowSettings &WindowSettings) { this->WindowSize = WindowSettings.Size; this->Anisotropy = 0; FramesPerSecond = 0; FrameCount = 0; FrameRateTimer = 0; Context = 0; Window = 0; Enabled = true; DirtyState(); // Set root element Element = new _Element(); Element->Visible = true; Element->Size = WindowSize; Element->CalculateBounds(); // Set video flags Uint32 VideoFlags = SDL_WINDOW_OPENGL; if(WindowSettings.Fullscreen) VideoFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP; // Set opengl attributes SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); // Set video mode Window = SDL_CreateWindow(WindowSettings.WindowTitle.c_str(), WindowSettings.Position.x, WindowSettings.Position.y, WindowSettings.Size.x, WindowSettings.Size.y, VideoFlags); if(Window == nullptr) throw std::runtime_error("SDL_CreateWindow failed"); // Set up opengl context Context = SDL_GL_CreateContext(Window); if(Context == nullptr) throw std::runtime_error("SDL_GL_CreateContext failed"); InitGLFunctions(); int MajorVersion, MinorVersion; SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &MajorVersion); SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &MinorVersion); // Set vsync SDL_GL_SetSwapInterval(WindowSettings.Vsync); // Set up OpenGL SetupOpenGL(); // Setup viewport ChangeViewport(WindowSize); png_init(0, 0); }
ERRCODE CRenderer::Initialize() { ERRCODE er; if(!(er = SetupWindow())) { if(!(er = SetupOpenGL())) { ready = true; if(separateThread) this->Go(); } } return er; }
//********************************************************************************* // Application initialization // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { g_hAppInstance = hInstance; //--- Create window g_hAppWnd = CreateWindow(WDCLASS_NAME, "3D scene renderer", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, g_hAppInstance, NULL); if (!g_hAppWnd) return(FALSE); SetupOpenGL(); //--- Display window ShowWindow(g_hAppWnd, nCmdShow); UpdateWindow(g_hAppWnd); return(TRUE); }
bool VideoOutputOpenGL::CreateVideoResources(void) { bool result = SetupOpenGL(); MoveResize(); return result; }
LRESULT WINAPI vmdWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; /* Paint structure. */ // XXX this enum has to be replicated here since its otherwise // private to the DisplayDevice class and children. enum EventCodes { WIN_REDRAW, WIN_LEFT, WIN_MIDDLE, WIN_RIGHT, WIN_WHEELUP, WIN_WHEELDOWN, WIN_MOUSEX, WIN_MOUSEY, WIN_KBD, WIN_KBD_ESCAPE, WIN_KBD_UP, WIN_KBD_DOWN, WIN_KBD_LEFT, WIN_KBD_RIGHT, WIN_KBD_PAGE_UP, WIN_KBD_PAGE_DOWN, WIN_KBD_HOME, WIN_KBD_END, WIN_KBD_INSERT, WIN_KBD_DELETE, WIN_KBD_F1, WIN_KBD_F2, WIN_KBD_F3, WIN_KBD_F4, WIN_KBD_F5, WIN_KBD_F6, WIN_KBD_F7, WIN_KBD_F8, WIN_KBD_F9, WIN_KBD_F10, WIN_KBD_F11, WIN_KBD_F12, WIN_NOEVENT }; wgldata *glwsrv; OpenGLDisplayDevice * ogldispdev; // Upon first window creation, immediately set our user-data field // to store caller-provided handles for this window instance if (msg == WM_NCCREATE) { #if defined(_M_X64) || defined(_WIN64) || defined(_Wp64) SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) (((CREATESTRUCT *) lParam)->lpCreateParams)); #else SetWindowLong(hwnd, GWL_USERDATA, (LONG) (((CREATESTRUCT *) lParam)->lpCreateParams)); #endif } // check to make sure we have a valid window data structure in case // it is destroyed while there are still pending messages... #if defined(_M_X64) || defined(_WIN64) || defined(_Wp64) ogldispdev = (OpenGLDisplayDevice *) GetWindowLongPtr(hwnd, GWLP_USERDATA); #else ogldispdev = (OpenGLDisplayDevice *) GetWindowLong(hwnd, GWL_USERDATA); #endif // when VMD destroys its window data structures it is possible that // the window could still get messages briefly thereafter, this prevents // us from attempting to handle any messages when the VMD state that goes // with the window has already been destructed. (most notably when using // the spaceball..) If we have a NULL pointer, let windows handle the // event for us using the default window proc. if (ogldispdev == NULL) return DefWindowProc(hwnd, msg, wParam, lParam); glwsrv = &ogldispdev->glwsrv; #ifdef VMDSPACEWARE // see if it is a spaceball event, if so do something about it. if (vmd_processwin32spaceballevent(glwsrv, msg, wParam, lParam)) return 0; // #endif switch(msg) { case WM_CREATE: glwsrv->hWnd = hwnd; glwsrv->hRC = SetupOpenGL(glwsrv); glwsrv->WEvents = WIN_REDRAW; return 0; case WM_SIZE: wglMakeCurrent(glwsrv->hDC, glwsrv->hRC); ogldispdev->xSize = LOWORD(lParam); ogldispdev->ySize = HIWORD(lParam); ogldispdev->reshape(); glViewport(0, 0, (GLsizei) ogldispdev->xSize, (GLsizei) ogldispdev->ySize); glwsrv->WEvents = WIN_REDRAW; return 0; case WM_SIZING: wglMakeCurrent(glwsrv->hDC, glwsrv->hRC); glClear(GL_COLOR_BUFFER_BIT); SwapBuffers(glwsrv->hDC); glDrawBuffer(GL_BACK); return 0; case WM_CLOSE: PostQuitMessage(0); return 0; case WM_PAINT: BeginPaint(hwnd, &ps); EndPaint(hwnd, &ps); glwsrv->WEvents = WIN_REDRAW; return 0; case WM_KEYDOWN: glwsrv->KeyFlag = MapVirtualKey((UINT) wParam, 2); // map to ASCII glwsrv->WEvents = WIN_KBD; if (glwsrv->KeyFlag == 0) { unsigned int keysym = wParam; switch (keysym) { case VK_ESCAPE: glwsrv->WEvents = WIN_KBD_ESCAPE; break; case VK_UP: glwsrv->WEvents = WIN_KBD_UP; break; case VK_DOWN: glwsrv->WEvents = WIN_KBD_DOWN; break; case VK_LEFT: glwsrv->WEvents = WIN_KBD_LEFT; break; case VK_RIGHT: glwsrv->WEvents = WIN_KBD_RIGHT; break; case VK_PRIOR: glwsrv->WEvents = WIN_KBD_PAGE_UP; break; case VK_NEXT: glwsrv->WEvents = WIN_KBD_PAGE_DOWN; break; case VK_HOME: glwsrv->WEvents = WIN_KBD_HOME; break; case VK_END: glwsrv->WEvents = WIN_KBD_END; break; case VK_INSERT: glwsrv->WEvents = WIN_KBD_INSERT; break; case VK_DELETE: glwsrv->WEvents = WIN_KBD_DELETE; break; case VK_F1: glwsrv->WEvents = WIN_KBD_F1; break; case VK_F2: glwsrv->WEvents = WIN_KBD_F2; break; case VK_F3: glwsrv->WEvents = WIN_KBD_F3; break; case VK_F4: glwsrv->WEvents = WIN_KBD_F4; break; case VK_F5: glwsrv->WEvents = WIN_KBD_F5; break; case VK_F6: glwsrv->WEvents = WIN_KBD_F6; break; case VK_F7: glwsrv->WEvents = WIN_KBD_F7; break; case VK_F8: glwsrv->WEvents = WIN_KBD_F8; break; case VK_F9: glwsrv->WEvents = WIN_KBD_F9; break; case VK_F10: glwsrv->WEvents = WIN_KBD_F10; break; case VK_F11: glwsrv->WEvents = WIN_KBD_F11; break; case VK_F12: glwsrv->WEvents = WIN_KBD_F12; break; default: glwsrv->WEvents = WIN_NOEVENT; break; } } return 0; case WM_MOUSEMOVE: vmd_transwin32mouse(ogldispdev, lParam); glwsrv->MouseFlags = (long) wParam; return 0; case WM_MOUSEWHEEL: { int zDelta = ((short) HIWORD(wParam)); // XXX // zDelta is in positive or negative multiples of WHEEL_DELTA for // clicky type scroll wheels on existing mice, may need to // recode this for continuous wheels at some future point in time. // WHEEL_DELTA is 120 in current versions of Windows. // We only activate an event if the user moves the mouse wheel at // least half of WHEEL_DELTA, so that they don't do it by accident // all the time. if (zDelta > (WHEEL_DELTA / 2)) { glwsrv->WEvents = WIN_WHEELUP; } else if (zDelta < -(WHEEL_DELTA / 2)) { glwsrv->WEvents = WIN_WHEELDOWN; } } return 0; case WM_LBUTTONDOWN: SetCapture(hwnd); vmd_transwin32mouse(ogldispdev, lParam); glwsrv->MouseFlags = (long) wParam; glwsrv->WEvents = WIN_LEFT; return 0; case WM_LBUTTONUP: vmd_transwin32mouse(ogldispdev, lParam); glwsrv->MouseFlags = (long) wParam; glwsrv->WEvents = WIN_LEFT; if (!(glwsrv->MouseFlags & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON))) ReleaseCapture(); return 0; case WM_MBUTTONDOWN: SetCapture(hwnd); vmd_transwin32mouse(ogldispdev, lParam); glwsrv->MouseFlags = (long) wParam; glwsrv->WEvents = WIN_MIDDLE; return 0; case WM_MBUTTONUP: vmd_transwin32mouse(ogldispdev, lParam); glwsrv->MouseFlags = (long) wParam; glwsrv->WEvents = WIN_MIDDLE; if (!(glwsrv->MouseFlags & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON))) ReleaseCapture(); return 0; case WM_RBUTTONDOWN: SetCapture(hwnd); vmd_transwin32mouse(ogldispdev, lParam); glwsrv->MouseFlags = (long) wParam; glwsrv->WEvents = WIN_RIGHT; return 0; case WM_RBUTTONUP: vmd_transwin32mouse(ogldispdev, lParam); glwsrv->MouseFlags = (long) wParam; glwsrv->WEvents = WIN_RIGHT; if (!(glwsrv->MouseFlags & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON))) ReleaseCapture(); return 0; case WM_SETCURSOR: // We process the mouse cursor hit test codes here, they tell us // what part of the window we're over, which helps us set the cursor // to the correct style for sizing borders, moves, etc. switch (LOWORD(lParam)) { case HTBOTTOM: case HTTOP: SetCursor(LoadCursor(NULL, IDC_SIZENS)); break; case HTLEFT: case HTRIGHT: SetCursor(LoadCursor(NULL, IDC_SIZEWE)); break; case HTTOPRIGHT: case HTBOTTOMLEFT: SetCursor(LoadCursor(NULL, IDC_SIZENESW)); break; case HTTOPLEFT: case HTBOTTOMRIGHT: SetCursor(LoadCursor(NULL, IDC_SIZENWSE)); break; case HTCAPTION: SetCursor(LoadCursor(NULL, IDC_ARROW)); break; case HTCLIENT: default: ogldispdev->set_cursor(glwsrv->cursornum); } return 0; // // Handle Windows File Drag and Drop Operations // This code needs to be linked against SHELL32.DLL // case WM_DROPFILES: { char lpszFile[4096]; UINT numfiles, fileindex, numc; HDROP hDropInfo = (HDROP)wParam; // Get the number of simultaneous dragged/dropped files. numfiles = DragQueryFile(hDropInfo, (DWORD)(-1), (LPSTR)NULL, 0); msgInfo << "Ignoring Drag and Drop operation, received " << ((int) numfiles) << " files:" << sendmsg; FileSpec spec; for (fileindex=0; fileindex<numfiles; fileindex++) { // lpszFile: complete pathname with device, colon and backslashes numc = DragQueryFile(hDropInfo, fileindex, (char *) &lpszFile, 4096); // VMD loads the file(s) here, or queues them up in its own // list to decide how to cope with them. Deciding how to deal // with these files is definitely the tricky part. msgInfo << " File(" << ((int) fileindex) << "): " << lpszFile << " (numc=" << ((int) numc) << ")" << sendmsg; // attempt to load the file into a new molecule ogldispdev->vmdapp->molecule_load(-1, lpszFile, NULL, &spec); } DragFinish(hDropInfo); // finish drop operation and release memory } return 0; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; }
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wcex; HWND hwnd; // HDC hDC; HGLRC hRC; MSG msg; BOOL bQuit = FALSE; /* register window class */ wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = 0; // CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wcex.lpfnWndProc = WindowProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wcex.lpszMenuName = NULL; wcex.lpszClassName = "CubeSolver"; wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);; if (!RegisterClassEx(&wcex)) return 0; /* create main window */ hwnd = CreateWindowEx(0, "CubeSolver", "CubeSolver", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, window_width, window_height, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, nCmdShow); /* enable OpenGL for the window */ EnableOpenGL(hwnd, &hDC, &hRC); SetupOpenGL(); /* program main loop */ while (!bQuit) { /* check for messages */ if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { /* handle or dispatch messages */ if (msg.message == WM_QUIT) { bQuit = TRUE; } else { TranslateMessage(&msg); DispatchMessage(&msg); } } else { /* OpenGL animation code goes here */ gCube.tick(0.01); Render(); Sleep (1); } } /* shutdown OpenGL */ DisableOpenGL(hwnd, hDC, hRC); /* destroy the window explicitly */ DestroyWindow(hwnd); return msg.wParam; }
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_SYSCOMMAND: { switch (wParam) { case SC_SCREENSAVE: case SC_MONITORPOWER: //return 0; // Prevent From Happening ; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } break; } case WM_SIZE: window_width = LOWORD(lParam); window_height = HIWORD(lParam); SetupOpenGL(); break; case WM_PAINT: { PAINTSTRUCT ps; BeginPaint(hwnd, &ps); EndPaint(hwnd, &ps); Render(); break; } case WM_CLOSE: PostQuitMessage(0); break; case WM_DESTROY: return 0; case WM_KEYDOWN: { switch (wParam) { case 'Q': gCube.move("Fc'"); break; case 'W': gCube.move("B"); break; case 'E': gCube.move("L'"); break; case 'R': gCube.move("l'"); break; case 'T': gCube.move("Lc'"); break; case 'A': gCube.move("Uc'"); break; case 'S': gCube.move("D"); break; case 'D': gCube.move("L"); break; case 'F': gCube.move("U'"); break; case 'G': gCube.move("F'"); break; case 'V': gCube.move("l"); break; case 'B': gCube.move("Lc"); break; case 'P': gCube.move("Fc"); break; case 'O': gCube.move("B'"); break; case 'I': gCube.move("R"); break; case 'U': gCube.move("r"); break; case 'Y': gCube.move("Rc"); break; case 192: gCube.move("Uc"); break; case 'L': gCube.move("D'"); break; case 'K': gCube.move("R'"); break; case 'J': gCube.move("U"); break; case 'H': gCube.move("F"); break; case 'M': gCube.move("r'"); break; case 'N': gCube.move("Rc'"); break; case VK_LEFT: gCube.move("Uc"); break; case VK_RIGHT: gCube.move("Uc'"); break; case VK_UP: gCube.move("Rc"); break; case VK_DOWN: gCube.move("Rc'"); break; case VK_SPACE: gCube.randomize(); break; case VK_END: //gCube.setFaces("BLBBUDFBFRLDRRBDRRLDDLFFURFRULUDDLDBDUUBLFUFFLURRBLUFB"); //gCube.setFaces("LUDRUDFBRULLRRBFBBUDBFFFLUUFFLDDURDRBURLLLFRDBLURBBDFD"); gCube.setFaces("BDFBULRDFDDUFRBULDUFLLFRUFBRULUDURUBLDBBLFFBFLRDRBLRRD"); break; case VK_HOME: //gCube.move("F L F U' R U F2 L2 U' L' B D' B' L2 U"); // Cube in cube gCube.move("F U F2 D B U R F L D R U L U B D2 R F U2 D2"); // 20 face turns break; case VK_RETURN: // Solve the cube gCube.solve(); break; case VK_BACK: gCube.clean(); break; case VK_ESCAPE: PostQuitMessage(0); break; default: printf("Unknown vkey: %d\n", wParam); fflush(stdout); } } break; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } return 0; }
int main() { SetupOpenGL(); std::unique_ptr<btBroadphaseInterface> broadphase { new btDbvtBroadphase }; std::unique_ptr<btDefaultCollisionConfiguration> collisionConfiguration { new btDefaultCollisionConfiguration }; std::unique_ptr<btCollisionDispatcher> dispatcher { new btCollisionDispatcher { collisionConfiguration.get() } }; std::unique_ptr<btSequentialImpulseConstraintSolver> solver { new btSequentialImpulseConstraintSolver }; std::unique_ptr<btDiscreteDynamicsWorld> dynamicsWorld { new btDiscreteDynamicsWorld { dispatcher.get(), broadphase.get(), solver.get(), collisionConfiguration.get() } }; dynamicsWorld->setGravity(btVector3 { 0, -10, 0 }); std::unique_ptr<btCollisionShape> groundShape { new btStaticPlaneShape { btVector3 { 0, 1, 0 }, 1 } }; std::unique_ptr<btSphereShape> fallShape { new btSphereShape { 1 } }; std::unique_ptr<btDefaultMotionState> groundMotionState { new btDefaultMotionState { btTransform { btQuaternion { 0, 0, 0, 1 }, btVector3 { 0, -1, 0 } } } }; btRigidBody::btRigidBodyConstructionInfo groundRigidBodyConstructionInfo { 0, groundMotionState.get(), groundShape.get(), btVector3 { 0, 0, 0 } }; std::unique_ptr<btRigidBody> groundRigidBody { new btRigidBody { groundRigidBodyConstructionInfo } }; dynamicsWorld->addRigidBody(groundRigidBody.get()); std::unique_ptr<btDefaultMotionState> fallMotionState { new btDefaultMotionState { btTransform { btQuaternion { 0, 0, 0, 1 }, btVector3 { 0, 50, 0 } } } }; btScalar mass { 1 }; btVector3 fallInertia { 0, 0, 0 }; fallShape->calculateLocalInertia(mass, fallInertia); btRigidBody::btRigidBodyConstructionInfo fallRigidBodyConstructionInfo { mass, fallMotionState.get(), fallShape.get(), fallInertia }; std::unique_ptr<btRigidBody> fallRigidBody { new btRigidBody { fallRigidBodyConstructionInfo } }; dynamicsWorld->addRigidBody(fallRigidBody.get()); glm::mat4 projectionMatrix = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f); glm::mat4 viewMatrix; glm::mat4 modelMatrix; glm::mat4 mvp; glm::vec3 lightPosition { 3, 3, 3 }; glm::vec3 lightColor { 1, 1, 1 }; float lightPower { 50.0f }; btTransform transformation; double currentTime, lastTime = glfwGetTime(); double fps { 0.0 }; size_t nFrames { 0l }; do { dynamicsWorld->stepSimulation(1 / 60.0f, 10); fallRigidBody->getMotionState()->getWorldTransform(transformation); ProcessInputs(); modelMatrix = glm::translate(glm::mat4 { 1.0f }, glm::vec3 { transformation.getOrigin().getX(), transformation.getOrigin().getY(), transformation.getOrigin().getZ() }); viewMatrix = glm::lookAt( s_position, s_position + s_direction, s_up ); mvp = projectionMatrix * viewMatrix * modelMatrix; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(s_programId); glUniformMatrix4fv(s_mvpMatrixId, 1, GL_FALSE, &mvp[0][0]); glUniformMatrix4fv(s_modelMatrixId, 1, GL_FALSE, &modelMatrix[0][0]); glUniformMatrix4fv(s_viewMatrixId, 1, GL_FALSE, &viewMatrix[0][0]); glUniform3f(s_lightPositionId, lightPosition.x, lightPosition.y, lightPosition.z); glUniform3f(s_lightColorId, lightColor.x, lightColor.y, lightColor.z); glUniform1f(s_lightPowerId, lightPower); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, s_textureId); glUniform1i(s_uniformTextureId, 0); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, s_vertexBufferId); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, s_uvCoordBufferId); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, nullptr); glEnableVertexAttribArray(2); glBindBuffer(GL_ARRAY_BUFFER, s_normalBufferId); glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glDrawArrays(GL_TRIANGLES, 0, s_model.vertices().size()); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glDisableVertexAttribArray(2); currentTime = glfwGetTime(); ++nFrames; if (currentTime - lastTime > 1.0) { fps = 1000.0/nFrames; nFrames = 0; lastTime += 1.0; } ShowStatus(transformation.getOrigin().getY(), fps); glfwSwapBuffers(s_window); glfwPollEvents(); } while (glfwGetKey(s_window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwGetKey(s_window, GLFW_KEY_Q) != GLFW_PRESS && glfwWindowShouldClose(s_window) == 0); dynamicsWorld->removeRigidBody(fallRigidBody.get()); dynamicsWorld->removeRigidBody(groundRigidBody.get()); CleanupOpenGL(); return 0; }