int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { createWindow(hInstance); createGLContext(); imguiRenderGLInit("c:\\windows\\fonts\\calibri.ttf"); timeBeginPeriod(1); ShowWindow(hWnd, SW_SHOW); for (;;) { MSG msg; while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) return 0; TranslateMessage(&msg); DispatchMessage(&msg); } renderFrame(); } timeEndPeriod(1); }
void init_imgui() { if (!imguiRenderGLInit(DroidSans_ttf, DroidSans_ttf_len)) { fprintf(stderr, "Could not init GUI renderer.\n"); exit(EXIT_FAILURE); } }
void TextEngineRenderer::Create() { glClearColor(1.0, 1.0, 1.0, 1.0); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if (edit) { MaybeRebuildAttenuationShader(); } vertex_shader.Create(GL_VERTEX_SHADER, {kVertexShaderSource}); fragment_shader.Create(GL_FRAGMENT_SHADER, {kFragmentShaderSource}); face_program.Create({&vertex_shader, &fragment_shader}); face_program.CompileAndLink(); vertex_format.Create({ {u8"vertex_position", GL_FLOAT, 2} }); unit_circle.data.insert(unit_circle.data.cend(), { 0.0f, 0.0f }); for (auto i = 0.0f; i < 101.0f; ++i) { const auto theta = 2.0f * i / 100.0f * M_PI; const auto point = glm::vec2(glm::cos(theta), glm::sin(theta)); unit_circle.data.insert(unit_circle.data.cend(), { point.x, point.y }); } unit_circle.element_count = 102; unit_circle.element_type = GL_TRIANGLE_FAN; unit_square.data.insert(unit_square.data.cend(), { 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f, 0.5f }); unit_square.element_count = 4; unit_square.element_type = GL_TRIANGLE_STRIP; circle_buffer.Create(GL_ARRAY_BUFFER); circle_buffer.Data(unit_circle.data_size(), unit_circle.data.data(), GL_STATIC_DRAW); circle_array.Create(); vertex_format.Apply(circle_array, face_program); CHECK_STATE(!glGetError()); rectangle_buffer.Create(GL_ARRAY_BUFFER); rectangle_buffer.Data(unit_square.data_size(), unit_square.data.data(), GL_STATIC_DRAW); rectangle_array.Create(); vertex_format.Apply(rectangle_array, face_program); CHECK_STATE(!glGetError()); stroke_width = 0.0025f; stroke = glm::vec4(0, 0, 0, 1); fill = glm::vec4(0.5, 0.5, 0.5, 1); CHECK_STATE(imguiRenderGLInit("../resource/fonts/ubuntu-font-family-0.80/Ubuntu-R.ttf")); }
static void sCreateUI() { ui.showMenu = true; ui.scroll = 0; ui.scrollarea1 = 0; ui.chooseTest = false; ui.mouseOverMenu = false; // Init UI if (!imguiRenderGLInit("DroidSans.ttf")) { fprintf(stderr, "Could not init GUI renderer.\n"); assert(false); return; } }
int main(int /*argc*/, char** /*argv*/) { // Init SDL if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { printf("Could not initialise SDL\n"); return -1; } // Center window char env[] = "SDL_VIDEO_CENTERED=1"; putenv(env); // Init OpenGL SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); //#ifndef WIN32 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); //#endif const SDL_VideoInfo* vi = SDL_GetVideoInfo(); bool presentationMode = false; int width, height; SDL_Surface* screen = 0; if (presentationMode) { width = 1700; height = 1000; screen = SDL_SetVideoMode(width, height, 0, SDL_OPENGL|SDL_FULLSCREEN); } else { width = 1700; height = 1000; screen = SDL_SetVideoMode(width, height, 0, SDL_OPENGL); } if (!screen) { printf("Could not initialise SDL opengl\n"); return -1; } glEnable(GL_MULTISAMPLE); SDL_WM_SetCaption("Recast Demo", 0); if (!imguiRenderGLInit("DroidSans.ttf")) { printf("Could not init GUI renderer.\n"); SDL_Quit(); return -1; } float t = 0.0f; float timeAcc = 0.0f; Uint32 lastTime = SDL_GetTicks(); int mx = 0, my = 0; float rx = 45; float ry = -45; float moveW = 0, moveS = 0, moveA = 0, moveD = 0; float camx = 0, camy = 0, camz = 0, camr = 1000; float origrx = 0, origry = 0; int origx = 0, origy = 0; float scrollZoom = 0; bool rotate = false; bool movedDuringRotate = false; float rays[3], raye[3]; bool mouseOverMenu = false; bool showMenu = !presentationMode; bool showLog = false; bool showTools = true; bool showLevels = false; bool showSample = false; bool showTestCases = false; int propScroll = 0; int logScroll = 0; int toolsScroll = 0; char sampleName[64] = "Choose Sample..."; FileList files; char meshName[128] = "Choose Mesh..."; float mpos[3] = {0,0,0}; bool mposSet = false; SlideShow slideShow; slideShow.init("slides/"); InputGeom* geom = 0; Sample* sample = 0; TestCase* test = 0; BuildContext ctx; glEnable(GL_CULL_FACE); float fogCol[4] = { 0.32f, 0.31f, 0.30f, 1.0f }; glEnable(GL_FOG); glFogi(GL_FOG_MODE, GL_LINEAR); glFogf(GL_FOG_START, camr*0.1f); glFogf(GL_FOG_END, camr*1.25f); glFogfv(GL_FOG_COLOR, fogCol); glDepthFunc(GL_LEQUAL); bool done = false; while(!done) { // Handle input events. int mscroll = 0; bool processHitTest = false; bool processHitTestShift = false; SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_KEYDOWN: // Handle any key presses here. if (event.key.keysym.sym == SDLK_ESCAPE) { done = true; } else if (event.key.keysym.sym == SDLK_t) { showLevels = false; showSample = false; showTestCases = true; scanDirectory("Tests", ".txt", files); } else if (event.key.keysym.sym == SDLK_TAB) { showMenu = !showMenu; } else if (event.key.keysym.sym == SDLK_SPACE) { if (sample) sample->handleToggle(); } else if (event.key.keysym.sym == SDLK_1) { if (sample) sample->handleStep(); } else if (event.key.keysym.sym == SDLK_9) { if (geom) geom->save("geomset.txt"); } else if (event.key.keysym.sym == SDLK_0) { delete geom; geom = new InputGeom; if (!geom || !geom->load(&ctx, "geomset.txt")) { delete geom; geom = 0; showLog = true; logScroll = 0; ctx.dumpLog("Geom load log %s:", meshName); } if (sample && geom) { sample->handleMeshChanged(geom); } if (geom || sample) { const float* bmin = 0; const float* bmax = 0; if (sample) { bmin = sample->getBoundsMin(); bmax = sample->getBoundsMax(); } else if (geom) { bmin = geom->getMeshBoundsMin(); bmax = geom->getMeshBoundsMax(); } // Reset camera and fog to match the mesh bounds. if (bmin && bmax) { camr = sqrtf(rcSqr(bmax[0]-bmin[0]) + rcSqr(bmax[1]-bmin[1]) + rcSqr(bmax[2]-bmin[2])) / 2; camx = (bmax[0] + bmin[0]) / 2 + camr; camy = (bmax[1] + bmin[1]) / 2 + camr; camz = (bmax[2] + bmin[2]) / 2 + camr; camr *= 3; } rx = 45; ry = -45; glFogf(GL_FOG_START, camr*0.2f); glFogf(GL_FOG_END, camr*1.25f); } } else if (event.key.keysym.sym == SDLK_RIGHT) { slideShow.nextSlide(); } else if (event.key.keysym.sym == SDLK_LEFT) { slideShow.prevSlide(); } break; case SDL_MOUSEBUTTONDOWN: if (event.button.button == SDL_BUTTON_RIGHT) { if (!mouseOverMenu) { // Rotate view rotate = true; movedDuringRotate = false; origx = mx; origy = my; origrx = rx; origry = ry; } } else if (event.button.button == SDL_BUTTON_WHEELUP) { if (mouseOverMenu) mscroll--; else scrollZoom -= 1.0f; } else if (event.button.button == SDL_BUTTON_WHEELDOWN) { if (mouseOverMenu) mscroll++; else scrollZoom += 1.0f; } break; case SDL_MOUSEBUTTONUP: // Handle mouse clicks here. if (event.button.button == SDL_BUTTON_RIGHT) { rotate = false; if (!mouseOverMenu) { if (!movedDuringRotate) { processHitTest = true; processHitTestShift = true; } } } else if (event.button.button == SDL_BUTTON_LEFT) { if (!mouseOverMenu) { processHitTest = true; processHitTestShift = (SDL_GetModState() & KMOD_SHIFT) ? true : false; } } break; case SDL_MOUSEMOTION: mx = event.motion.x; my = height-1 - event.motion.y; if (rotate) { int dx = mx - origx; int dy = my - origy; rx = origrx - dy*0.25f; ry = origry + dx*0.25f; if (dx*dx+dy*dy > 3*3) movedDuringRotate = true; } break; case SDL_QUIT: done = true; break; default: break; } } unsigned char mbut = 0; if (SDL_GetMouseState(0,0) & SDL_BUTTON_LMASK) mbut |= IMGUI_MBUT_LEFT; if (SDL_GetMouseState(0,0) & SDL_BUTTON_RMASK) mbut |= IMGUI_MBUT_RIGHT; Uint32 time = SDL_GetTicks(); float dt = (time - lastTime) / 1000.0f; lastTime = time; t += dt; // Hit test mesh. if (processHitTest && geom && sample) { float hitt; bool hit = geom->raycastMesh(rays, raye, hitt); if (hit) { if (SDL_GetModState() & KMOD_CTRL) { // Marker mposSet = true; mpos[0] = rays[0] + (raye[0] - rays[0])*hitt; mpos[1] = rays[1] + (raye[1] - rays[1])*hitt; mpos[2] = rays[2] + (raye[2] - rays[2])*hitt; } else { float pos[3]; pos[0] = rays[0] + (raye[0] - rays[0])*hitt; pos[1] = rays[1] + (raye[1] - rays[1])*hitt; pos[2] = rays[2] + (raye[2] - rays[2])*hitt; sample->handleClick(rays, pos, processHitTestShift); } } else { if (SDL_GetModState() & KMOD_CTRL) { // Marker mposSet = false; } } } // Update sample simulation. const float SIM_RATE = 20; const float DELTA_TIME = 1.0f/SIM_RATE; timeAcc = rcClamp(timeAcc+dt, -1.0f, 1.0f); int simIter = 0; while (timeAcc > DELTA_TIME) { timeAcc -= DELTA_TIME; if (simIter < 5) { if (sample) sample->handleUpdate(DELTA_TIME); } simIter++; } // Clamp the framerate so that we do not hog all the CPU. const float MIN_FRAME_TIME = 1.0f/40.0f; if (dt < MIN_FRAME_TIME) { int ms = (int)((MIN_FRAME_TIME - dt)*1000.0f); if (ms > 10) ms = 10; if (ms >= 0) SDL_Delay(ms); } // Update and render glViewport(0, 0, width, height); glClearColor(0.3f, 0.3f, 0.32f, 1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_TEXTURE_2D); // Render 3d glEnable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(50.0f, (float)width/(float)height, 1.0f, camr); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRotatef(rx,1,0,0); glRotatef(ry,0,1,0); glTranslatef(-camx, -camy, -camz); // Get hit ray position and direction. GLdouble proj[16]; GLdouble model[16]; GLint view[4]; glGetDoublev(GL_PROJECTION_MATRIX, proj); glGetDoublev(GL_MODELVIEW_MATRIX, model); glGetIntegerv(GL_VIEWPORT, view); GLdouble x, y, z; gluUnProject(mx, my, 0.0f, model, proj, view, &x, &y, &z); rays[0] = (float)x; rays[1] = (float)y; rays[2] = (float)z; gluUnProject(mx, my, 1.0f, model, proj, view, &x, &y, &z); raye[0] = (float)x; raye[1] = (float)y; raye[2] = (float)z; // Handle keyboard movement. Uint8* keystate = SDL_GetKeyState(NULL); moveW = rcClamp(moveW + dt * 4 * (keystate[SDLK_w] ? 1 : -1), 0.0f, 1.0f); moveS = rcClamp(moveS + dt * 4 * (keystate[SDLK_s] ? 1 : -1), 0.0f, 1.0f); moveA = rcClamp(moveA + dt * 4 * (keystate[SDLK_a] ? 1 : -1), 0.0f, 1.0f); moveD = rcClamp(moveD + dt * 4 * (keystate[SDLK_d] ? 1 : -1), 0.0f, 1.0f); float keybSpeed = 22.0f; if (SDL_GetModState() & KMOD_SHIFT) keybSpeed *= 4.0f; float movex = (moveD - moveA) * keybSpeed * dt; float movey = (moveS - moveW) * keybSpeed * dt; movey += scrollZoom * 2.0f; scrollZoom = 0; camx += movex * (float)model[0]; camy += movex * (float)model[4]; camz += movex * (float)model[8]; camx += movey * (float)model[2]; camy += movey * (float)model[6]; camz += movey * (float)model[10]; glEnable(GL_FOG); if (sample) sample->handleRender(); if (test) test->handleRender(); glDisable(GL_FOG); // Render GUI glDisable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, width, 0, height); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); mouseOverMenu = false; imguiBeginFrame(mx,my,mbut,mscroll); if (sample) { sample->handleRenderOverlay((double*)proj, (double*)model, (int*)view); } if (test) { if (test->handleRenderOverlay((double*)proj, (double*)model, (int*)view)) mouseOverMenu = true; } // Help text. if (showMenu) { const char msg[] = "W/S/A/D: Move RMB: Rotate"; imguiDrawText(280, height-20, IMGUI_ALIGN_LEFT, msg, imguiRGBA(255,255,255,128)); } if (showMenu) { if (imguiBeginScrollArea("Properties", width-250-10, 10, 250, height-20, &propScroll)) mouseOverMenu = true; if (imguiCheck("Show Log", showLog)) showLog = !showLog; if (imguiCheck("Show Tools", showTools)) showTools = !showTools; imguiSeparator(); imguiLabel("Sample"); if (imguiButton(sampleName)) { if (showSample) { showSample = false; } else { showSample = true; showLevels = false; showTestCases = false; } } imguiSeparator(); imguiLabel("Input Mesh"); if (imguiButton(meshName)) { if (showLevels) { showLevels = false; } else { showSample = false; showTestCases = false; showLevels = true; scanDirectory("Meshes", ".obj", files); } } if (geom) { char text[64]; snprintf(text, 64, "Verts: %.1fk Tris: %.1fk", geom->getMesh()->getVertCount()/1000.0f, geom->getMesh()->getTriCount()/1000.0f); imguiValue(text); } imguiSeparator(); if (geom && sample) { imguiSeparatorLine(); sample->handleSettings(); if (imguiButton("Build")) { ctx.resetLog(); if (!sample->handleBuild()) { showLog = true; logScroll = 0; } ctx.dumpLog("Build log %s:", meshName); // Clear test. delete test; test = 0; } imguiSeparator(); } if (sample) { imguiSeparatorLine(); sample->handleDebugMode(); } imguiEndScrollArea(); } // Sample selection dialog. if (showSample) { static int levelScroll = 0; if (imguiBeginScrollArea("Choose Sample", width-10-250-10-200, height-10-250, 200, 250, &levelScroll)) mouseOverMenu = true; Sample* newSample = 0; for (int i = 0; i < g_nsamples; ++i) { if (imguiItem(g_samples[i].name)) { newSample = g_samples[i].create(); if (newSample) strcpy(sampleName, g_samples[i].name); } } if (newSample) { delete sample; sample = newSample; sample->setContext(&ctx); if (geom && sample) { sample->handleMeshChanged(geom); } showSample = false; } if (geom || sample) { const float* bmin = 0; const float* bmax = 0; if (sample) { bmin = sample->getBoundsMin(); bmax = sample->getBoundsMax(); } else if (geom) { bmin = geom->getMeshBoundsMin(); bmax = geom->getMeshBoundsMax(); } // Reset camera and fog to match the mesh bounds. if (bmin && bmax) { camr = sqrtf(rcSqr(bmax[0]-bmin[0]) + rcSqr(bmax[1]-bmin[1]) + rcSqr(bmax[2]-bmin[2])) / 2; camx = (bmax[0] + bmin[0]) / 2 + camr; camy = (bmax[1] + bmin[1]) / 2 + camr; camz = (bmax[2] + bmin[2]) / 2 + camr; camr *= 3; } rx = 45; ry = -45; glFogf(GL_FOG_START, camr*0.1f); glFogf(GL_FOG_END, camr*1.25f); } imguiEndScrollArea(); } // Level selection dialog. if (showLevels) { static int levelScroll = 0; if (imguiBeginScrollArea("Choose Level", width-10-250-10-200, height-10-450, 200, 450, &levelScroll)) mouseOverMenu = true; int levelToLoad = -1; for (int i = 0; i < files.size; ++i) { if (imguiItem(files.files[i])) levelToLoad = i; } if (levelToLoad != -1) { strncpy(meshName, files.files[levelToLoad], sizeof(meshName)); meshName[sizeof(meshName)-1] = '\0'; showLevels = false; delete geom; geom = 0; char path[256]; strcpy(path, "Meshes/"); strcat(path, meshName); geom = new InputGeom; if (!geom || !geom->loadMesh(&ctx, path)) { delete geom; geom = 0; showLog = true; logScroll = 0; ctx.dumpLog("Geom load log %s:", meshName); } if (sample && geom) { sample->handleMeshChanged(geom); } if (geom || sample) { const float* bmin = 0; const float* bmax = 0; if (sample) { bmin = sample->getBoundsMin(); bmax = sample->getBoundsMax(); } else if (geom) { bmin = geom->getMeshBoundsMin(); bmax = geom->getMeshBoundsMax(); } // Reset camera and fog to match the mesh bounds. if (bmin && bmax) { camr = sqrtf(rcSqr(bmax[0]-bmin[0]) + rcSqr(bmax[1]-bmin[1]) + rcSqr(bmax[2]-bmin[2])) / 2; camx = (bmax[0] + bmin[0]) / 2 + camr; camy = (bmax[1] + bmin[1]) / 2 + camr; camz = (bmax[2] + bmin[2]) / 2 + camr; camr *= 3; } rx = 45; ry = -45; glFogf(GL_FOG_START, camr*0.1f); glFogf(GL_FOG_END, camr*1.25f); } } imguiEndScrollArea(); } // Test cases if (showTestCases) { static int testScroll = 0; if (imguiBeginScrollArea("Choose Test To Run", width-10-250-10-200, height-10-450, 200, 450, &testScroll)) mouseOverMenu = true; int testToLoad = -1; for (int i = 0; i < files.size; ++i) { if (imguiItem(files.files[i])) testToLoad = i; } if (testToLoad != -1) { char path[256]; strcpy(path, "Tests/"); strcat(path, files.files[testToLoad]); test = new TestCase; if (test) { // Load the test. if (!test->load(path)) { delete test; test = 0; } // Create sample Sample* newSample = 0; for (int i = 0; i < g_nsamples; ++i) { if (strcmp(g_samples[i].name, test->getSampleName()) == 0) { newSample = g_samples[i].create(); if (newSample) strcpy(sampleName, g_samples[i].name); } } if (newSample) { delete sample; sample = newSample; sample->setContext(&ctx); showSample = false; } // Load geom. strcpy(meshName, test->getGeomFileName()); meshName[sizeof(meshName)-1] = '\0'; delete geom; geom = 0; strcpy(path, "Meshes/"); strcat(path, meshName); geom = new InputGeom; if (!geom || !geom->loadMesh(&ctx, path)) { delete geom; geom = 0; showLog = true; logScroll = 0; ctx.dumpLog("Geom load log %s:", meshName); } if (sample && geom) { sample->handleMeshChanged(geom); } // This will ensure that tile & poly bits are updated in tiled sample. if (sample) sample->handleSettings(); ctx.resetLog(); if (sample && !sample->handleBuild()) { ctx.dumpLog("Build log %s:", meshName); } if (geom || sample) { const float* bmin = 0; const float* bmax = 0; if (sample) { bmin = sample->getBoundsMin(); bmax = sample->getBoundsMax(); } else if (geom) { bmin = geom->getMeshBoundsMin(); bmax = geom->getMeshBoundsMax(); } // Reset camera and fog to match the mesh bounds. if (bmin && bmax) { camr = sqrtf(rcSqr(bmax[0]-bmin[0]) + rcSqr(bmax[1]-bmin[1]) + rcSqr(bmax[2]-bmin[2])) / 2; camx = (bmax[0] + bmin[0]) / 2 + camr; camy = (bmax[1] + bmin[1]) / 2 + camr; camz = (bmax[2] + bmin[2]) / 2 + camr; camr *= 3; } rx = 45; ry = -45; glFogf(GL_FOG_START, camr*0.2f); glFogf(GL_FOG_END, camr*1.25f); } // Do the tests. if (sample) test->doTests(sample->getNavMesh(), sample->getNavMeshQuery()); } } imguiEndScrollArea(); } // Log if (showLog && showMenu) { if (imguiBeginScrollArea("Log", 250+20, 10, width - 300 - 250, 200, &logScroll)) mouseOverMenu = true; for (int i = 0; i < ctx.getLogCount(); ++i) imguiLabel(ctx.getLogText(i)); imguiEndScrollArea(); } // Tools if (!showTestCases && showTools && showMenu) // && geom && sample) { if (imguiBeginScrollArea("Tools", 10, 10, 250, height-20, &toolsScroll)) mouseOverMenu = true; if (sample) sample->handleTools(); imguiEndScrollArea(); } slideShow.updateAndDraw(dt, (float)width, (float)height); // Marker if (mposSet && gluProject((GLdouble)mpos[0], (GLdouble)mpos[1], (GLdouble)mpos[2], model, proj, view, &x, &y, &z)) { // Draw marker circle glLineWidth(5.0f); glColor4ub(240,220,0,196); glBegin(GL_LINE_LOOP); const float r = 25.0f; for (int i = 0; i < 20; ++i) { const float a = (float)i / 20.0f * RC_PI*2; const float fx = (float)x + cosf(a)*r; const float fy = (float)y + sinf(a)*r; glVertex2f(fx,fy); } glEnd(); glLineWidth(1.0f); } imguiEndFrame(); imguiRenderGLDraw(); glEnable(GL_DEPTH_TEST); SDL_GL_SwapBuffers(); } imguiRenderGLDestroy(); SDL_Quit(); delete sample; delete geom; return 0; }
int main( int argc, char **argv ) { int width = 1024, height=768; // Initialise GLFW if( !glfwInit() ) { fprintf( stderr, "Failed to initialize GLFW\n" ); exit( EXIT_FAILURE ); } // Open a window and create its OpenGL context if( !glfwOpenWindow( width, height, 0,0,0,0, 24,0, GLFW_WINDOW ) ) { fprintf( stderr, "Failed to open GLFW window\n" ); glfwTerminate(); exit( EXIT_FAILURE ); } glfwSetWindowTitle( "imgui sample imguiRenderGL2" ); GLenum err = glewInit(); if (GLEW_OK != err) { /* Problem: glewInit failed, something is seriously wrong. */ fprintf(stderr, "Error: %s\n", glewGetErrorString(err)); exit( EXIT_FAILURE ); } // Ensure we can capture the escape key being pressed below glfwEnable( GLFW_STICKY_KEYS ); // Enable vertical sync (on cards that support it) glfwSwapInterval( 1 ); // Init UI if (!imguiRenderGLInit("DroidSans.ttf")) { fprintf(stderr, "Could not init GUI renderer.\n"); exit(EXIT_FAILURE); } glClearColor(0.8f, 0.8f, 0.8f, 1.f); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_DEPTH_TEST); // imgui states bool checked1 = false; bool checked2 = false; bool checked3 = true; bool checked4 = false; float value1 = 50.f; float value2 = 30.f; int scrollarea1 = 0; int scrollarea2 = 0; // glfw scrolling int glfwscroll = 0; do { glfwGetWindowSize(&width, &height); glViewport(0, 0, width, height); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Mouse states unsigned char mousebutton = 0; int currentglfwscroll = glfwGetMouseWheel(); int mscroll = 0; if (currentglfwscroll < glfwscroll) mscroll = 2; if (currentglfwscroll > glfwscroll) mscroll = -2; glfwscroll = currentglfwscroll; int mousex; int mousey; glfwGetMousePos(&mousex, &mousey); mousey = height - mousey; int leftButton = glfwGetMouseButton( GLFW_MOUSE_BUTTON_LEFT ); int rightButton = glfwGetMouseButton( GLFW_MOUSE_BUTTON_RIGHT ); int middleButton = glfwGetMouseButton( GLFW_MOUSE_BUTTON_MIDDLE ); int toggle = 0; if( leftButton == GLFW_PRESS ) mousebutton |= IMGUI_MBUT_LEFT; // Draw UI glMatrixMode(GL_PROJECTION); glLoadIdentity(); float projection[16] = { 2.f/width, 0.f, 0.f, 0.f, 0.f, 2.f/height, 0.f, 0.f, 0.f, 0.f, -2.f, 0.f, -1.f, -1.f, -1.f, 1.f }; glLoadMatrixf(projection); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glUseProgram(0); imguiBeginFrame(mousex, mousey, mousebutton, mscroll); imguiBeginScrollArea("Scroll area", 10, 10, width / 5, height - 20, &scrollarea1); imguiSeparatorLine(); imguiSeparator(); imguiButton("Button"); imguiButton("Disabled button", false); imguiItem("Item"); imguiItem("Disabled item", false); toggle = imguiCheck("Checkbox", checked1); if (toggle) checked1 = !checked1; toggle = imguiCheck("Disabled checkbox", checked2, false); if (toggle) checked2 = !checked2; toggle = imguiCollapse("Collapse", "subtext", checked3); if (checked3) { imguiIndent(); imguiLabel("Collapsible element"); imguiUnindent(); } if (toggle) checked3 = !checked3; toggle = imguiCollapse("Disabled collapse", "subtext", checked4, false); if (toggle) checked4 = !checked4; imguiLabel("Label"); imguiValue("Value"); imguiSlider("Slider", &value1, 0.f, 100.f, 1.f); imguiSlider("Disabled slider", &value2, 0.f, 100.f, 1.f, false); imguiIndent(); imguiLabel("Indented"); imguiUnindent(); imguiLabel("Unindented"); imguiEndScrollArea(); imguiBeginScrollArea("Scroll area", 20 + width / 5, 500, width / 5, height - 510, &scrollarea2); imguiSeparatorLine(); imguiSeparator(); for (int i = 0; i < 100; ++i) imguiLabel("A wall of text"); imguiEndScrollArea(); imguiEndFrame(); imguiDrawText(30 + width / 5 * 2, height - 20, IMGUI_ALIGN_LEFT, "Free text", imguiRGBA(32,192, 32,192)); imguiDrawText(30 + width / 5 * 2 + 100, height - 40, IMGUI_ALIGN_RIGHT, "Free text", imguiRGBA(32, 32, 192, 192)); imguiDrawText(30 + width / 5 * 2 + 50, height - 60, IMGUI_ALIGN_CENTER, "Free text", imguiRGBA(192, 32, 32,192)); imguiDrawLine(30 + width / 5 * 2, height - 80, 30 + width / 5 * 2 + 100, height - 60, 1.f, imguiRGBA(32,192, 32,192)); imguiDrawLine(30 + width / 5 * 2, height - 100, 30 + width / 5 * 2 + 100, height - 80, 2.f, imguiRGBA(32, 32, 192, 192)); imguiDrawLine(30 + width / 5 * 2, height - 120, 30 + width / 5 * 2 + 100, height - 100, 3.f, imguiRGBA(192, 32, 32,192)); imguiDrawRoundedRect(30 + width / 5 * 2, height - 240, 100, 100, 5.f, imguiRGBA(32,192, 32,192)); imguiDrawRoundedRect(30 + width / 5 * 2, height - 350, 100, 100, 10.f, imguiRGBA(32, 32, 192, 192)); imguiDrawRoundedRect(30 + width / 5 * 2, height - 470, 100, 100, 20.f, imguiRGBA(192, 32, 32,192)); imguiDrawRect(30 + width / 5 * 2, height - 590, 100, 100, imguiRGBA(32, 192, 32, 192)); imguiDrawRect(30 + width / 5 * 2, height - 710, 100, 100, imguiRGBA(32, 32, 192, 192)); imguiDrawRect(30 + width / 5 * 2, height - 830, 100, 100, imguiRGBA(192, 32, 32,192)); imguiRenderGLDraw(width, height); // Check for errors GLenum err = glGetError(); if(err != GL_NO_ERROR) { fprintf(stderr, "OpenGL Error : %s\n", gluErrorString(err)); } // Swap buffers glfwSwapBuffers(); } // Check if the ESC key was pressed or the window was closed while( glfwGetKey( GLFW_KEY_ESC ) != GLFW_PRESS && glfwGetWindowParam( GLFW_OPENED ) ); // Clean UI imguiRenderGLDestroy(); // Close OpenGL window and terminate GLFW glfwTerminate(); exit( EXIT_SUCCESS ); }
int main( int argc, char **argv ) { int width = 800, height= 600; float widthf = (float) width, heightf = (float) height; double t; float fps = 0.f; // Initialise GLFW if( !glfwInit() ) { fprintf( stderr, "Failed to initialize GLFW\n" ); exit( EXIT_FAILURE ); } // Force core profile on Mac OSX #ifdef __APPLE__ glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2); glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); #endif // Open a window and create its OpenGL context if( !glfwOpenWindow( width, height, 0,0,0,0, 24, 0, GLFW_WINDOW ) ) { fprintf( stderr, "Failed to open GLFW window\n" ); glfwTerminate(); exit( EXIT_FAILURE ); } glfwSetWindowTitle( "001_a" ); // Core profile is flagged as experimental in glew #ifdef __APPLE__ glewExperimental = GL_TRUE; #endif GLenum err = glewInit(); if (GLEW_OK != err) { /* Problem: glewInit failed, something is seriously wrong. */ fprintf(stderr, "Error: %s\n", glewGetErrorString(err)); exit( EXIT_FAILURE ); } // Ensure we can capture the escape key being pressed below glfwEnable( GLFW_STICKY_KEYS ); // Enable vertical sync (on cards that support it) glfwSwapInterval( 1 ); GLenum glerr = GL_NO_ERROR; glerr = glGetError(); if (!imguiRenderGLInit(DroidSans_ttf, DroidSans_ttf_len)) { fprintf(stderr, "Could not init GUI renderer.\n"); exit(EXIT_FAILURE); } // Init viewer structures Camera camera; camera_defaults(camera); GUIStates guiStates; init_gui_states(guiStates); float dummySlider = 0.f; // Load images and upload textures GLuint textures[2]; glGenTextures(2, textures); int x; int y; int comp; unsigned char * diffuse = stbi_load("textures/spnza_bricks_a_diff.tga", &x, &y, &comp, 3); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textures[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, x, y, 0, GL_RGB, GL_UNSIGNED_BYTE, diffuse); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); fprintf(stderr, "Diffuse %dx%d:%d\n", x, y, comp); unsigned char * spec = stbi_load("textures/spnza_bricks_a_spec.tga", &x, &y, &comp, 1); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textures[1]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, x, y, 0, GL_RED, GL_UNSIGNED_BYTE, spec); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); fprintf(stderr, "Spec %dx%d:%d\n", x, y, comp); glerr = glGetError(); if(glerr != GL_NO_ERROR) fprintf(stderr, "2nd OpenGL Error : %s\n", gluErrorString(glerr)); // Try to load and compile shader ShaderGLSL shader; const char * shaderFile = "001/3a.glsl"; //const char * shaderFile = "001/4a.glsl"; //const char * shaderFile = "001/5a.glsl"; //const char * shaderFile = "001/5ba.glsl"; //const char * shaderFile = "001/6a.glsl"; //const char * shaderFile = "001/7a.glsl"; //const char * shaderFile = "001/8a.glsl"; //int status = load_shader_from_file(shader, shaderFile, ShaderGLSL::VERTEX_SHADER | ShaderGLSL::FRAGMENT_SHADER | ShaderGLSL::GEOMETRY_SHADER); int status = load_shader_from_file(shader, shaderFile, ShaderGLSL::VERTEX_SHADER | ShaderGLSL::FRAGMENT_SHADER); if ( status == -1 ) { fprintf(stderr, "Error on loading %s\n", shaderFile); exit( EXIT_FAILURE ); } // Apply shader GLuint program = shader.program; glUseProgram(program); GLuint projectionLocation = glGetUniformLocation(program, "Projection"); GLuint viewLocation = glGetUniformLocation(program, "View"); GLuint objectLocation = glGetUniformLocation(program, "Object"); GLuint timeLocation = glGetUniformLocation(program, "Time"); GLuint diffuseLocation = glGetUniformLocation(program, "Diffuse"); GLuint specLocation = glGetUniformLocation(program, "Spec"); GLuint cameraPositionLocation = glGetUniformLocation(program, "CameraPosition"); glUniform1i(diffuseLocation, 0); glUniform1i(specLocation, 1); // Load geometry int cube_triangleCount = 12; int cube_triangleList[] = {0, 1, 2, 2, 1, 3, 4, 5, 6, 6, 5, 7, 8, 9, 10, 10, 9, 11, 12, 13, 14, 14, 13, 15, 16, 17, 18, 19, 17, 20, 21, 22, 23, 24, 25, 26, }; float cube_uvs[] = {0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f, 1.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f, 1.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f, 1.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f, 1.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f, 0.f, 1.f, 1.f, 0.f, 1.f, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 1.f, 1.f, 0.f, }; float cube_vertices[] = {-0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5 }; float cube_normals[] = {0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, }; int plane_triangleCount = 2; int plane_triangleList[] = {0, 1, 2, 2, 1, 3}; float plane_uvs[] = {0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f, 1.f}; float plane_vertices[] = {-5.0, -1.0, 5.0, 5.0, -1.0, 5.0, -5.0, -1.0, -5.0, 5.0, -1.0, -5.0}; float plane_normals[] = {0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0}; // Vertex Array Object GLuint vao[2]; glGenVertexArrays(2, vao); // Vertex Buffer Objects GLuint vbo[8]; glGenBuffers(8, vbo); // Cube glBindVertexArray(vao[0]); // Bind indices and upload data glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[0]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cube_triangleList), cube_triangleList, GL_STATIC_DRAW); // Bind vertices and upload data glBindBuffer(GL_ARRAY_BUFFER, vbo[1]); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*3, (void*)0); glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices), cube_vertices, GL_STATIC_DRAW); // Bind normals and upload data glBindBuffer(GL_ARRAY_BUFFER, vbo[2]); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*3, (void*)0); glBufferData(GL_ARRAY_BUFFER, sizeof(cube_normals), cube_normals, GL_STATIC_DRAW); // Bind uv coords and upload data glBindBuffer(GL_ARRAY_BUFFER, vbo[3]); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*2, (void*)0); glBufferData(GL_ARRAY_BUFFER, sizeof(cube_uvs), cube_uvs, GL_STATIC_DRAW); // Plane glBindVertexArray(vao[1]); // Bind indices and upload data glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[4]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(plane_triangleList), plane_triangleList, GL_STATIC_DRAW); // Bind vertices and upload data glBindBuffer(GL_ARRAY_BUFFER, vbo[5]); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*3, (void*)0); glBufferData(GL_ARRAY_BUFFER, sizeof(plane_vertices), plane_vertices, GL_STATIC_DRAW); // Bind normals and upload data glBindBuffer(GL_ARRAY_BUFFER, vbo[6]); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*3, (void*)0); glBufferData(GL_ARRAY_BUFFER, sizeof(plane_normals), plane_normals, GL_STATIC_DRAW); // Bind uv coords and upload data glBindBuffer(GL_ARRAY_BUFFER, vbo[7]); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*2, (void*)0); glBufferData(GL_ARRAY_BUFFER, sizeof(plane_uvs), plane_uvs, GL_STATIC_DRAW); // Unbind everything. Potentially illegal on some implementations glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); // Viewport glViewport( 0, 0, width, height ); do { t = glfwGetTime(); // Mouse states int leftButton = glfwGetMouseButton( GLFW_MOUSE_BUTTON_LEFT ); int rightButton = glfwGetMouseButton( GLFW_MOUSE_BUTTON_RIGHT ); int middleButton = glfwGetMouseButton( GLFW_MOUSE_BUTTON_MIDDLE ); if( leftButton == GLFW_PRESS ) guiStates.turnLock = true; else guiStates.turnLock = false; if( rightButton == GLFW_PRESS ) guiStates.zoomLock = true; else guiStates.zoomLock = false; if( middleButton == GLFW_PRESS ) guiStates.panLock = true; else guiStates.panLock = false; // Camera movements int altPressed = glfwGetKey(GLFW_KEY_LSHIFT); if (!altPressed && (leftButton == GLFW_PRESS || rightButton == GLFW_PRESS || middleButton == GLFW_PRESS)) { int x; int y; glfwGetMousePos(&x, &y); guiStates.lockPositionX = x; guiStates.lockPositionY = y; } if (altPressed == GLFW_PRESS) { int mousex; int mousey; glfwGetMousePos(&mousex, &mousey); int diffLockPositionX = mousex - guiStates.lockPositionX; int diffLockPositionY = mousey - guiStates.lockPositionY; if (guiStates.zoomLock) { float zoomDir = 0.0; if (diffLockPositionX > 0) zoomDir = -1.f; else if (diffLockPositionX < 0 ) zoomDir = 1.f; camera_zoom(camera, zoomDir * GUIStates::MOUSE_ZOOM_SPEED); } else if (guiStates.turnLock) { camera_turn(camera, diffLockPositionY * GUIStates::MOUSE_TURN_SPEED, diffLockPositionX * GUIStates::MOUSE_TURN_SPEED); } else if (guiStates.panLock) { camera_pan(camera, diffLockPositionX * GUIStates::MOUSE_PAN_SPEED, diffLockPositionY * GUIStates::MOUSE_PAN_SPEED); } guiStates.lockPositionX = mousex; guiStates.lockPositionY = mousey; } // Default states glEnable(GL_DEPTH_TEST); // Clear the front buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Get camera matrices glm::mat4 projection = glm::perspective(45.0f, widthf / heightf, 0.1f, 100.f); glm::mat4 worldToView = glm::lookAt(camera.eye, camera.o, camera.up); glm::mat4 objectToWorld; // Select textures glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textures[0]); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textures[1]); // Select shader glUseProgram(program); // Upload uniforms glUniformMatrix4fv(projectionLocation, 1, 0, glm::value_ptr(projection)); glUniformMatrix4fv(viewLocation, 1, 0, glm::value_ptr(worldToView)); glUniformMatrix4fv(objectLocation, 1, 0, glm::value_ptr(objectToWorld)); glUniform1f(timeLocation, t); glUniform3fv(cameraPositionLocation, 1, glm::value_ptr(camera.eye)); // Render vaos glBindVertexArray(vao[0]); glDrawElementsInstanced(GL_TRIANGLES, cube_triangleCount * 3, GL_UNSIGNED_INT, (void*)0, 4); //glDrawElements(GL_TRIANGLES, cube_triangleCount * 3, GL_UNSIGNED_INT, (void*)0); glBindVertexArray(vao[1]); glDrawElements(GL_TRIANGLES, plane_triangleCount * 3, GL_UNSIGNED_INT, (void*)0); #if 1 // Draw UI glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glViewport(0, 0, width, height); unsigned char mbut = 0; int mscroll = 0; int mousex; int mousey; glfwGetMousePos(&mousex, &mousey); mousey = height - mousey; if( leftButton == GLFW_PRESS ) mbut |= IMGUI_MBUT_LEFT; imguiBeginFrame(mousex, mousey, mbut, mscroll); int logScroll = 0; char lineBuffer[512]; imguiBeginScrollArea("001", width - 210, height - 310, 200, 300, &logScroll); sprintf(lineBuffer, "FPS %f", fps); imguiLabel(lineBuffer); imguiSlider("Dummy", &dummySlider, 0.0, 3.0, 0.1); imguiEndScrollArea(); imguiEndFrame(); imguiRenderGLDraw(width, height); glDisable(GL_BLEND); #endif // Check for errors GLenum err = glGetError(); if(err != GL_NO_ERROR) { fprintf(stderr, "OpenGL Error : %s\n", gluErrorString(err)); } // Swap buffers glfwSwapBuffers(); double newTime = glfwGetTime(); fps = 1.f/ (newTime - t); } // Check if the ESC key was pressed or the window was closed while( glfwGetKey( GLFW_KEY_ESC ) != GLFW_PRESS && glfwGetWindowParam( GLFW_OPENED ) ); // Close OpenGL window and terminate GLFW glfwTerminate(); exit( EXIT_SUCCESS ); }
int main( int argc, char **argv ) { int width = 1024, height=768; float widthf = (float) width, heightf = (float) height; double t; float fps = 0.f; // Initialise GLFW if( !glfwInit() ) { fprintf( stderr, "Failed to initialize GLFW\n" ); exit( EXIT_FAILURE ); } // Force core profile on Mac OSX #ifdef __APPLE__ glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2); glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); #endif // Open a window and create its OpenGL context if( !glfwOpenWindow( width, height, 0,0,0,0, 24, 0, GLFW_WINDOW ) ) { fprintf( stderr, "Failed to open GLFW window\n" ); glfwTerminate(); exit( EXIT_FAILURE ); } glfwSetWindowTitle( "002_forward_a" ); // Core profile is flagged as experimental in glew #ifdef __APPLE__ glewExperimental = GL_TRUE; #endif GLenum err = glewInit(); if (GLEW_OK != err) { /* Problem: glewInit failed, something is seriously wrong. */ fprintf(stderr, "Error: %s\n", glewGetErrorString(err)); exit( EXIT_FAILURE ); } // Ensure we can capture the escape key being pressed below glfwEnable( GLFW_STICKY_KEYS ); // Enable vertical sync (on cards that support it) glfwSwapInterval( 1 ); GLenum glerr = GL_NO_ERROR; glerr = glGetError(); if (!imguiRenderGLInit(DroidSans_ttf, DroidSans_ttf_len)) { fprintf(stderr, "Could not init GUI renderer.\n"); exit(EXIT_FAILURE); } // Init viewer structures Camera camera; camera_defaults(camera); GUIStates guiStates; init_gui_states(guiStates); // GUI float numLights = 10.f; // Load images and upload textures GLuint textures[3]; glGenTextures(3, textures); int x; int y; int comp; unsigned char * diffuse = stbi_load("textures/spnza_bricks_a_diff.tga", &x, &y, &comp, 3); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textures[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, x, y, 0, GL_RGB, GL_UNSIGNED_BYTE, diffuse); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); fprintf(stderr, "Diffuse %dx%d:%d\n", x, y, comp); unsigned char * spec = stbi_load("textures/spnza_bricks_a_spec.tga", &x, &y, &comp, 1); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textures[1]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, x, y, 0, GL_RED, GL_UNSIGNED_BYTE, spec); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); fprintf(stderr, "Spec %dx%d:%d\n", x, y, comp); // Try to load and compile shader int status; ShaderGLSL gbuffer_shader; const char * shaderFileGBuffer = "002/2_gbuffera.glsl"; //int status = load_shader_from_file(gbuffer_shader, shaderFileGBuffer, ShaderGLSL::VERTEX_SHADER | ShaderGLSL::FRAGMENT_SHADER | ShaderGLSL::GEOMETRY_SHADER); status = load_shader_from_file(gbuffer_shader, shaderFileGBuffer, ShaderGLSL::VERTEX_SHADER | ShaderGLSL::FRAGMENT_SHADER); if ( status == -1 ) { fprintf(stderr, "Error on loading %s\n", shaderFileGBuffer); exit( EXIT_FAILURE ); } // Compute locations for gbuffer_shader GLuint gbuffer_projectionLocation = glGetUniformLocation(gbuffer_shader.program, "Projection"); GLuint gbuffer_viewLocation = glGetUniformLocation(gbuffer_shader.program, "View"); GLuint gbuffer_objectLocation = glGetUniformLocation(gbuffer_shader.program, "Object"); GLuint gbuffer_timeLocation = glGetUniformLocation(gbuffer_shader.program, "Time"); GLuint gbuffer_diffuseLocation = glGetUniformLocation(gbuffer_shader.program, "Diffuse"); GLuint gbuffer_specLocation = glGetUniformLocation(gbuffer_shader.program, "Spec"); // Load Blit shader ShaderGLSL blit_shader; const char * shaderFileBlit = "002/2_blita.glsl"; //int status = load_shader_from_file(blit_shader, shaderFileBlit, ShaderGLSL::VERTEX_SHADER | ShaderGLSL::FRAGMENT_SHADER | ShaderGLSL::GEOMETRY_SHADER); status = load_shader_from_file(blit_shader, shaderFileBlit, ShaderGLSL::VERTEX_SHADER | ShaderGLSL::FRAGMENT_SHADER); if ( status == -1 ) { fprintf(stderr, "Error on loading %s\n", shaderFileBlit); exit( EXIT_FAILURE ); } // Compute locations for blit_shader GLuint blit_tex1Location = glGetUniformLocation(blit_shader.program, "Texture1"); // Load light accumulation shader ShaderGLSL lighting_shader; const char * shaderFileLighting = "002/2_lighta.glsl"; //int status = load_shader_from_file(lighting_shader, shaderFileLighting, ShaderGLSL::VERTEX_SHADER | ShaderGLSL::FRAGMENT_SHADER | ShaderGLSL::GEOMETRY_SHADER); status = load_shader_from_file(lighting_shader, shaderFileLighting, ShaderGLSL::VERTEX_SHADER | ShaderGLSL::FRAGMENT_SHADER); if ( status == -1 ) { fprintf(stderr, "Error on loading %s\n", shaderFileLighting); exit( EXIT_FAILURE ); } // Compute locations for lighting_shader GLuint lighting_materialLocation = glGetUniformLocation(lighting_shader.program, "Material"); GLuint lighting_normalLocation = glGetUniformLocation(lighting_shader.program, "Normal"); GLuint lighting_depthLocation = glGetUniformLocation(lighting_shader.program, "Depth"); GLuint lighting_inverseViewProjectionLocation = glGetUniformLocation(lighting_shader.program, "InverseViewProjection"); GLuint lighting_cameraPositionLocation = glGetUniformLocation(lighting_shader.program, "CameraPosition"); GLuint lighting_lightPositionLocation = glGetUniformLocation(lighting_shader.program, "LightPosition"); GLuint lighting_lightColorLocation = glGetUniformLocation(lighting_shader.program, "LightColor"); GLuint lighting_lightIntensityLocation = glGetUniformLocation(lighting_shader.program, "LightIntensity"); // Load geometry int cube_triangleCount = 12; int cube_triangleList[] = {0, 1, 2, 2, 1, 3, 4, 5, 6, 6, 5, 7, 8, 9, 10, 10, 9, 11, 12, 13, 14, 14, 13, 15, 16, 17, 18, 19, 17, 20, 21, 22, 23, 24, 25, 26, }; float cube_uvs[] = {0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f, 1.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f, 1.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f, 1.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f, 1.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f, 0.f, 1.f, 1.f, 0.f, 1.f, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 1.f, 1.f, 0.f, }; float cube_vertices[] = {-0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5 }; float cube_normals[] = {0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, }; int plane_triangleCount = 2; int plane_triangleList[] = {0, 1, 2, 2, 1, 3}; float plane_uvs[] = {0.f, 0.f, 0.f, 10.f, 10.f, 0.f, 10.f, 10.f}; float plane_vertices[] = {-50.0, -1.0, 50.0, 50.0, -1.0, 50.0, -50.0, -1.0, -50.0, 50.0, -1.0, -50.0}; float plane_normals[] = {0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0}; int quad_triangleCount = 2; int quad_triangleList[] = {0, 1, 2, 2, 1, 3}; float quad_vertices[] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0}; // Vertex Array Object GLuint vao[3]; glGenVertexArrays(3, vao); // Vertex Buffer Objects GLuint vbo[12]; glGenBuffers(12, vbo); // Cube glBindVertexArray(vao[0]); // Bind indices and upload data glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[0]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cube_triangleList), cube_triangleList, GL_STATIC_DRAW); // Bind vertices and upload data glBindBuffer(GL_ARRAY_BUFFER, vbo[1]); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*3, (void*)0); glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices), cube_vertices, GL_STATIC_DRAW); // Bind normals and upload data glBindBuffer(GL_ARRAY_BUFFER, vbo[2]); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*3, (void*)0); glBufferData(GL_ARRAY_BUFFER, sizeof(cube_normals), cube_normals, GL_STATIC_DRAW); // Bind uv coords and upload data glBindBuffer(GL_ARRAY_BUFFER, vbo[3]); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*2, (void*)0); glBufferData(GL_ARRAY_BUFFER, sizeof(cube_uvs), cube_uvs, GL_STATIC_DRAW); // Plane glBindVertexArray(vao[1]); // Bind indices and upload data glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[4]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(plane_triangleList), plane_triangleList, GL_STATIC_DRAW); // Bind vertices and upload data glBindBuffer(GL_ARRAY_BUFFER, vbo[5]); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*3, (void*)0); glBufferData(GL_ARRAY_BUFFER, sizeof(plane_vertices), plane_vertices, GL_STATIC_DRAW); // Bind normals and upload data glBindBuffer(GL_ARRAY_BUFFER, vbo[6]); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*3, (void*)0); glBufferData(GL_ARRAY_BUFFER, sizeof(plane_normals), plane_normals, GL_STATIC_DRAW); // Bind uv coords and upload data glBindBuffer(GL_ARRAY_BUFFER, vbo[7]); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*2, (void*)0); glBufferData(GL_ARRAY_BUFFER, sizeof(plane_uvs), plane_uvs, GL_STATIC_DRAW); // Quad glBindVertexArray(vao[2]); // Bind indices and upload data glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[8]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quad_triangleList), quad_triangleList, GL_STATIC_DRAW); // Bind vertices and upload data glBindBuffer(GL_ARRAY_BUFFER, vbo[9]); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*2, (void*)0); glBufferData(GL_ARRAY_BUFFER, sizeof(quad_vertices), quad_vertices, GL_STATIC_DRAW); // Unbind everything. Potentially illegal on some implementations glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); // Init frame buffers GLuint gbufferFbo; GLuint gbufferTextures[3]; GLuint gbufferDrawBuffers[2]; glGenTextures(3, gbufferTextures); // Create color texture glBindTexture(GL_TEXTURE_2D, gbufferTextures[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, 0); //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Create normal texture glBindTexture(GL_TEXTURE_2D, gbufferTextures[1]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, 0); //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Create depth texture glBindTexture(GL_TEXTURE_2D, gbufferTextures[2]); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Create Framebuffer Object glGenFramebuffers(1, &gbufferFbo); glBindFramebuffer(GL_FRAMEBUFFER, gbufferFbo); // Attach textures to framebuffer glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 , GL_TEXTURE_2D, gbufferTextures[0], 0); gbufferDrawBuffers[0] = GL_COLOR_ATTACHMENT0; glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1 , GL_TEXTURE_2D, gbufferTextures[1], 0); gbufferDrawBuffers[1] = GL_COLOR_ATTACHMENT1; glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, gbufferTextures[2], 0); if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { fprintf(stderr, "Error on building framebuffer\n"); exit( EXIT_FAILURE ); } glBindFramebuffer(GL_FRAMEBUFFER, 0); do { t = glfwGetTime(); // Mouse states int leftButton = glfwGetMouseButton( GLFW_MOUSE_BUTTON_LEFT ); int rightButton = glfwGetMouseButton( GLFW_MOUSE_BUTTON_RIGHT ); int middleButton = glfwGetMouseButton( GLFW_MOUSE_BUTTON_MIDDLE ); if( leftButton == GLFW_PRESS ) guiStates.turnLock = true; else guiStates.turnLock = false; if( rightButton == GLFW_PRESS ) guiStates.zoomLock = true; else guiStates.zoomLock = false; if( middleButton == GLFW_PRESS ) guiStates.panLock = true; else guiStates.panLock = false; // Camera movements int altPressed = glfwGetKey(GLFW_KEY_LSHIFT); if (!altPressed && (leftButton == GLFW_PRESS || rightButton == GLFW_PRESS || middleButton == GLFW_PRESS)) { int x; int y; glfwGetMousePos(&x, &y); guiStates.lockPositionX = x; guiStates.lockPositionY = y; } if (altPressed == GLFW_PRESS) { int mousex; int mousey; glfwGetMousePos(&mousex, &mousey); int diffLockPositionX = mousex - guiStates.lockPositionX; int diffLockPositionY = mousey - guiStates.lockPositionY; if (guiStates.zoomLock) { float zoomDir = 0.0; if (diffLockPositionX > 0) zoomDir = -1.f; else if (diffLockPositionX < 0 ) zoomDir = 1.f; camera_zoom(camera, zoomDir * GUIStates::MOUSE_ZOOM_SPEED); } else if (guiStates.turnLock) { camera_turn(camera, diffLockPositionY * GUIStates::MOUSE_TURN_SPEED, diffLockPositionX * GUIStates::MOUSE_TURN_SPEED); } else if (guiStates.panLock) { camera_pan(camera, diffLockPositionX * GUIStates::MOUSE_PAN_SPEED, diffLockPositionY * GUIStates::MOUSE_PAN_SPEED); } guiStates.lockPositionX = mousex; guiStates.lockPositionY = mousey; } // Get camera matrices glm::mat4 projection = glm::perspective(45.0f, widthf / heightf, 0.1f, 100.f); glm::mat4 worldToView = glm::lookAt(camera.eye, camera.o, camera.up); glm::mat4 objectToWorld; glm::mat4 worldToScreen = projection * worldToView; glm::mat4 screenToWorld = glm::transpose(glm::inverse(worldToScreen)); glBindFramebuffer(GL_FRAMEBUFFER, gbufferFbo); glDrawBuffers(2, gbufferDrawBuffers); // Viewport glViewport( 0, 0, width, height ); // Default states glEnable(GL_DEPTH_TEST); // Clear the front buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Bind gbuffer shader glUseProgram(gbuffer_shader.program); // Upload uniforms glUniformMatrix4fv(gbuffer_projectionLocation, 1, 0, glm::value_ptr(projection)); glUniformMatrix4fv(gbuffer_viewLocation, 1, 0, glm::value_ptr(worldToView)); glUniformMatrix4fv(gbuffer_objectLocation, 1, 0, glm::value_ptr(objectToWorld)); glUniform1f(gbuffer_timeLocation, t); glUniform1i(gbuffer_diffuseLocation, 0); glUniform1i(gbuffer_specLocation, 1); // Bind textures glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textures[0]); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textures[1]); // Render vaos glBindVertexArray(vao[0]); glDrawElementsInstanced(GL_TRIANGLES, cube_triangleCount * 3, GL_UNSIGNED_INT, (void*)0, 4); glBindVertexArray(vao[1]); glDrawElements(GL_TRIANGLES, plane_triangleCount * 3, GL_UNSIGNED_INT, (void*)0); // Unbind framebuffer glBindFramebuffer(GL_FRAMEBUFFER, 0); // Viewport glViewport( 0, 0, width, height ); // Clear the front buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Bind lighting shader glUseProgram(lighting_shader.program); // Upload uniforms glUniform1i(lighting_materialLocation, 0); glUniform1i(lighting_normalLocation, 1); glUniform1i(lighting_depthLocation, 2); glUniform3fv(lighting_cameraPositionLocation, 1, glm::value_ptr(camera.eye)); glUniformMatrix4fv(lighting_inverseViewProjectionLocation, 1, 0, glm::value_ptr(screenToWorld)); // Bind color to unit 0 glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, gbufferTextures[0]); // Bind normal to unit 1 glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, gbufferTextures[1]); // Bind depth to unit 2 glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, gbufferTextures[2]); // Blit above the rest glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); for (int i = 0; i < (int) numLights; ++i) { float tl = t * i; //Update light uniforms float lightPosition[3] = { sinf(tl) * 10.f, -0.5f, cosf(tl) * 10.f}; float lightColor[3] = {sinf(tl) * 1.f, 1.f - cosf(tl), -sinf(tl)}; float lightIntensity = 10.0; glUniform3fv(lighting_lightPositionLocation, 1, lightPosition); glUniform3fv(lighting_lightColorLocation, 1, lightColor); glUniform1f(lighting_lightIntensityLocation, lightIntensity); // Draw quad glBindVertexArray(vao[2]); glDrawElements(GL_TRIANGLES, quad_triangleCount * 3, GL_UNSIGNED_INT, (void*)0); } glDisable(GL_BLEND); // Bind blit shader glUseProgram(blit_shader.program); // Upload uniforms glUniform1i(blit_tex1Location, 0); // use only unit 0 glActiveTexture(GL_TEXTURE0); // Viewport glViewport( 0, 0, width/3, height/4 ); // Bind texture glBindTexture(GL_TEXTURE_2D, gbufferTextures[0]); // Draw quad glBindVertexArray(vao[2]); glDrawElements(GL_TRIANGLES, quad_triangleCount * 3, GL_UNSIGNED_INT, (void*)0); // Viewport glViewport( width/3, 0, width/3, height/4 ); // Bind texture glBindTexture(GL_TEXTURE_2D, gbufferTextures[1]); // Draw quad glBindVertexArray(vao[2]); glDrawElements(GL_TRIANGLES, quad_triangleCount * 3, GL_UNSIGNED_INT, (void*)0); // Viewport glViewport( width/3 * 2, 0, width/3, height/4 ); // Bind texture glBindTexture(GL_TEXTURE_2D, gbufferTextures[2]); // Draw quad glBindVertexArray(vao[2]); glDrawElements(GL_TRIANGLES, quad_triangleCount * 3, GL_UNSIGNED_INT, (void*)0); #if 1 // Draw UI glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glViewport(0, 0, width, height); unsigned char mbut = 0; int mscroll = 0; int mousex; int mousey; glfwGetMousePos(&mousex, &mousey); mousey = height - mousey; if( leftButton == GLFW_PRESS ) mbut |= IMGUI_MBUT_LEFT; imguiBeginFrame(mousex, mousey, mbut, mscroll); int logScroll = 0; char lineBuffer[512]; imguiBeginScrollArea("001", width - 210, height - 310, 200, 300, &logScroll); sprintf(lineBuffer, "FPS %f", fps); imguiLabel(lineBuffer); imguiSlider("Lights", &numLights, 0.0, 100.0, 1.0); imguiEndScrollArea(); imguiEndFrame(); imguiRenderGLDraw(width, height); glDisable(GL_BLEND); #endif // Check for errors GLenum err = glGetError(); if(err != GL_NO_ERROR) { fprintf(stderr, "OpenGL Error : %s\n", gluErrorString(err)); } // Swap buffers glfwSwapBuffers(); } // Check if the ESC key was pressed or the window was closed while( glfwGetKey( GLFW_KEY_ESC ) != GLFW_PRESS && glfwGetWindowParam( GLFW_OPENED ) ); // Clean UI imguiRenderGLDestroy(); // Close OpenGL window and terminate GLFW glfwTerminate(); exit( EXIT_SUCCESS ); }
int main(int argc, char **argv) { // SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); // SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); /* initialize OpenGL */ initGraphics(800,600,0); initGL( ); initInput(); renderInit(); imguiRenderGLInit("DroidSans.ttf"); curl_global_init(CURL_GLOBAL_ALL); FW::FileWatcher* watcher = new FW::FileWatcher(); /*FW::WatchID watchid = */watcher->addWatch( "./", new RecompileListener() ); recompile(); /* resize the initial window */ // resizeWindow( xres, yres ); /* These are to calculate our fps */ static GLint T0 = 0; static GLint Frames = 0; /* wait for events */ bool done = false; SDL_Event event; while ( !done ) { /* handle the events in the queue */ while ( SDL_PollEvent( &event ) ) { switch( event.type ) { //case SDL_ACTIVEEVENT: /* Something's happend with our focus * If we lost focus or we are iconified, we * shouldn't draw the screen */ //if ( event.active.gain == 0 ) // isActive = FALSE; // else // isActive = TRUE; // break; #if 0 case SDL_VIDEORESIZE: /* handle resize event */ surface = SDL_SetVideoMode( event.resize.w, event.resize.h, 16, videoFlags ); if ( !surface ) { fprintf( stderr, "Could not get a surface after resize: %s\n", SDL_GetError( ) ); Quit( 1 ); } resizeWindow( event.resize.w, event.resize.h ); break; #endif case SDL_KEYDOWN: /* handle key presses */ handleKeyPress( &event.key.keysym ); break; case SDL_KEYUP: if(event.key.keysym.sym<=255){ keystat[event.key.keysym.sym] = 0; } break; case SDL_MOUSEMOTION: mousexr = event.motion.xrel; mouseyr = event.motion.yrel; mousex = event.motion.x; mousey = event.motion.y; break; case SDL_MOUSEBUTTONDOWN: mousestat[event.button.button] = 1; break; case SDL_MOUSEBUTTONUP: mousestat[event.button.button] = 0; break; case SDL_QUIT: /* handle quit requests */ done = TRUE; break; default: break; } } /* draw the scene */ //if ( isActive ) { watcher->update(); //glClearColor(1, 0, 0, 1); //glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); if(update) { update(); } /* glMatrixMode(GL_PROJECTION); glLoadIdentity(); float projection[16] = { 2.f/800, 0.f, 0.f, 0.f, 0.f, 2.f/600, 0.f, 0.f, 0.f, 0.f, -2.f, 0.f, -1.f, -1.f, -1.f, 1.f }; glLoadMatrixf(projection); glMatrixMode(GL_MODELVIEW); glLoadIdentity();*/ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_DEPTH_TEST); imguiRenderGLDraw(800, 600); /* glBegin(GL_TRIANGLES); glColor3f(1, 1, 0); glVertex2d(1, 1); glVertex2d(1, 0); glVertex2d(0, 1); glEnd(); */ /* Draw it to the screen */ swapBuffers(); /* Gather our frames per second */ Frames++; { GLint t = SDL_GetTicks(); if (t - T0 < 16) { // SDL_Delay(16 - (t-T0)); // GLfloat seconds = (t - T0) / 1000.f; // GLfloat fps = Frames / seconds; // Frames = 0; } T0 = t; } } } imguiRenderGLDestroy(); renderFini(); /* clean ourselves up and exit */ Quit( 0 ); /* Should never get here */ return( 0 ); }
bool Visualization::initialize() { m_initialized = true; m_mousePosition[0] = m_mousePosition[1] = 1; m_crowdAvailableDt = 0.f; m_stopRequested = false; m_rotating = false; if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { printf("Could not initialize SDL.\n"); m_initialized = false; } else { // Center window char env[] = "SDL_VIDEO_CENTERED=1"; #ifdef _MSC_VER _putenv(env); #else putenv(env); #endif // Init OpenGL SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); //#ifndef WIN32 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); //#endif const SDL_VideoInfo* vi = SDL_GetVideoInfo(); SDL_Surface* screen = 0; if (m_fullscreen) { m_winWidth = vi->current_w; m_winHeight = vi->current_h; screen = SDL_SetVideoMode(m_winWidth, m_winHeight, 0, SDL_OPENGL|SDL_FULLSCREEN); } else { m_winWidth = vi->current_w - 20; m_winHeight = vi->current_h - 80; screen = SDL_SetVideoMode(m_winWidth, m_winHeight, 0, SDL_OPENGL); } if (!screen) { printf("Could not initialise SDL opengl.\n"); m_initialized = false; } else { glEnable(GL_MULTISAMPLE); SDL_WM_SetCaption("Detour Crowd Demo", 0); if (!imguiRenderGLInit("DroidSans.ttf")) { printf("Could not init GUI renderer.\n"); m_initialized = false; } else if (!initializeCamera()) { printf("Unable to initialize the camera.\n"); m_initialized = false; } else if (m_debugInfo == 0 || !m_debugInfo->initialize()) { printf("Unable to initialize the crowd debug info.\n"); m_initialized = false; } else { m_initialized = true; glEnable(GL_CULL_FACE); float fogCol[4] = { 0.32f, 0.31f, 0.30f, 1.0f }; glEnable(GL_FOG); glFogi(GL_FOG_MODE, GL_LINEAR); glFogf(GL_FOG_START, m_zFar*0.1f); glFogf(GL_FOG_END, m_zFar*1.25f); glFogfv(GL_FOG_COLOR, fogCol); glDepthFunc(GL_LEQUAL); m_lastTickCount = SDL_GetTicks(); // Extract OpenGL view properties glGetDoublev(GL_PROJECTION_MATRIX, m_projection); glGetDoublev(GL_MODELVIEW_MATRIX, m_modelView); glGetIntegerv(GL_VIEWPORT, m_viewport); } } } if (!m_initialized) { SDL_Quit(); } return m_initialized; }