Showing the changes to interface/src/Environment.cpp (1 of 4 files). Show all
Unified · Split
| @@ -5,6 +5,8 @@ · 4 unmodified lines | |||
| 5 | // Created by Andrzej Kapolka on 5/6/13. | 5 | // Created by Andrzej Kapolka on 5/6/13. |
| 6 | // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. | 6 | // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. |
| 7 | 7 | ||
| 8 | #include <QByteArray> | ||
| 9 | |||
| 8 | #include "Camera.h" | 10 | #include "Camera.h" |
| 9 | #include "Environment.h" | 11 | #include "Environment.h" |
| 10 | #include "renderer/ProgramObject.h" | 12 | #include "renderer/ProgramObject.h" |
| @@ -12,24 +14,8 @@ · 1 unmodified line | |||
| 12 | #include "world.h" | 14 | #include "world.h" |
| 13 | 15 | ||
| 14 | void Environment::init() { | 16 | void Environment::init() { |
| 15 | _skyFromAtmosphereProgram = new ProgramObject(); | 17 | _skyFromAtmosphereProgram = createSkyProgram("Atmosphere", _skyFromAtmosphereUniformLocations); |
| 16 | _skyFromAtmosphereProgram->attachFromSourceFile(GL_VERTEX_SHADER_ARB, "resources/shaders/SkyFromAtmosphere.vert"); | 18 | _skyFromSpaceProgram = createSkyProgram("Space", _skyFromSpaceUniformLocations); |
| 17 | _skyFromAtmosphereProgram->attachFromSourceFile(GL_FRAGMENT_SHADER_ARB, "resources/shaders/SkyFromAtmosphere.frag"); | ||
| 18 | _skyFromAtmosphereProgram->link(); | ||
| 19 | |||
| 20 | _cameraPosLocation = _skyFromAtmosphereProgram->getUniformLocation("v3CameraPos"); | ||
| 21 | _lightPosLocation = _skyFromAtmosphereProgram->getUniformLocation("v3LightPos"); | ||
| 22 | _invWavelengthLocation = _skyFromAtmosphereProgram->getUniformLocation("v3InvWavelength"); | ||
| 23 | _innerRadiusLocation = _skyFromAtmosphereProgram->getUniformLocation("fInnerRadius"); | ||
| 24 | _krESunLocation = _skyFromAtmosphereProgram->getUniformLocation("fKrESun"); | ||
| 25 | _kmESunLocation = _skyFromAtmosphereProgram->getUniformLocation("fKmESun"); | ||
| 26 | _kr4PiLocation = _skyFromAtmosphereProgram->getUniformLocation("fKr4PI"); | ||
| 27 | _km4PiLocation = _skyFromAtmosphereProgram->getUniformLocation("fKm4PI"); | ||
| 28 | _scaleLocation = _skyFromAtmosphereProgram->getUniformLocation("fScale"); | ||
| 29 | _scaleDepthLocation = _skyFromAtmosphereProgram->getUniformLocation("fScaleDepth"); | ||
| 30 | _scaleOverScaleDepthLocation = _skyFromAtmosphereProgram->getUniformLocation("fScaleOverScaleDepth"); | ||
| 31 | _gLocation = _skyFromAtmosphereProgram->getUniformLocation("g"); | ||
| 32 | _g2Location = _skyFromAtmosphereProgram->getUniformLocation("g2"); | ||
| 33 | } | 19 | } |
| 34 | 20 | ||
| 35 | void Environment::renderAtmosphere(Camera& camera) { | 21 | void Environment::renderAtmosphere(Camera& camera) { |
| @@ -44,32 +30,48 @@ void Environment::renderAtmosphere(Camera& camera) { · 8 unmodified lines | |||
| 44 | float projection[16]; | 30 | float projection[16]; |
| 45 | glGetFloatv(GL_PROJECTION_MATRIX, projection); | 31 | glGetFloatv(GL_PROJECTION_MATRIX, projection); |
| 46 | glm::vec3 relativeCameraPos = camera.getPosition() - getAtmosphereCenter(); | 32 | glm::vec3 relativeCameraPos = camera.getPosition() - getAtmosphereCenter(); |
| 47 | float near = camera.getNearClip(), far = glm::length(relativeCameraPos) + getAtmosphereOuterRadius(); | 33 | float height = glm::length(relativeCameraPos); |
| 34 | float near = camera.getNearClip(), far = height + getAtmosphereOuterRadius(); | ||
| 48 | projection[10] = (far + near) / (near - far); | 35 | projection[10] = (far + near) / (near - far); |
| 49 | projection[14] = (2.0f * far * near) / (near - far); | 36 | projection[14] = (2.0f * far * near) / (near - far); |
| 50 | glLoadMatrixf(projection); | 37 | glLoadMatrixf(projection); |
| 51 | 38 | ||
| 39 | // use the appropriate shader depending on whether we're inside or outside | ||
| 40 | ProgramObject* program; | ||
| 41 | int* locations; | ||
| 42 | if (height < getAtmosphereOuterRadius()) { | ||
| 43 | program = _skyFromAtmosphereProgram; | ||
| 44 | locations = _skyFromAtmosphereUniformLocations; | ||
| 45 | |||
| 46 | } else { | ||
| 47 | program = _skyFromSpaceProgram; | ||
| 48 | locations = _skyFromSpaceUniformLocations; | ||
| 49 | } | ||
| 50 | |||
| 52 | // the constants here are from Sean O'Neil's GPU Gems entry | 51 | // the constants here are from Sean O'Neil's GPU Gems entry |
| 53 | // (http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html), GameEngine.cpp | 52 | // (http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html), GameEngine.cpp |
| 54 | _skyFromAtmosphereProgram->bind(); | 53 | program->bind(); |
| 55 | _skyFromAtmosphereProgram->setUniform(_cameraPosLocation, relativeCameraPos); | 54 | program->setUniform(locations[CAMERA_POS_LOCATION], relativeCameraPos); |
| 56 | glm::vec3 lightDirection = glm::normalize(getSunLocation()); | 55 | glm::vec3 lightDirection = glm::normalize(getSunLocation()); |
| 57 | _skyFromAtmosphereProgram->setUniform(_lightPosLocation, lightDirection); | 56 | program->setUniform(locations[LIGHT_POS_LOCATION], lightDirection); |
| 58 | _skyFromAtmosphereProgram->setUniform(_invWavelengthLocation, | 57 | program->setUniform(locations[INV_WAVELENGTH_LOCATION], |
| 59 | 1 / powf(getScatteringWavelengths().r, 4.0f), | 58 | 1 / powf(getScatteringWavelengths().r, 4.0f), |
| 60 | 1 / powf(getScatteringWavelengths().g, 4.0f), | 59 | 1 / powf(getScatteringWavelengths().g, 4.0f), |
| 61 | 1 / powf(getScatteringWavelengths().b, 4.0f)); | 60 | 1 / powf(getScatteringWavelengths().b, 4.0f)); |
| 62 | _skyFromAtmosphereProgram->setUniform(_innerRadiusLocation, getAtmosphereInnerRadius()); | 61 | program->setUniform(locations[CAMERA_HEIGHT2_LOCATION], height * height); |
| 63 | _skyFromAtmosphereProgram->setUniform(_krESunLocation, getRayleighScattering() * getSunBrightness()); | 62 | program->setUniform(locations[OUTER_RADIUS_LOCATION], getAtmosphereOuterRadius()); |
| 64 | _skyFromAtmosphereProgram->setUniform(_kmESunLocation, getMieScattering() * getSunBrightness()); | 63 | program->setUniform(locations[OUTER_RADIUS2_LOCATION], getAtmosphereOuterRadius() * getAtmosphereOuterRadius()); |
| 65 | _skyFromAtmosphereProgram->setUniform(_kr4PiLocation, getRayleighScattering() * 4.0f * PIf); | 64 | program->setUniform(locations[INNER_RADIUS_LOCATION], getAtmosphereInnerRadius()); |
| 66 | _skyFromAtmosphereProgram->setUniform(_km4PiLocation, getMieScattering() * 4.0f * PIf); | 65 | program->setUniform(locations[KR_ESUN_LOCATION], getRayleighScattering() * getSunBrightness()); |
| 67 | _skyFromAtmosphereProgram->setUniform(_scaleLocation, 1.0f / (getAtmosphereOuterRadius() - getAtmosphereInnerRadius())); | 66 | program->setUniform(locations[KM_ESUN_LOCATION], getMieScattering() * getSunBrightness()); |
| 68 | _skyFromAtmosphereProgram->setUniform(_scaleDepthLocation, 0.25f); | 67 | program->setUniform(locations[KR_4PI_LOCATION], getRayleighScattering() * 4.0f * PIf); |
| 69 | _skyFromAtmosphereProgram->setUniform(_scaleOverScaleDepthLocation, | 68 | program->setUniform(locations[KM_4PI_LOCATION], getMieScattering() * 4.0f * PIf); |
| 69 | program->setUniform(locations[SCALE_LOCATION], 1.0f / (getAtmosphereOuterRadius() - getAtmosphereInnerRadius())); | ||
| 70 | program->setUniform(locations[SCALE_DEPTH_LOCATION], 0.25f); | ||
| 71 | program->setUniform(locations[SCALE_OVER_SCALE_DEPTH_LOCATION], | ||
| 70 | (1.0f / (getAtmosphereOuterRadius() - getAtmosphereInnerRadius())) / 0.25f); | 72 | (1.0f / (getAtmosphereOuterRadius() - getAtmosphereInnerRadius())) / 0.25f); |
| 71 | _skyFromAtmosphereProgram->setUniform(_gLocation, -0.990f); | 73 | program->setUniform(locations[G_LOCATION], -0.990f); |
| 72 | _skyFromAtmosphereProgram->setUniform(_g2Location, -0.990f * -0.990f); | 74 | program->setUniform(locations[G2_LOCATION], -0.990f * -0.990f); |
| 73 | 75 | ||
| 74 | glFrontFace(GL_CW); | 76 | glFrontFace(GL_CW); |
| 75 | glDepthMask(GL_FALSE); | 77 | glDepthMask(GL_FALSE); |
| @@ -78,10 +80,37 @@ void Environment::renderAtmosphere(Camera& camera) { · 2 unmodified lines | |||
| 78 | glDepthMask(GL_TRUE); | 80 | glDepthMask(GL_TRUE); |
| 79 | glFrontFace(GL_CCW); | 81 | glFrontFace(GL_CCW); |
| 80 | 82 | ||
| 81 | _skyFromAtmosphereProgram->release(); | 83 | program->release(); |
| 82 | 84 | ||
| 83 | glPopMatrix(); | 85 | glPopMatrix(); |
| 84 | 86 | ||
| 85 | glMatrixMode(GL_MODELVIEW); | 87 | glMatrixMode(GL_MODELVIEW); |
| 86 | glPopMatrix(); | 88 | glPopMatrix(); |
| 87 | } | 89 | } |
| 90 | |||
| 91 | ProgramObject* Environment::createSkyProgram(const char* from, int* locations) { | ||
| 92 | ProgramObject* program = new ProgramObject(); | ||
| 93 | QByteArray prefix = QByteArray("resources/shaders/SkyFrom") + from; | ||
| 94 | program->attachFromSourceFile(GL_VERTEX_SHADER_ARB, prefix + ".vert"); | ||
| 95 | program->attachFromSourceFile(GL_FRAGMENT_SHADER_ARB, prefix + ".frag"); | ||
| 96 | program->link(); | ||
| 97 | |||
| 98 | locations[CAMERA_POS_LOCATION] = program->getUniformLocation("v3CameraPos"); | ||
| 99 | locations[LIGHT_POS_LOCATION] = program->getUniformLocation("v3LightPos"); | ||
| 100 | locations[INV_WAVELENGTH_LOCATION] = program->getUniformLocation("v3InvWavelength"); | ||
| 101 | locations[CAMERA_HEIGHT2_LOCATION] = program->getUniformLocation("fCameraHeight2"); | ||
| 102 | locations[OUTER_RADIUS_LOCATION] = program->getUniformLocation("fOuterRadius"); | ||
| 103 | locations[OUTER_RADIUS2_LOCATION] = program->getUniformLocation("fOuterRadius2"); | ||
| 104 | locations[INNER_RADIUS_LOCATION] = program->getUniformLocation("fInnerRadius"); | ||
| 105 | locations[KR_ESUN_LOCATION] = program->getUniformLocation("fKrESun"); | ||
| 106 | locations[KM_ESUN_LOCATION] = program->getUniformLocation("fKmESun"); | ||
| 107 | locations[KR_4PI_LOCATION] = program->getUniformLocation("fKr4PI"); | ||
| 108 | locations[KM_4PI_LOCATION] = program->getUniformLocation("fKm4PI"); | ||
| 109 | locations[SCALE_LOCATION] = program->getUniformLocation("fScale"); | ||
| 110 | locations[SCALE_DEPTH_LOCATION] = program->getUniformLocation("fScaleDepth"); | ||
| 111 | locations[SCALE_OVER_SCALE_DEPTH_LOCATION] = program->getUniformLocation("fScaleOverScaleDepth"); | ||
| 112 | locations[G_LOCATION] = program->getUniformLocation("g"); | ||
| 113 | locations[G2_LOCATION] = program->getUniformLocation("g2"); | ||
| 114 | |||
| 115 | return program; | ||
| 116 | } | ||