Guest User

Untitled

a guest
Jul 31st, 2012
218
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.14 KB | None | 0 0
  1. #include "DeferredRenderingGame.h"
  2.  
  3. namespace rps_test_game {
  4.  
  5.     DeferredRenderingGame::DeferredRenderingGame(void)
  6.         : CGame()
  7.     {
  8.         scene = NULL;
  9.  
  10.         camera = CFreeCamera();
  11.  
  12.         gBufferColorShader = NULL;
  13.         gBufferDebugShader = NULL;
  14.  
  15.         gBuffer = NULL;
  16.  
  17.         gBufferDisplay = GBufferDisplays::All;
  18.         drawAABB = true;
  19.         drawLightGeometry = false;
  20.  
  21.         bunnyRenderableMesh = NULL;
  22.         sponzaRenderableMesh = NULL;
  23.         fullscreenQuadMesh = NULL;
  24.         sphereMesh = NULL;
  25.  
  26.         setWindowSize(ivec2(1280, 720));
  27.     }
  28.  
  29.     DeferredRenderingGame::~DeferredRenderingGame(void)
  30.     {
  31.         // Nothing to release, everything is destroyed from content manager or in freeGame
  32.     }
  33.  
  34.     float randomFloatRange(float a, float b)
  35.     {
  36.         return ((b-a)*((float)rand()/RAND_MAX))+a;
  37.     }
  38.  
  39.     float randomColorFloat() {
  40.         return randomFloatRange(0.0f, 1.0f);
  41.     }
  42.  
  43.     vec4 randomColor() {
  44.         return vec4(randomColorFloat(), randomColorFloat(), randomColorFloat(), 1.0f);
  45.     }
  46.  
  47.     void DeferredRenderingGame::initGame() {
  48.         rend = getRenderer();
  49.  
  50.         rend->clearColor(0.0f, 0.0f, 0.0f, 1.0f);
  51.  
  52.         scene = new CScene();
  53.  
  54.         fullscreenQuadMesh = getContentMng()->genRenderableQuad(vec2(2.0f, 2.0f), "");
  55.         sphereMesh = getContentMng()->loadRenderableMesh("sphere/sphere.obj", "");
  56.         bunnyRenderableMesh = getContentMng()->loadRenderableMesh("stanford_bunny/bunny.rps", "bunny>");
  57.         sponzaRenderableMesh = getContentMng()->loadRenderableMesh("sponza/sponza.rps", "sponza>");
  58.  
  59.         gBufferColorShader = getContentMng()->loadShader("gbuffer_color", "GBuffer.vert", "GBuffer_Color.frag");
  60.         gBufferDebugShader = getContentMng()->loadShader("gbuffer_debug", "GBuffer_Debug.vert", "GBuffer_Debug.frag");
  61.         pointLightShader = getContentMng()->loadShader("pointlight", "PointLight.vert", "PointLight.frag");
  62.         directionalLightShader = getContentMng()->loadShader("directionallight", "DirectionalLight.vert", "DirectionalLight.frag");
  63.  
  64.         gBuffer = getContentMng()->createFramebuffer("gbuffer", getWindowSize());
  65.         gBuffer->addRenderTarget(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_ATTACHMENT, "depth", GL_NEAREST);
  66.         gBuffer->addTextureTarget(GL_RGBA32F, GL_RGBA, GL_FLOAT, GL_COLOR_ATTACHMENT0, "pos", GL_NEAREST);
  67.         gBuffer->addTextureTarget(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, GL_COLOR_ATTACHMENT1, "normal", GL_LINEAR);
  68.         gBuffer->addTextureTarget(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, GL_COLOR_ATTACHMENT2, "diffuse", GL_LINEAR);
  69.         gBuffer->update();
  70.  
  71.         lightBuffer = getContentMng()->createFramebuffer("lightbuffer", getWindowSize());
  72.         lightBuffer->addTextureTarget(GL_RGBA32F, GL_RGBA, GL_FLOAT, GL_COLOR_ATTACHMENT0, "lightBuffer", GL_LINEAR);
  73.         lightBuffer->update();
  74.  
  75.         scene->add(new CMeshSceneNode(sponzaRenderableMesh, mat4(), true));
  76.         scene->add(new CMeshSceneNode(bunnyRenderableMesh, glm::scale(mat4(), vec3(10.0f, 10.0f, 10.0f)), false));
  77.  
  78.         lightNodes.push_back(new CSceneLightNode(LightTypes::Directional, vec3(0.0f, 1000.0f, 0.0f), 0.0f));
  79.  
  80.         float lightStart = -1000.0f;
  81.         float lightEnd = 1000.0f;
  82.  
  83.         float lightCur = lightStart;
  84.         while (lightCur < lightEnd) {
  85.             lightNodes.push_back(new CSceneLightNode(LightTypes::Point, vec3(lightCur, 50.0f, 0.0f), 200.0f, randomColor()));
  86.  
  87.             lightNodes.push_back(new CSceneLightNode(LightTypes::Point, vec3(lightCur, 50.0f, -550.0f), 200.0f, randomColor()));
  88.             lightNodes.push_back(new CSceneLightNode(LightTypes::Point, vec3(lightCur, 50.0f, -350.0f), 200.0f, randomColor()));
  89.  
  90.             lightNodes.push_back(new CSceneLightNode(LightTypes::Point, vec3(lightCur, 50.0f, 300.0f), 200.0f, randomColor()));
  91.             lightNodes.push_back(new CSceneLightNode(LightTypes::Point, vec3(lightCur, 50.0f, 500.0f), 200.0f, randomColor()));
  92.  
  93.             lightCur += 100.0f;
  94.         }
  95.  
  96.         for (unsigned int i = 0; i < lightNodes.size(); i++) {
  97.             scene->add(lightNodes[i]);
  98.         }
  99.  
  100.         frustum = CFrustum();
  101.         camera.setPos(0.0f, 2.5f, 20.0f);
  102.         camera.setAspect(getWindowAspect());
  103.     }
  104.  
  105.     void DeferredRenderingGame::freeGame() {
  106.         if (scene)
  107.             delete scene;
  108.     }
  109.  
  110.     void DeferredRenderingGame::updateGame(const float &frametime) {
  111.         // Update rendering states
  112.         if (CKeyboardInput::get()->isKeyPressed(Keys::Space)) {
  113.             CKeyboardInput::get()->setKeyPressed(Keys::Space, false);
  114.             gBufferDisplay++;
  115.             if (gBufferDisplay > 4) gBufferDisplay = 0;
  116.         }
  117.         if (CKeyboardInput::get()->isKeyPressed(Keys::G)) {
  118.             CKeyboardInput::get()->setKeyPressed(Keys::G, false);
  119.             drawLightGeometry = !drawLightGeometry;
  120.         }
  121.  
  122.         // Update camera
  123.         camera.setAspect(getWindowAspect());
  124.         FreeCameraControl ctrl = FreeCameraControl();
  125.         ctrl.mouseLook = CMouseInput::get()->isMousePressed(MouseButton::Left);
  126.         ctrl.mousePos = CMouseInput::get()->getMousePos();
  127.         if (CKeyboardInput::get()->isKeyPressed(Keys::W)) {
  128.             ctrl.forward = -200.0f * frametime;
  129.         } else if (CKeyboardInput::get()->isKeyPressed(Keys::S)) {
  130.             ctrl.forward = 200.0f * frametime;
  131.         }
  132.         if (CKeyboardInput::get()->isKeyPressed(Keys::A)) {
  133.             ctrl.strafe = -200.0f * frametime;
  134.         } else if (CKeyboardInput::get()->isKeyPressed(Keys::D)) {
  135.             ctrl.strafe = 200.0f * frametime;
  136.         }
  137.         if (CKeyboardInput::get()->isKeyPressed(Keys::Q)) {
  138.             ctrl.upDown = -200.0f * frametime;
  139.         } else if (CKeyboardInput::get()->isKeyPressed(Keys::E)) {
  140.             ctrl.upDown = 200.0f * frametime;
  141.         }
  142.         camera.update(ctrl);
  143.  
  144.         // Update frustum
  145.         frustum.update(camera.getProjection(), camera.getModelView());
  146.  
  147.         vec3 pos = camera.getPos();
  148.         char buffer[255];
  149.         sprintf_s(buffer, "%f, %f, %f", pos.x, pos.y, pos.z);
  150.         glfwSetWindowTitle(buffer);
  151.     }
  152.  
  153.     void DeferredRenderingGame::drawSceneIntoGBuffer(mat4 &camMV, mat4 &camProj) {
  154.         for (list<CSceneNode*>::iterator i = scene->getBegin(); i != scene->getEnd(); ++i) {
  155.             CSceneNode* node = *i;
  156.             if (node->isRenderable()) {
  157.                 mat4 modelview = node->getModelview();
  158.                 if (node->getType() == SceneNodeTypes::Mesh) {
  159.                     CMeshSceneNode* meshSceneNode = (CMeshSceneNode*)node;
  160.                     CRenderableMesh* mesh = meshSceneNode->getMeshInstance();
  161.  
  162.                     // Enable GBuffer color shader
  163.                     rend->enableShader(gBufferColorShader);
  164.                     gBufferColorShader->uniformMatrix4(gBufferColorShader->getUniformLocation("cam_proj"), &camProj[0][0]);
  165.                     gBufferColorShader->uniformMatrix4(gBufferColorShader->getUniformLocation("cam_view"), &camMV[0][0]);
  166.                     gBufferColorShader->uniform1f(gBufferColorShader->getUniformLocation("materialValue"), (float)GBufferMaterialFlags::Default);
  167.  
  168.                     // Draw mesh
  169.                     getRenderer()->loadMatrix(modelview);
  170.                     glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
  171.                     getRenderer()->drawMesh(mesh);
  172.  
  173.                     // Disable GBuffer color shader
  174.                     rend->disableShader(gBufferColorShader);
  175.  
  176.                     // Debug enabled?
  177.                     if (drawAABB) {
  178.                         // Enable GBuffer debug shader
  179.                         rend->enableShader(gBufferColorShader);
  180.                         gBufferColorShader->uniformMatrix4(gBufferColorShader->getUniformLocation("cam_proj"), &camProj[0][0]);
  181.                         gBufferColorShader->uniformMatrix4(gBufferColorShader->getUniformLocation("cam_view"), &camMV[0][0]);
  182.                         gBufferColorShader->uniform1f(gBufferColorShader->getUniformLocation("materialValue"), (float)GBufferMaterialFlags::NoLighting);
  183.  
  184.                         // Draw aabb or other debug stuff for mesh
  185.                         getRenderer()->loadMatrix(mat4());
  186.                         glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
  187.                         getRenderer()->drawAABB(meshSceneNode->getAABB());
  188.  
  189.                         // Disable GBuffer debug shader
  190.                         rend->disableShader(gBufferColorShader);
  191.                     }
  192.                 } else if (node->getType() == SceneNodeTypes::Light) {
  193.                     CSceneLightNode* lightNode = (CSceneLightNode*)node;
  194.                     Light light = lightNode->getLight();
  195.  
  196.                     if (drawLightGeometry) {
  197.                         // enable GBuffer color shader
  198.                         rend->enableShader(gBufferColorShader);
  199.                         gBufferColorShader->uniformMatrix4(gBufferColorShader->getUniformLocation("cam_proj"), &camProj[0][0]);
  200.                         gBufferColorShader->uniformMatrix4(gBufferColorShader->getUniformLocation("cam_view"), &camMV[0][0]);
  201.                         gBufferColorShader->uniform1f(gBufferColorShader->getUniformLocation("materialValue"), (float)GBufferMaterialFlags::NoLighting);
  202.  
  203.                         // Draw light point
  204.                         mat4 mv = glm::scale(glm::translate(mat4(), light.pos), vec3(light.radius));
  205.                         rend->loadMatrix(mv);
  206.                         rend->wireframe(true);
  207.                         rend->drawMesh(sphereMesh);
  208.                         rend->wireframe(false);
  209.  
  210.                         // Disable GBuffer color shader
  211.                         rend->disableShader(gBufferColorShader);
  212.                     }
  213.  
  214.                 }
  215.             }
  216.         }
  217.     }
  218.  
  219.     void DeferredRenderingGame::fillGBuffer() {
  220.         // Update GBuffer if required
  221.         gBuffer->resizeIfRequired(getWindowSize());
  222.  
  223.         // Load camera matrix
  224.         mat4 camMV = camera.getModelView();
  225.         mat4 camProj = camera.getProjection();
  226.  
  227.         // Save active buffer
  228.         GLint latestBuffer = gBuffer->getDrawBuffer();
  229.  
  230.         // Enable GBUffer
  231.         gBuffer->enable();
  232.  
  233.          // Draw to position,normal/diffuse buffers only
  234.         gBuffer->setDrawBuffers(GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2);
  235.  
  236.         // Viewport and clearing
  237.         rend->viewport(gBuffer->getSize());
  238.         rend->clearColor(-10000.0f, 0.0f, 0.0f, 1.0f);
  239.         rend->clear(ClearFlags::Color | ClearFlags::Depth);
  240.  
  241.         // Draw scene into GBuffer
  242.         drawSceneIntoGBuffer(camMV, camProj);
  243.  
  244.         // Reset buffer
  245.         gBuffer->setDrawBuffer(latestBuffer);
  246.  
  247.         // Disable GBUffer
  248.         gBuffer->disable();
  249.     }
  250.  
  251.     void DeferredRenderingGame::accumulateLighting() {
  252.         // Load camera matrix
  253.         mat4 camMV = camera.getModelView();
  254.         mat4 camProj = camera.getProjection();
  255.  
  256.         // Get GBuffer textures
  257.         CTexture2D* positionTex = gBuffer->getTexture("pos");
  258.         CTexture2D* normalTex = gBuffer->getTexture("normal");
  259.  
  260.         // Update light buffer if required
  261.         lightBuffer->resizeIfRequired(getWindowSize());
  262.  
  263.         // Save active buffer
  264.         GLint latestBuffer = lightBuffer->getDrawBuffer();
  265.  
  266.         // Disable depth test
  267.         rend->depthTest(false);
  268.         rend->depthMask(false);
  269.  
  270.         // Enable blending
  271.         rend->blending(true);
  272.         rend->blendFunc(GL_ONE, GL_ONE);
  273.  
  274.         // Enable light buffer
  275.         lightBuffer->enable();
  276.  
  277.         // Draw to light buffer only
  278.         lightBuffer->setDrawBuffer(GL_COLOR_ATTACHMENT0);
  279.  
  280.         // Viewport and clearing
  281.         rend->viewport(lightBuffer->getSize());
  282.         rend->clearColor(0.0f, 0.0f, 0.0f, 1.0f);
  283.         rend->clear(ClearFlags::Color);
  284.  
  285.         // Change to ortho projection
  286.         mat4 orthoMVP = glm::ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
  287.         rend->loadMatrix(orthoMVP);
  288.  
  289.         // Loop through all lights
  290.         for (list<CSceneNode*>::iterator i = scene->getBegin(); i != scene->getEnd(); ++i) {
  291.             CSceneNode* node = *i;
  292.             if (node->getType() == SceneNodeTypes::Light) {
  293.                 CSceneLightNode* lightNode = (CSceneLightNode*)node;
  294.                 Light light = lightNode->getLight();
  295.  
  296.                 CGLSL* lightShader = NULL;
  297.                 if (light.type == LightTypes::Point) {
  298.                     lightShader = pointLightShader;
  299.                 } else if (light.type == LightTypes::Directional) {
  300.                     lightShader = directionalLightShader;
  301.                 }
  302.  
  303.                 if (lightShader != NULL) {
  304.                     // Enable textures
  305.                     rend->enableTexture(normalTex, 0);
  306.                     rend->enableTexture(positionTex, 1);
  307.  
  308.                     // Enable light shader
  309.                     rend->enableShader(lightShader);
  310.                     lightShader->uniform1i(lightShader->getUniformLocation("normalTex"), 0);
  311.                     lightShader->uniform1i(lightShader->getUniformLocation("positionTex"), 1);
  312.                     lightShader->uniform4f(lightShader->getUniformLocation("lightColor"), &light.color[0]);
  313.                     lightShader->uniform1f(lightShader->getUniformLocation("shininess"), light.shininess);
  314.                     lightShader->uniform3f(lightShader->getUniformLocation("lightPos"), &light.pos[0]);
  315.                     lightShader->uniform1f(lightShader->getUniformLocation("lightRadius"), light.radius);
  316.                     lightShader->uniform1f(lightShader->getUniformLocation("lightFalloff"), light.falloff);
  317.  
  318.                     // Draw fullscreen quad mesh
  319.                     rend->drawMesh(fullscreenQuadMesh);
  320.  
  321.                     // Disable light shader
  322.                     rend->disableShader(lightShader);
  323.  
  324.                     // Disable textures
  325.                     rend->disableTexture(positionTex, 1);
  326.                     rend->disableTexture(normalTex, 0);
  327.                 }
  328.             }
  329.         }
  330.  
  331.         // Reset light buffer
  332.         lightBuffer->setDrawBuffer(latestBuffer);
  333.  
  334.         // Disable light buffer
  335.         lightBuffer->disable();
  336.  
  337.         // Disable blending
  338.         rend->blending(false);
  339.         rend->blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  340.  
  341.         // Enable depth test
  342.         rend->depthMask(true);
  343.         rend->depthTest(true);
  344.     }
  345.  
  346.     void DeferredRenderingGame::drawGBuffer() {
  347.         // Get GBuffer textures
  348.         CTexture2D* positionTex = gBuffer->getTexture("pos");
  349.         CTexture2D* normalTex = gBuffer->getTexture("normal");
  350.         CTexture2D* diffuseTex = gBuffer->getTexture("diffuse");
  351.         CTexture2D* lightBufferTex = lightBuffer->getTexture("lightBuffer");
  352.  
  353.         // Change to ortho projection
  354.         mat4 orthoMVP = glm::ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
  355.         rend->loadMatrix(orthoMVP);
  356.  
  357.         // Clear everything
  358.         rend->clearColor(0.0f, 0.0f, 0.0f, 1.0f);
  359.         rend->clear(ClearFlags::Color | ClearFlags::Depth);
  360.  
  361.         CTexture2D* tex = NULL;
  362.         switch (gBufferDisplay) {
  363.         case GBufferDisplays::Position:
  364.             tex = positionTex;
  365.             break;
  366.         case GBufferDisplays::Normals:
  367.             tex = normalTex;
  368.             break;
  369.         case GBufferDisplays::Diffuse:
  370.             tex = diffuseTex;
  371.             break;
  372.         case GBufferDisplays::LightBuffer:
  373.             tex = lightBufferTex;
  374.             break;
  375.         }
  376.  
  377.         ivec2 winSize = getWindowSize();
  378.  
  379.         glColor4f(1.0, 1.0f, 1.0f, 1.0f);
  380.  
  381.         if (tex != NULL) {
  382.             // Set viewport to window size
  383.             rend->viewport(getWindowSize());
  384.  
  385.             rend->enableTexture(tex, 0);
  386.             rend->drawMesh(fullscreenQuadMesh);
  387.             rend->disableTexture(tex, 0);
  388.         } else {
  389.             // Position
  390.             rend->viewport(0, winSize.y / 2, winSize.x / 2, winSize.y / 2);
  391.             rend->enableTexture(positionTex, 0);
  392.             rend->drawMesh(fullscreenQuadMesh);
  393.             rend->disableTexture(positionTex, 0);
  394.  
  395.             // Normals
  396.             rend->viewport(winSize.x / 2, winSize.y / 2, winSize.x / 2, winSize.y / 2);
  397.             rend->enableTexture(normalTex, 0);
  398.             rend->drawMesh(fullscreenQuadMesh);
  399.             rend->disableTexture(normalTex, 0);
  400.  
  401.             // Diffuse
  402.             rend->viewport(0, 0, winSize.x / 2, winSize.y / 2);
  403.             rend->enableTexture(diffuseTex, 0);
  404.             rend->drawMesh(fullscreenQuadMesh);
  405.             rend->disableTexture(diffuseTex, 0);
  406.  
  407.             // Light Buffer
  408.             rend->viewport(winSize.x / 2, 0, winSize.x / 2, winSize.y / 2);
  409.             rend->enableTexture(lightBufferTex, 0);
  410.             rend->drawMesh(fullscreenQuadMesh);
  411.             rend->disableTexture(lightBufferTex, 0);
  412.         }
  413.     }
  414.  
  415.     void DeferredRenderingGame::renderGame(const float &frametime) {
  416.         // Fill GBuffer
  417.         fillGBuffer();
  418.  
  419.         // Accumulate lighting
  420.         accumulateLighting();
  421.  
  422.         // Draw GBuffer
  423.         drawGBuffer();
  424.  
  425.         /*
  426.         rend->viewport(getWindowSize());
  427.         rend->clear(ClearFlags::Color | ClearFlags::Depth);
  428.  
  429.         glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
  430.         rend->loadMatrix(camera.getModelViewProjection());
  431.         rend->drawAABB(bunnyRenderableMesh->getAABB());
  432.         */
  433.  
  434.         /*
  435.         glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
  436.         rend->loadMatrix(glm::translate(camera.getModelViewProjection(), vec3(0.0f, 2.5f, 0.0f)));
  437.         rend->drawMesh(cubeRenderableMesh);
  438.  
  439.         glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
  440.         showNormalsShader->enable();
  441.         showNormalsShader->uniform1f(showNormalsShader->getUniformLocation("normalsLength"), 0.5f);
  442.         rend->loadMatrix(camera.getModelViewProjection());
  443.         rend->drawMesh(planeRenderableMesh);
  444.         rend->loadMatrix(glm::translate(camera.getModelViewProjection(), vec3(0.0f, 2.5f, 0.0f)));
  445.         rend->drawMesh(cubeRenderableMesh);
  446.         showNormalsShader->disable();
  447.         */
  448.  
  449.        
  450.     }
  451.  
  452. }
Advertisement
Add Comment
Please, Sign In to add comment