Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "DeferredRenderingGame.h"
- namespace rps_test_game {
- DeferredRenderingGame::DeferredRenderingGame(void)
- : CGame()
- {
- scene = NULL;
- camera = CFreeCamera();
- gBufferColorShader = NULL;
- gBufferDebugShader = NULL;
- gBuffer = NULL;
- gBufferDisplay = GBufferDisplays::All;
- drawAABB = true;
- drawLightGeometry = false;
- bunnyRenderableMesh = NULL;
- sponzaRenderableMesh = NULL;
- fullscreenQuadMesh = NULL;
- sphereMesh = NULL;
- setWindowSize(ivec2(1280, 720));
- }
- DeferredRenderingGame::~DeferredRenderingGame(void)
- {
- // Nothing to release, everything is destroyed from content manager or in freeGame
- }
- float randomFloatRange(float a, float b)
- {
- return ((b-a)*((float)rand()/RAND_MAX))+a;
- }
- float randomColorFloat() {
- return randomFloatRange(0.0f, 1.0f);
- }
- vec4 randomColor() {
- return vec4(randomColorFloat(), randomColorFloat(), randomColorFloat(), 1.0f);
- }
- void DeferredRenderingGame::initGame() {
- rend = getRenderer();
- rend->clearColor(0.0f, 0.0f, 0.0f, 1.0f);
- scene = new CScene();
- fullscreenQuadMesh = getContentMng()->genRenderableQuad(vec2(2.0f, 2.0f), "");
- sphereMesh = getContentMng()->loadRenderableMesh("sphere/sphere.obj", "");
- bunnyRenderableMesh = getContentMng()->loadRenderableMesh("stanford_bunny/bunny.rps", "bunny>");
- sponzaRenderableMesh = getContentMng()->loadRenderableMesh("sponza/sponza.rps", "sponza>");
- gBufferColorShader = getContentMng()->loadShader("gbuffer_color", "GBuffer.vert", "GBuffer_Color.frag");
- gBufferDebugShader = getContentMng()->loadShader("gbuffer_debug", "GBuffer_Debug.vert", "GBuffer_Debug.frag");
- pointLightShader = getContentMng()->loadShader("pointlight", "PointLight.vert", "PointLight.frag");
- directionalLightShader = getContentMng()->loadShader("directionallight", "DirectionalLight.vert", "DirectionalLight.frag");
- gBuffer = getContentMng()->createFramebuffer("gbuffer", getWindowSize());
- gBuffer->addRenderTarget(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_ATTACHMENT, "depth", GL_NEAREST);
- gBuffer->addTextureTarget(GL_RGBA32F, GL_RGBA, GL_FLOAT, GL_COLOR_ATTACHMENT0, "pos", GL_NEAREST);
- gBuffer->addTextureTarget(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, GL_COLOR_ATTACHMENT1, "normal", GL_LINEAR);
- gBuffer->addTextureTarget(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, GL_COLOR_ATTACHMENT2, "diffuse", GL_LINEAR);
- gBuffer->update();
- lightBuffer = getContentMng()->createFramebuffer("lightbuffer", getWindowSize());
- lightBuffer->addTextureTarget(GL_RGBA32F, GL_RGBA, GL_FLOAT, GL_COLOR_ATTACHMENT0, "lightBuffer", GL_LINEAR);
- lightBuffer->update();
- scene->add(new CMeshSceneNode(sponzaRenderableMesh, mat4(), true));
- scene->add(new CMeshSceneNode(bunnyRenderableMesh, glm::scale(mat4(), vec3(10.0f, 10.0f, 10.0f)), false));
- lightNodes.push_back(new CSceneLightNode(LightTypes::Directional, vec3(0.0f, 1000.0f, 0.0f), 0.0f));
- float lightStart = -1000.0f;
- float lightEnd = 1000.0f;
- float lightCur = lightStart;
- while (lightCur < lightEnd) {
- lightNodes.push_back(new CSceneLightNode(LightTypes::Point, vec3(lightCur, 50.0f, 0.0f), 200.0f, randomColor()));
- lightNodes.push_back(new CSceneLightNode(LightTypes::Point, vec3(lightCur, 50.0f, -550.0f), 200.0f, randomColor()));
- lightNodes.push_back(new CSceneLightNode(LightTypes::Point, vec3(lightCur, 50.0f, -350.0f), 200.0f, randomColor()));
- lightNodes.push_back(new CSceneLightNode(LightTypes::Point, vec3(lightCur, 50.0f, 300.0f), 200.0f, randomColor()));
- lightNodes.push_back(new CSceneLightNode(LightTypes::Point, vec3(lightCur, 50.0f, 500.0f), 200.0f, randomColor()));
- lightCur += 100.0f;
- }
- for (unsigned int i = 0; i < lightNodes.size(); i++) {
- scene->add(lightNodes[i]);
- }
- frustum = CFrustum();
- camera.setPos(0.0f, 2.5f, 20.0f);
- camera.setAspect(getWindowAspect());
- }
- void DeferredRenderingGame::freeGame() {
- if (scene)
- delete scene;
- }
- void DeferredRenderingGame::updateGame(const float &frametime) {
- // Update rendering states
- if (CKeyboardInput::get()->isKeyPressed(Keys::Space)) {
- CKeyboardInput::get()->setKeyPressed(Keys::Space, false);
- gBufferDisplay++;
- if (gBufferDisplay > 4) gBufferDisplay = 0;
- }
- if (CKeyboardInput::get()->isKeyPressed(Keys::G)) {
- CKeyboardInput::get()->setKeyPressed(Keys::G, false);
- drawLightGeometry = !drawLightGeometry;
- }
- // Update camera
- camera.setAspect(getWindowAspect());
- FreeCameraControl ctrl = FreeCameraControl();
- ctrl.mouseLook = CMouseInput::get()->isMousePressed(MouseButton::Left);
- ctrl.mousePos = CMouseInput::get()->getMousePos();
- if (CKeyboardInput::get()->isKeyPressed(Keys::W)) {
- ctrl.forward = -200.0f * frametime;
- } else if (CKeyboardInput::get()->isKeyPressed(Keys::S)) {
- ctrl.forward = 200.0f * frametime;
- }
- if (CKeyboardInput::get()->isKeyPressed(Keys::A)) {
- ctrl.strafe = -200.0f * frametime;
- } else if (CKeyboardInput::get()->isKeyPressed(Keys::D)) {
- ctrl.strafe = 200.0f * frametime;
- }
- if (CKeyboardInput::get()->isKeyPressed(Keys::Q)) {
- ctrl.upDown = -200.0f * frametime;
- } else if (CKeyboardInput::get()->isKeyPressed(Keys::E)) {
- ctrl.upDown = 200.0f * frametime;
- }
- camera.update(ctrl);
- // Update frustum
- frustum.update(camera.getProjection(), camera.getModelView());
- vec3 pos = camera.getPos();
- char buffer[255];
- sprintf_s(buffer, "%f, %f, %f", pos.x, pos.y, pos.z);
- glfwSetWindowTitle(buffer);
- }
- void DeferredRenderingGame::drawSceneIntoGBuffer(mat4 &camMV, mat4 &camProj) {
- for (list<CSceneNode*>::iterator i = scene->getBegin(); i != scene->getEnd(); ++i) {
- CSceneNode* node = *i;
- if (node->isRenderable()) {
- mat4 modelview = node->getModelview();
- if (node->getType() == SceneNodeTypes::Mesh) {
- CMeshSceneNode* meshSceneNode = (CMeshSceneNode*)node;
- CRenderableMesh* mesh = meshSceneNode->getMeshInstance();
- // Enable GBuffer color shader
- rend->enableShader(gBufferColorShader);
- gBufferColorShader->uniformMatrix4(gBufferColorShader->getUniformLocation("cam_proj"), &camProj[0][0]);
- gBufferColorShader->uniformMatrix4(gBufferColorShader->getUniformLocation("cam_view"), &camMV[0][0]);
- gBufferColorShader->uniform1f(gBufferColorShader->getUniformLocation("materialValue"), (float)GBufferMaterialFlags::Default);
- // Draw mesh
- getRenderer()->loadMatrix(modelview);
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- getRenderer()->drawMesh(mesh);
- // Disable GBuffer color shader
- rend->disableShader(gBufferColorShader);
- // Debug enabled?
- if (drawAABB) {
- // Enable GBuffer debug shader
- rend->enableShader(gBufferColorShader);
- gBufferColorShader->uniformMatrix4(gBufferColorShader->getUniformLocation("cam_proj"), &camProj[0][0]);
- gBufferColorShader->uniformMatrix4(gBufferColorShader->getUniformLocation("cam_view"), &camMV[0][0]);
- gBufferColorShader->uniform1f(gBufferColorShader->getUniformLocation("materialValue"), (float)GBufferMaterialFlags::NoLighting);
- // Draw aabb or other debug stuff for mesh
- getRenderer()->loadMatrix(mat4());
- glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
- getRenderer()->drawAABB(meshSceneNode->getAABB());
- // Disable GBuffer debug shader
- rend->disableShader(gBufferColorShader);
- }
- } else if (node->getType() == SceneNodeTypes::Light) {
- CSceneLightNode* lightNode = (CSceneLightNode*)node;
- Light light = lightNode->getLight();
- if (drawLightGeometry) {
- // enable GBuffer color shader
- rend->enableShader(gBufferColorShader);
- gBufferColorShader->uniformMatrix4(gBufferColorShader->getUniformLocation("cam_proj"), &camProj[0][0]);
- gBufferColorShader->uniformMatrix4(gBufferColorShader->getUniformLocation("cam_view"), &camMV[0][0]);
- gBufferColorShader->uniform1f(gBufferColorShader->getUniformLocation("materialValue"), (float)GBufferMaterialFlags::NoLighting);
- // Draw light point
- mat4 mv = glm::scale(glm::translate(mat4(), light.pos), vec3(light.radius));
- rend->loadMatrix(mv);
- rend->wireframe(true);
- rend->drawMesh(sphereMesh);
- rend->wireframe(false);
- // Disable GBuffer color shader
- rend->disableShader(gBufferColorShader);
- }
- }
- }
- }
- }
- void DeferredRenderingGame::fillGBuffer() {
- // Update GBuffer if required
- gBuffer->resizeIfRequired(getWindowSize());
- // Load camera matrix
- mat4 camMV = camera.getModelView();
- mat4 camProj = camera.getProjection();
- // Save active buffer
- GLint latestBuffer = gBuffer->getDrawBuffer();
- // Enable GBUffer
- gBuffer->enable();
- // Draw to position,normal/diffuse buffers only
- gBuffer->setDrawBuffers(GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2);
- // Viewport and clearing
- rend->viewport(gBuffer->getSize());
- rend->clearColor(-10000.0f, 0.0f, 0.0f, 1.0f);
- rend->clear(ClearFlags::Color | ClearFlags::Depth);
- // Draw scene into GBuffer
- drawSceneIntoGBuffer(camMV, camProj);
- // Reset buffer
- gBuffer->setDrawBuffer(latestBuffer);
- // Disable GBUffer
- gBuffer->disable();
- }
- void DeferredRenderingGame::accumulateLighting() {
- // Load camera matrix
- mat4 camMV = camera.getModelView();
- mat4 camProj = camera.getProjection();
- // Get GBuffer textures
- CTexture2D* positionTex = gBuffer->getTexture("pos");
- CTexture2D* normalTex = gBuffer->getTexture("normal");
- // Update light buffer if required
- lightBuffer->resizeIfRequired(getWindowSize());
- // Save active buffer
- GLint latestBuffer = lightBuffer->getDrawBuffer();
- // Disable depth test
- rend->depthTest(false);
- rend->depthMask(false);
- // Enable blending
- rend->blending(true);
- rend->blendFunc(GL_ONE, GL_ONE);
- // Enable light buffer
- lightBuffer->enable();
- // Draw to light buffer only
- lightBuffer->setDrawBuffer(GL_COLOR_ATTACHMENT0);
- // Viewport and clearing
- rend->viewport(lightBuffer->getSize());
- rend->clearColor(0.0f, 0.0f, 0.0f, 1.0f);
- rend->clear(ClearFlags::Color);
- // Change to ortho projection
- mat4 orthoMVP = glm::ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
- rend->loadMatrix(orthoMVP);
- // Loop through all lights
- for (list<CSceneNode*>::iterator i = scene->getBegin(); i != scene->getEnd(); ++i) {
- CSceneNode* node = *i;
- if (node->getType() == SceneNodeTypes::Light) {
- CSceneLightNode* lightNode = (CSceneLightNode*)node;
- Light light = lightNode->getLight();
- CGLSL* lightShader = NULL;
- if (light.type == LightTypes::Point) {
- lightShader = pointLightShader;
- } else if (light.type == LightTypes::Directional) {
- lightShader = directionalLightShader;
- }
- if (lightShader != NULL) {
- // Enable textures
- rend->enableTexture(normalTex, 0);
- rend->enableTexture(positionTex, 1);
- // Enable light shader
- rend->enableShader(lightShader);
- lightShader->uniform1i(lightShader->getUniformLocation("normalTex"), 0);
- lightShader->uniform1i(lightShader->getUniformLocation("positionTex"), 1);
- lightShader->uniform4f(lightShader->getUniformLocation("lightColor"), &light.color[0]);
- lightShader->uniform1f(lightShader->getUniformLocation("shininess"), light.shininess);
- lightShader->uniform3f(lightShader->getUniformLocation("lightPos"), &light.pos[0]);
- lightShader->uniform1f(lightShader->getUniformLocation("lightRadius"), light.radius);
- lightShader->uniform1f(lightShader->getUniformLocation("lightFalloff"), light.falloff);
- // Draw fullscreen quad mesh
- rend->drawMesh(fullscreenQuadMesh);
- // Disable light shader
- rend->disableShader(lightShader);
- // Disable textures
- rend->disableTexture(positionTex, 1);
- rend->disableTexture(normalTex, 0);
- }
- }
- }
- // Reset light buffer
- lightBuffer->setDrawBuffer(latestBuffer);
- // Disable light buffer
- lightBuffer->disable();
- // Disable blending
- rend->blending(false);
- rend->blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- // Enable depth test
- rend->depthMask(true);
- rend->depthTest(true);
- }
- void DeferredRenderingGame::drawGBuffer() {
- // Get GBuffer textures
- CTexture2D* positionTex = gBuffer->getTexture("pos");
- CTexture2D* normalTex = gBuffer->getTexture("normal");
- CTexture2D* diffuseTex = gBuffer->getTexture("diffuse");
- CTexture2D* lightBufferTex = lightBuffer->getTexture("lightBuffer");
- // Change to ortho projection
- mat4 orthoMVP = glm::ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
- rend->loadMatrix(orthoMVP);
- // Clear everything
- rend->clearColor(0.0f, 0.0f, 0.0f, 1.0f);
- rend->clear(ClearFlags::Color | ClearFlags::Depth);
- CTexture2D* tex = NULL;
- switch (gBufferDisplay) {
- case GBufferDisplays::Position:
- tex = positionTex;
- break;
- case GBufferDisplays::Normals:
- tex = normalTex;
- break;
- case GBufferDisplays::Diffuse:
- tex = diffuseTex;
- break;
- case GBufferDisplays::LightBuffer:
- tex = lightBufferTex;
- break;
- }
- ivec2 winSize = getWindowSize();
- glColor4f(1.0, 1.0f, 1.0f, 1.0f);
- if (tex != NULL) {
- // Set viewport to window size
- rend->viewport(getWindowSize());
- rend->enableTexture(tex, 0);
- rend->drawMesh(fullscreenQuadMesh);
- rend->disableTexture(tex, 0);
- } else {
- // Position
- rend->viewport(0, winSize.y / 2, winSize.x / 2, winSize.y / 2);
- rend->enableTexture(positionTex, 0);
- rend->drawMesh(fullscreenQuadMesh);
- rend->disableTexture(positionTex, 0);
- // Normals
- rend->viewport(winSize.x / 2, winSize.y / 2, winSize.x / 2, winSize.y / 2);
- rend->enableTexture(normalTex, 0);
- rend->drawMesh(fullscreenQuadMesh);
- rend->disableTexture(normalTex, 0);
- // Diffuse
- rend->viewport(0, 0, winSize.x / 2, winSize.y / 2);
- rend->enableTexture(diffuseTex, 0);
- rend->drawMesh(fullscreenQuadMesh);
- rend->disableTexture(diffuseTex, 0);
- // Light Buffer
- rend->viewport(winSize.x / 2, 0, winSize.x / 2, winSize.y / 2);
- rend->enableTexture(lightBufferTex, 0);
- rend->drawMesh(fullscreenQuadMesh);
- rend->disableTexture(lightBufferTex, 0);
- }
- }
- void DeferredRenderingGame::renderGame(const float &frametime) {
- // Fill GBuffer
- fillGBuffer();
- // Accumulate lighting
- accumulateLighting();
- // Draw GBuffer
- drawGBuffer();
- /*
- rend->viewport(getWindowSize());
- rend->clear(ClearFlags::Color | ClearFlags::Depth);
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- rend->loadMatrix(camera.getModelViewProjection());
- rend->drawAABB(bunnyRenderableMesh->getAABB());
- */
- /*
- glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
- rend->loadMatrix(glm::translate(camera.getModelViewProjection(), vec3(0.0f, 2.5f, 0.0f)));
- rend->drawMesh(cubeRenderableMesh);
- glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
- showNormalsShader->enable();
- showNormalsShader->uniform1f(showNormalsShader->getUniformLocation("normalsLength"), 0.5f);
- rend->loadMatrix(camera.getModelViewProjection());
- rend->drawMesh(planeRenderableMesh);
- rend->loadMatrix(glm::translate(camera.getModelViewProjection(), vec3(0.0f, 2.5f, 0.0f)));
- rend->drawMesh(cubeRenderableMesh);
- showNormalsShader->disable();
- */
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment