//-------------------------------------------------------------------------------------- // //-------------------------------------------------------------------------------------- void InitGUI() { // Initialize dialogs g_SettingsDlg.Init(&g_DialogResourceManager); g_HUD.Init(&g_DialogResourceManager); g_HUD.SetCallback(OnGUIEvent); g_TextRenderer.Init(&g_DialogResourceManager); int iY = 10; g_HUD.AddButton (IDC_TOGGLEFULLSCREEN, L"Toggle full screen" , 35, iY, 160, 22); g_HUD.AddButton (IDC_TOGGLEREF, L"Toggle REF (F3)" , 35, iY += 24, 160, 22, VK_F3); g_HUD.AddButton (IDC_CHANGEDEVICE, L"Change device (F2)" , 35, iY += 24, 160, 22, VK_F2); iY += 20; g_HUD.AddCheckBox(IDC_DEINTERLEAVE, L"Deinterleaved Texturing", 35, iY += 28, 125, 22, g_UseDeinterleavedTexturing); g_HUD.AddCheckBox(IDC_RANDOMIZE, L"Randomize Samples", 35, iY += 28, 125, 22, g_RandomizeSamples); g_HUD.AddCheckBox(IDC_BLUR_AO, L"Blur AO", 35, iY += 28, 125, 22, g_BlurAO); iY += 24; CDXUTComboBox *pComboBox; g_HUD.AddComboBox(IDC_CHANGESCENE, 35, iY += 24, 160, 22, 'M', false, &pComboBox); for (int i = 0; i < ARRAYSIZE(g_MeshDesc); i++) { pComboBox->AddItem(g_MeshDesc[i].Name, NULL); } iY += 24; WCHAR sz[100]; int dy = 20; StringCchPrintf(sz, 100, UI_RADIUS_MULT L"%0.2f", g_AOParams.Radius); g_HUD.AddStatic(IDC_RADIUS_STATIC, sz, 35, iY += dy, 125, 22); g_HUD.AddSlider(IDC_RADIUS_SLIDER, 50, iY += dy, 100, 22, 0, 100, int(g_AOParams.Radius / MAX_RADIUS_MULT * 100)); StringCchPrintf(sz, 100, UI_AO_BIAS L"%g", g_AOParams.Bias); g_HUD.AddStatic(IDC_BIAS_STATIC, sz, 35, iY += dy, 125, 22); g_HUD.AddSlider(IDC_BIAS_SLIDER, 50, iY += dy, 100, 22, 0, 500, int(g_AOParams.Bias * 1000)); StringCchPrintf(sz, 100, UI_POW_EXPONENT L"%0.2f", g_AOParams.PowerExponent); g_HUD.AddStatic(IDC_EXPONENT_STATIC, sz, 35, iY += dy, 125, 22); g_HUD.AddSlider(IDC_EXPONENT_SLIDER, 50, iY += dy, 100, 22, 0, 400, (int)(100.0f*g_AOParams.PowerExponent)); StringCchPrintf(sz, 100, UI_BLUR_SHARPNESS L"%0.2f", g_AOParams.Blur.Sharpness); g_HUD.AddStatic(IDC_BLUR_SHARPNESS_STATIC, sz, 35, iY += dy, 125, 22); g_HUD.AddSlider(IDC_BLUR_SHARPNESS_SLIDER, 50, iY += dy, 100, 22, 0, 1600, (int)(100.0f*g_AOParams.Blur.Sharpness)); UINT ButtonGroup = 0; iY += 24; g_HUD.AddRadioButton( IDC_1xMSAA, ButtonGroup, L"1X MSAA", 35, iY += 24, 125, 22, (g_MSAACurrentSettings == MSAA_MODE_1X) ); g_HUD.AddRadioButton( IDC_2xMSAA, ButtonGroup, L"2X MSAA", 35, iY += 24, 125, 22, (g_MSAACurrentSettings == MSAA_MODE_2X) ); g_HUD.AddRadioButton( IDC_4xMSAA, ButtonGroup, L"4X MSAA", 35, iY += 24, 125, 22, (g_MSAACurrentSettings == MSAA_MODE_4X) ); g_HUD.AddRadioButton( IDC_8xMSAA, ButtonGroup, L"8X MSAA", 35, iY += 24, 125, 22, (g_MSAACurrentSettings == MSAA_MODE_8X) ); ++ButtonGroup; iY += 24; g_HUD.AddRadioButton( IDC_PER_PIXEL_AO, ButtonGroup, L"PER_PIXEL_AO", 35, iY += 24, 125, 22, (g_AOParams.Output.MSAAMode == GFSDK_SSAO_PER_PIXEL_AO) ); g_HUD.AddRadioButton( IDC_PER_SAMPLE_AO, ButtonGroup, L"PER_SAMPLE_AO", 35, iY += 24, 125, 22, (g_AOParams.Output.MSAAMode == GFSDK_SSAO_PER_SAMPLE_AO) ); }
int main() { InitGlfw initGlfw; ShaderLoader shaderLoader; TextureLoader textureLoader; TextRenderer textRenderer; // Init initGlfw.Init(); textRenderer.Init(); glfwSetKeyCallback(initGlfw.window, KeyCallback); glfwSetMouseButtonCallback(initGlfw.window, MouseButtonCallback); glfwSetCursorPosCallback(initGlfw.window, MouseMoveCallback); // Shader loading GLuint defaultShaderProgram; GLuint textShaderProgram; GLuint simpleShaderProgram; defaultShaderProgram = shaderLoader.CreateProgram("Shaders\\vertex_shader.glsl", "Shaders\\fragment_shader.glsl"); textShaderProgram = shaderLoader.CreateProgram("Shaders\\text_vs.glsl", "Shaders\\text_fs.glsl"); simpleShaderProgram = shaderLoader.CreateProgram("Shaders\\simple_vertex_shader.glsl", "Shaders\\simple_fragment_shader.glsl"); // Load texture GLuint texture = textureLoader.LoadRGB("Images\\container.jpg"); GLuint blankTexture = textureLoader.LoadBlank(); cout << "Blank texture status: " << blankTexture << endl; // Define camera component vectors float wallDistanceMargin = 0.2f; float currentX; float currentZ; glm::vec3 cameraPos = glm::vec3(0.0f, -0.5f, 6.0f); glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f); glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f); float yaw = -90.0f; glm::vec3 front(cos(glm::radians(yaw)), 0.0f, sin(glm::radians(yaw))); // Define model and view matrices and get shader locations GLuint modelLocation = glGetUniformLocation(defaultShaderProgram, "model"); GLuint viewLocation = glGetUniformLocation(defaultShaderProgram, "view"); GLuint projectionLocation = glGetUniformLocation(defaultShaderProgram, "projection"); double currentTime = glfwGetTime(); double delta; glm::mat4 view; glm::mat4 proj1; glm::mat4 idm = glm::mat4(); // Hard-coded virtual environment Square backWall; Square leftWall; Square rightWall; Square floorSquare; Square frontWall; Square rewardZone; float corridorDepth = 10.0f; float corridorWidth = 3.0f; float wallHeight = 2.0f; float rewardZoneDepth = 2.0f; float rewardZonePosition = -3.0f; float rewardZoneLowZ = rewardZonePosition - rewardZoneDepth; float rewardZoneHighZ = rewardZonePosition + rewardZoneDepth; bool inRewardZone = false; backWall.SetColor(0.5f, 0.5f, 0.9f); backWall.SetScaling(corridorWidth, wallHeight); backWall.SetPosition(0.0f, wallHeight/2, -corridorDepth); frontWall.SetColor(0.5f, 0.5f, 0.9f); frontWall.SetScaling(corridorWidth, wallHeight); frontWall.SetPosition(0.0f, wallHeight / 2.0f, corridorDepth); leftWall.SetColor(0.5f, 0.9f, 0.5f); leftWall.SetScaling(corridorDepth, wallHeight); leftWall.SetRotation(0.0f, 90.0f, 0.0f); leftWall.SetPosition(-corridorWidth, wallHeight/2, 0.0f); rightWall.SetColor(0.5f, 0.9f, 0.5f); rightWall.SetScaling(corridorDepth, wallHeight); rightWall.SetRotation(0.0f, 90.0f, 0.0f); rightWall.SetPosition(corridorWidth,wallHeight/2, 0.0f); floorSquare.SetColor(0.1f, 0.1f, 0.1f); floorSquare.SetScaling(corridorWidth, corridorDepth); floorSquare.SetRotation(-90.0f, 0.0f, 0.0f); floorSquare.SetPosition(0.0f, -wallHeight/2.0f, 0.0f); rewardZone.SetColor(0.2f, 0.9f, 0.2f); rewardZone.SetScaling(corridorWidth, rewardZoneDepth); rewardZone.SetRotation(-90.0f, 0.0f, 0.0f); rewardZone.SetPosition(0.0f, -wallHeight / 2.0f + 0.01f, rewardZonePosition); proj1 = glm::perspective(45.0f, (float)2.0f*initGlfw.windowInfo.width / initGlfw.windowInfo.height, 0.1f, 100.0f); glEnable(GL_DEPTH_TEST); // Create frame buffer for offscreen rendering, configured to draw to a texture buffer from which we sample // to draw on each window. GLuint frameBufferObject; GLuint frameBufferTexture; GLuint renderBufferObject; int fullWidth = 2*initGlfw.windowInfo.width; glGenTextures(1, &frameBufferTexture); glBindTexture(GL_TEXTURE_2D, frameBufferTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fullWidth, initGlfw.windowInfo.height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); glGenRenderbuffers(1, &renderBufferObject); glBindRenderbuffer(GL_RENDERBUFFER, renderBufferObject); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, fullWidth, initGlfw.windowInfo.height); glBindRenderbuffer(GL_RENDERBUFFER, 0); glGenFramebuffers(1, &frameBufferObject); glBindFramebuffer(GL_FRAMEBUFFER, frameBufferObject); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, frameBufferTexture, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderBufferObject); glBindFramebuffer(GL_FRAMEBUFFER, 0); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) cout << "Framebuffer completed" << endl; // Generate quads for left and right window GLfloat leftScreenVertices[] = { // Positions // TexCoords -1.0f, 1.0f, 0.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.5f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 0.5f, 0.0f, 1.0f, 1.0f, 0.5f, 1.0f }; GLfloat rightScreenVertices[] = { // Positions // TexCoords -1.0f, 1.0f, 0.5f, 1.0f, -1.0f, -1.0f, 0.5f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.5f, 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f }; GLuint leftScreenVBO; GLuint rightScreenVBO; glGenBuffers(1, &leftScreenVBO); glBindBuffer(GL_ARRAY_BUFFER, leftScreenVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(leftScreenVertices), leftScreenVertices, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glGenBuffers(1, &rightScreenVBO); glBindBuffer(GL_ARRAY_BUFFER, rightScreenVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(rightScreenVertices), rightScreenVertices, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); // Game loop int updateTick = 0; while (!glfwWindowShouldClose(initGlfw.window)) { // Get time delta = glfwGetTime() - currentTime; currentTime = glfwGetTime(); std::string fpsString = "FPS: " + std::to_string(delta); // Update view matrix // sensor readings need to be plugged in here front = glm::vec3(cos(glm::radians(yaw)), 0.0f, sin(glm::radians(yaw))); currentX = cameraPos.x; currentZ = cameraPos.z; cameraPos += yVelocity * front; cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp)) * xVelocity; // Collision detection, reset to previous position if wall boundary is crossed if ( (cameraPos.x-wallDistanceMargin) < -corridorWidth | (cameraPos.x + wallDistanceMargin)> corridorWidth) cameraPos.x = currentX; if ((cameraPos.z-wallDistanceMargin) < -corridorDepth | (cameraPos.z + wallDistanceMargin) > corridorDepth) cameraPos.z = currentZ; // Check reward zone entries if (!inRewardZone && (cameraPos.z > rewardZoneLowZ && cameraPos.z < rewardZoneHighZ)) { inRewardZone = true; cout << "Reward zone ENTRY detected." << endl; } if (inRewardZone && (cameraPos.z < rewardZoneLowZ || cameraPos.z > rewardZoneHighZ)) { inRewardZone = false; cout << "Reward zone EXIT detected." << endl; } view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp); // Draw the complete screen to the offscreen framebuffer glfwMakeContextCurrent(initGlfw.window); glBindFramebuffer(GL_FRAMEBUFFER, frameBufferObject); glViewport(0, 0, fullWidth, initGlfw.windowInfo.height); glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (showFPS) textRenderer.RenderText(textShaderProgram, fpsString, 0.0f, GLfloat(initGlfw.windowInfo.height - 20), 1.0, glm::vec3(0.8, 0.6, 0.6)); glUseProgram(defaultShaderProgram); glUniformMatrix4fv(viewLocation, 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, glm::value_ptr(proj1)); glUniformMatrix4fv(modelLocation, 1, GL_FALSE, glm::value_ptr(idm)); glBindTexture(GL_TEXTURE_2D, texture); frontWall.Draw(); backWall.Draw(); leftWall.Draw(); rightWall.Draw(); floorSquare.Draw(); glBindTexture(GL_TEXTURE_2D, blankTexture); rewardZone.Draw(); glBindTexture(GL_TEXTURE_2D, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); // First monitor drawing calls //glfwMakeContextCurrent(initGlfw.window); glClear(GL_COLOR_BUFFER_BIT); glDisable(GL_DEPTH_TEST); glViewport(0, 0, initGlfw.windowInfo.width, initGlfw.windowInfo.height); glUseProgram(simpleShaderProgram); glBindTexture(GL_TEXTURE_2D, frameBufferTexture); glBindBuffer(GL_ARRAY_BUFFER, rightScreenVBO); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)(2 * sizeof(GLfloat))); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glDrawArrays(GL_TRIANGLES, 0, 6); glBindBuffer(GL_ARRAY_BUFFER, 0); glfwSwapBuffers(initGlfw.window); // Second monitor drawing calls glfwMakeContextCurrent(initGlfw.window2); glClear(GL_COLOR_BUFFER_BIT); glDisable(GL_DEPTH_TEST); glUseProgram(simpleShaderProgram); glBindTexture(GL_TEXTURE_2D, frameBufferTexture); glBindBuffer(GL_ARRAY_BUFFER, leftScreenVBO); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)(2 * sizeof(GLfloat))); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glDrawArrays(GL_TRIANGLES, 0, 6); glBindBuffer(GL_ARRAY_BUFFER, 0); glfwSwapBuffers(initGlfw.window2); // Check events glfwPollEvents(); // Output information ++updateTick; if (updateTick % 60 == 0) { cout << "Camera position: (" << cameraPos.x << ", " << cameraPos.y << ", " << cameraPos.z << ")" << endl; updateTick = 0; } } glfwTerminate(); // Clean up after exiting glDeleteFramebuffers(1, &frameBufferObject); return 0; }