mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 18:44:01 +02:00
Merge pull request #237 from ey6es/master
Added basic environment data and atmosphere rendering.
This commit is contained in:
commit
5e450827d8
20 changed files with 974 additions and 41 deletions
|
@ -32,7 +32,7 @@ configure_file(InterfaceConfig.h.in ${PROJECT_BINARY_DIR}/includes/InterfaceConf
|
|||
|
||||
# grab the implementation and header files from src dirs
|
||||
file(GLOB INTERFACE_SRCS src/*.cpp src/*.h)
|
||||
foreach(SUBDIR ui)
|
||||
foreach(SUBDIR ui renderer)
|
||||
file(GLOB SUBDIR_SRCS src/${SUBDIR}/*.cpp src/${SUBDIR}/*.h)
|
||||
set(INTERFACE_SRCS ${INTERFACE_SRCS} ${SUBDIR_SRCS})
|
||||
endforeach(SUBDIR)
|
||||
|
|
48
interface/resources/shaders/SkyFromAtmosphere.frag
Normal file
48
interface/resources/shaders/SkyFromAtmosphere.frag
Normal file
|
@ -0,0 +1,48 @@
|
|||
//
|
||||
// For licensing information, see http://http.developer.nvidia.com/GPUGems/gpugems_app01.html:
|
||||
//
|
||||
// NVIDIA Statement on the Software
|
||||
//
|
||||
// The source code provided is freely distributable, so long as the NVIDIA header remains unaltered and user modifications are
|
||||
// detailed.
|
||||
//
|
||||
// No Warranty
|
||||
//
|
||||
// THE SOFTWARE AND ANY OTHER MATERIALS PROVIDED BY NVIDIA ON THE ENCLOSED CD-ROM ARE PROVIDED "AS IS." NVIDIA DISCLAIMS ALL
|
||||
// WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
//
|
||||
// Limitation of Liability
|
||||
//
|
||||
// NVIDIA SHALL NOT BE LIABLE TO ANY USER, DEVELOPER, DEVELOPER'S CUSTOMERS, OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH OR
|
||||
// UNDER DEVELOPER FOR ANY LOSS OF PROFITS, INCOME, SAVINGS, OR ANY OTHER CONSEQUENTIAL, INCIDENTAL, SPECIAL, PUNITIVE, DIRECT
|
||||
// OR INDIRECT DAMAGES (WHETHER IN AN ACTION IN CONTRACT, TORT OR BASED ON A WARRANTY), EVEN IF NVIDIA HAS BEEN ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF THE ESSENTIAL PURPOSE OF ANY
|
||||
// LIMITED REMEDY. IN NO EVENT SHALL NVIDIA'S AGGREGATE LIABILITY TO DEVELOPER OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH
|
||||
// OR UNDER DEVELOPER EXCEED THE AMOUNT OF MONEY ACTUALLY PAID BY DEVELOPER TO NVIDIA FOR THE SOFTWARE OR ANY OTHER MATERIALS.
|
||||
//
|
||||
|
||||
//
|
||||
// Atmospheric scattering fragment shader
|
||||
//
|
||||
// Author: Sean O'Neil
|
||||
//
|
||||
// Copyright (c) 2004 Sean O'Neil
|
||||
//
|
||||
|
||||
#version 120
|
||||
|
||||
uniform vec3 v3LightPos;
|
||||
uniform float g;
|
||||
uniform float g2;
|
||||
|
||||
varying vec3 v3Direction;
|
||||
|
||||
|
||||
void main (void)
|
||||
{
|
||||
float fCos = dot(v3LightPos, v3Direction) / length(v3Direction);
|
||||
float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos*fCos) / pow(1.0 + g2 - 2.0*g*fCos, 1.5);
|
||||
gl_FragColor = gl_Color + fMiePhase * gl_SecondaryColor;
|
||||
gl_FragColor.a = gl_FragColor.b;
|
||||
}
|
100
interface/resources/shaders/SkyFromAtmosphere.vert
Normal file
100
interface/resources/shaders/SkyFromAtmosphere.vert
Normal file
|
@ -0,0 +1,100 @@
|
|||
//
|
||||
// For licensing information, see http://http.developer.nvidia.com/GPUGems/gpugems_app01.html:
|
||||
//
|
||||
// NVIDIA Statement on the Software
|
||||
//
|
||||
// The source code provided is freely distributable, so long as the NVIDIA header remains unaltered and user modifications are
|
||||
// detailed.
|
||||
//
|
||||
// No Warranty
|
||||
//
|
||||
// THE SOFTWARE AND ANY OTHER MATERIALS PROVIDED BY NVIDIA ON THE ENCLOSED CD-ROM ARE PROVIDED "AS IS." NVIDIA DISCLAIMS ALL
|
||||
// WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
//
|
||||
// Limitation of Liability
|
||||
//
|
||||
// NVIDIA SHALL NOT BE LIABLE TO ANY USER, DEVELOPER, DEVELOPER'S CUSTOMERS, OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH OR
|
||||
// UNDER DEVELOPER FOR ANY LOSS OF PROFITS, INCOME, SAVINGS, OR ANY OTHER CONSEQUENTIAL, INCIDENTAL, SPECIAL, PUNITIVE, DIRECT
|
||||
// OR INDIRECT DAMAGES (WHETHER IN AN ACTION IN CONTRACT, TORT OR BASED ON A WARRANTY), EVEN IF NVIDIA HAS BEEN ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF THE ESSENTIAL PURPOSE OF ANY
|
||||
// LIMITED REMEDY. IN NO EVENT SHALL NVIDIA'S AGGREGATE LIABILITY TO DEVELOPER OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH
|
||||
// OR UNDER DEVELOPER EXCEED THE AMOUNT OF MONEY ACTUALLY PAID BY DEVELOPER TO NVIDIA FOR THE SOFTWARE OR ANY OTHER MATERIALS.
|
||||
//
|
||||
|
||||
//
|
||||
// Atmospheric scattering vertex shader
|
||||
//
|
||||
// Author: Sean O'Neil
|
||||
//
|
||||
// Copyright (c) 2004 Sean O'Neil
|
||||
//
|
||||
|
||||
#version 120
|
||||
|
||||
uniform vec3 v3CameraPos; // The camera's current position
|
||||
uniform vec3 v3LightPos; // The direction vector to the light source
|
||||
uniform vec3 v3InvWavelength; // 1 / pow(wavelength, 4) for the red, green, and blue channels
|
||||
uniform float fInnerRadius; // The inner (planetary) radius
|
||||
uniform float fKrESun; // Kr * ESun
|
||||
uniform float fKmESun; // Km * ESun
|
||||
uniform float fKr4PI; // Kr * 4 * PI
|
||||
uniform float fKm4PI; // Km * 4 * PI
|
||||
uniform float fScale; // 1 / (fOuterRadius - fInnerRadius)
|
||||
uniform float fScaleDepth; // The scale depth (i.e. the altitude at which the atmosphere's average density is found)
|
||||
uniform float fScaleOverScaleDepth; // fScale / fScaleDepth
|
||||
|
||||
const int nSamples = 2;
|
||||
const float fSamples = 2.0;
|
||||
|
||||
varying vec3 v3Direction;
|
||||
|
||||
|
||||
float scale(float fCos)
|
||||
{
|
||||
float x = 1.0 - fCos;
|
||||
return fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// Get the ray from the camera to the vertex, and its length (which is the far point of the ray passing through the atmosphere)
|
||||
vec3 v3Pos = gl_Vertex.xyz;
|
||||
vec3 v3Ray = v3Pos - v3CameraPos;
|
||||
float fFar = length(v3Ray);
|
||||
v3Ray /= fFar;
|
||||
|
||||
// Calculate the ray's starting position, then calculate its scattering offset
|
||||
vec3 v3Start = v3CameraPos;
|
||||
float fHeight = length(v3Start);
|
||||
float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
|
||||
float fStartAngle = dot(v3Ray, v3Start) / fHeight;
|
||||
float fStartOffset = fDepth * scale(fStartAngle);
|
||||
|
||||
// Initialize the scattering loop variables
|
||||
//gl_FrontColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
float fSampleLength = fFar / fSamples;
|
||||
float fScaledLength = fSampleLength * fScale;
|
||||
vec3 v3SampleRay = v3Ray * fSampleLength;
|
||||
vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5;
|
||||
|
||||
// Now loop through the sample rays
|
||||
vec3 v3FrontColor = vec3(0.0, 0.0, 0.0);
|
||||
for(int i=0; i<nSamples; i++)
|
||||
{
|
||||
float fHeight = length(v3SamplePoint);
|
||||
float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
|
||||
float fLightAngle = dot(v3LightPos, v3SamplePoint) / fHeight;
|
||||
float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight;
|
||||
float fScatter = (fStartOffset + fDepth * (scale(fLightAngle) - scale(fCameraAngle)));
|
||||
vec3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI));
|
||||
v3FrontColor += v3Attenuate * (fDepth * fScaledLength);
|
||||
v3SamplePoint += v3SampleRay;
|
||||
}
|
||||
|
||||
// Finally, scale the Mie and Rayleigh colors and set up the varying variables for the pixel shader
|
||||
gl_FrontSecondaryColor.rgb = v3FrontColor * fKmESun;
|
||||
gl_FrontColor.rgb = v3FrontColor * (v3InvWavelength * fKrESun);
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
v3Direction = v3CameraPos - v3Pos;
|
||||
}
|
48
interface/resources/shaders/SkyFromSpace.frag
Normal file
48
interface/resources/shaders/SkyFromSpace.frag
Normal file
|
@ -0,0 +1,48 @@
|
|||
//
|
||||
// For licensing information, see http://http.developer.nvidia.com/GPUGems/gpugems_app01.html:
|
||||
//
|
||||
// NVIDIA Statement on the Software
|
||||
//
|
||||
// The source code provided is freely distributable, so long as the NVIDIA header remains unaltered and user modifications are
|
||||
// detailed.
|
||||
//
|
||||
// No Warranty
|
||||
//
|
||||
// THE SOFTWARE AND ANY OTHER MATERIALS PROVIDED BY NVIDIA ON THE ENCLOSED CD-ROM ARE PROVIDED "AS IS." NVIDIA DISCLAIMS ALL
|
||||
// WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
//
|
||||
// Limitation of Liability
|
||||
//
|
||||
// NVIDIA SHALL NOT BE LIABLE TO ANY USER, DEVELOPER, DEVELOPER'S CUSTOMERS, OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH OR
|
||||
// UNDER DEVELOPER FOR ANY LOSS OF PROFITS, INCOME, SAVINGS, OR ANY OTHER CONSEQUENTIAL, INCIDENTAL, SPECIAL, PUNITIVE, DIRECT
|
||||
// OR INDIRECT DAMAGES (WHETHER IN AN ACTION IN CONTRACT, TORT OR BASED ON A WARRANTY), EVEN IF NVIDIA HAS BEEN ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF THE ESSENTIAL PURPOSE OF ANY
|
||||
// LIMITED REMEDY. IN NO EVENT SHALL NVIDIA'S AGGREGATE LIABILITY TO DEVELOPER OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH
|
||||
// OR UNDER DEVELOPER EXCEED THE AMOUNT OF MONEY ACTUALLY PAID BY DEVELOPER TO NVIDIA FOR THE SOFTWARE OR ANY OTHER MATERIALS.
|
||||
//
|
||||
|
||||
//
|
||||
// Atmospheric scattering fragment shader
|
||||
//
|
||||
// Author: Sean O'Neil
|
||||
//
|
||||
// Copyright (c) 2004 Sean O'Neil
|
||||
//
|
||||
|
||||
#version 120
|
||||
|
||||
uniform vec3 v3LightPos;
|
||||
uniform float g;
|
||||
uniform float g2;
|
||||
|
||||
varying vec3 v3Direction;
|
||||
|
||||
|
||||
void main (void)
|
||||
{
|
||||
float fCos = dot(v3LightPos, v3Direction) / length(v3Direction);
|
||||
float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos*fCos) / pow(1.0 + g2 - 2.0*g*fCos, 1.5);
|
||||
gl_FragColor = gl_Color + fMiePhase * gl_SecondaryColor;
|
||||
gl_FragColor.a = gl_FragColor.b;
|
||||
}
|
109
interface/resources/shaders/SkyFromSpace.vert
Normal file
109
interface/resources/shaders/SkyFromSpace.vert
Normal file
|
@ -0,0 +1,109 @@
|
|||
//
|
||||
// For licensing information, see http://http.developer.nvidia.com/GPUGems/gpugems_app01.html:
|
||||
//
|
||||
// NVIDIA Statement on the Software
|
||||
//
|
||||
// The source code provided is freely distributable, so long as the NVIDIA header remains unaltered and user modifications are
|
||||
// detailed.
|
||||
//
|
||||
// No Warranty
|
||||
//
|
||||
// THE SOFTWARE AND ANY OTHER MATERIALS PROVIDED BY NVIDIA ON THE ENCLOSED CD-ROM ARE PROVIDED "AS IS." NVIDIA DISCLAIMS ALL
|
||||
// WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
//
|
||||
// Limitation of Liability
|
||||
//
|
||||
// NVIDIA SHALL NOT BE LIABLE TO ANY USER, DEVELOPER, DEVELOPER'S CUSTOMERS, OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH OR
|
||||
// UNDER DEVELOPER FOR ANY LOSS OF PROFITS, INCOME, SAVINGS, OR ANY OTHER CONSEQUENTIAL, INCIDENTAL, SPECIAL, PUNITIVE, DIRECT
|
||||
// OR INDIRECT DAMAGES (WHETHER IN AN ACTION IN CONTRACT, TORT OR BASED ON A WARRANTY), EVEN IF NVIDIA HAS BEEN ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF THE ESSENTIAL PURPOSE OF ANY
|
||||
// LIMITED REMEDY. IN NO EVENT SHALL NVIDIA'S AGGREGATE LIABILITY TO DEVELOPER OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH
|
||||
// OR UNDER DEVELOPER EXCEED THE AMOUNT OF MONEY ACTUALLY PAID BY DEVELOPER TO NVIDIA FOR THE SOFTWARE OR ANY OTHER MATERIALS.
|
||||
//
|
||||
|
||||
//
|
||||
// Atmospheric scattering vertex shader
|
||||
//
|
||||
// Author: Sean O'Neil
|
||||
//
|
||||
// Copyright (c) 2004 Sean O'Neil
|
||||
//
|
||||
|
||||
#version 120
|
||||
|
||||
uniform vec3 v3CameraPos; // The camera's current position
|
||||
uniform vec3 v3LightPos; // The direction vector to the light source
|
||||
uniform vec3 v3InvWavelength; // 1 / pow(wavelength, 4) for the red, green, and blue channels
|
||||
uniform float fCameraHeight2; // fCameraHeight^2
|
||||
uniform float fOuterRadius; // The outer (atmosphere) radius
|
||||
uniform float fOuterRadius2; // fOuterRadius^2
|
||||
uniform float fInnerRadius; // The inner (planetary) radius
|
||||
uniform float fKrESun; // Kr * ESun
|
||||
uniform float fKmESun; // Km * ESun
|
||||
uniform float fKr4PI; // Kr * 4 * PI
|
||||
uniform float fKm4PI; // Km * 4 * PI
|
||||
uniform float fScale; // 1 / (fOuterRadius - fInnerRadius)
|
||||
uniform float fScaleDepth; // The scale depth (i.e. the altitude at which the atmosphere's average density is found)
|
||||
uniform float fScaleOverScaleDepth; // fScale / fScaleDepth
|
||||
|
||||
const int nSamples = 2;
|
||||
const float fSamples = 2.0;
|
||||
|
||||
varying vec3 v3Direction;
|
||||
|
||||
|
||||
float scale(float fCos)
|
||||
{
|
||||
float x = 1.0 - fCos;
|
||||
return fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// Get the ray from the camera to the vertex and its length (which is the far point of the ray passing through the atmosphere)
|
||||
vec3 v3Pos = gl_Vertex.xyz;
|
||||
vec3 v3Ray = v3Pos - v3CameraPos;
|
||||
float fFar = length(v3Ray);
|
||||
v3Ray /= fFar;
|
||||
|
||||
// Calculate the closest intersection of the ray with the outer atmosphere (which is the near point of the ray passing through the atmosphere)
|
||||
float B = 2.0 * dot(v3CameraPos, v3Ray);
|
||||
float C = fCameraHeight2 - fOuterRadius2;
|
||||
float fDet = max(0.0, B*B - 4.0 * C);
|
||||
float fNear = 0.5 * (-B - sqrt(fDet));
|
||||
|
||||
// Calculate the ray's starting position, then calculate its scattering offset
|
||||
vec3 v3Start = v3CameraPos + v3Ray * fNear;
|
||||
fFar -= fNear;
|
||||
float fStartAngle = dot(v3Ray, v3Start) / fOuterRadius;
|
||||
float fStartDepth = exp(-1.0 / fScaleDepth);
|
||||
float fStartOffset = fStartDepth * scale(fStartAngle);
|
||||
|
||||
// Initialize the scattering loop variables
|
||||
//gl_FrontColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
float fSampleLength = fFar / fSamples;
|
||||
float fScaledLength = fSampleLength * fScale;
|
||||
vec3 v3SampleRay = v3Ray * fSampleLength;
|
||||
vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5;
|
||||
|
||||
// Now loop through the sample rays
|
||||
vec3 v3FrontColor = vec3(0.0, 0.0, 0.0);
|
||||
for(int i=0; i<nSamples; i++)
|
||||
{
|
||||
float fHeight = length(v3SamplePoint);
|
||||
float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
|
||||
float fLightAngle = dot(v3LightPos, v3SamplePoint) / fHeight;
|
||||
float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight;
|
||||
float fScatter = (fStartOffset + fDepth * (scale(fLightAngle) - scale(fCameraAngle)));
|
||||
vec3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI));
|
||||
v3FrontColor += v3Attenuate * (fDepth * fScaledLength);
|
||||
v3SamplePoint += v3SampleRay;
|
||||
}
|
||||
|
||||
// Finally, scale the Mie and Rayleigh colors and set up the varying variables for the pixel shader
|
||||
gl_FrontSecondaryColor.rgb = v3FrontColor * fKmESun;
|
||||
gl_FrontColor.rgb = v3FrontColor * (v3InvWavelength * fKrESun);
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
v3Direction = v3CameraPos - v3Pos;
|
||||
}
|
114
interface/src/Environment.cpp
Normal file
114
interface/src/Environment.cpp
Normal file
|
@ -0,0 +1,114 @@
|
|||
//
|
||||
// Environment.cpp
|
||||
// interface
|
||||
//
|
||||
// Created by Andrzej Kapolka on 5/6/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
|
||||
#include <QByteArray>
|
||||
|
||||
#include "Camera.h"
|
||||
#include "Environment.h"
|
||||
#include "renderer/ProgramObject.h"
|
||||
#include "renderer/ShaderObject.h"
|
||||
#include "world.h"
|
||||
|
||||
void Environment::init() {
|
||||
_skyFromAtmosphereProgram = createSkyProgram("Atmosphere", _skyFromAtmosphereUniformLocations);
|
||||
_skyFromSpaceProgram = createSkyProgram("Space", _skyFromSpaceUniformLocations);
|
||||
}
|
||||
|
||||
void Environment::renderAtmosphere(Camera& camera) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glTranslatef(getAtmosphereCenter().x, getAtmosphereCenter().y, getAtmosphereCenter().z);
|
||||
|
||||
// use the camera distance to reset the near and far distances to keep the atmosphere in the frustum
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
|
||||
float projection[16];
|
||||
glGetFloatv(GL_PROJECTION_MATRIX, projection);
|
||||
glm::vec3 relativeCameraPos = camera.getPosition() - getAtmosphereCenter();
|
||||
float height = glm::length(relativeCameraPos);
|
||||
float near = camera.getNearClip(), far = height + getAtmosphereOuterRadius();
|
||||
projection[10] = (far + near) / (near - far);
|
||||
projection[14] = (2.0f * far * near) / (near - far);
|
||||
glLoadMatrixf(projection);
|
||||
|
||||
// use the appropriate shader depending on whether we're inside or outside
|
||||
ProgramObject* program;
|
||||
int* locations;
|
||||
if (height < getAtmosphereOuterRadius()) {
|
||||
program = _skyFromAtmosphereProgram;
|
||||
locations = _skyFromAtmosphereUniformLocations;
|
||||
|
||||
} else {
|
||||
program = _skyFromSpaceProgram;
|
||||
locations = _skyFromSpaceUniformLocations;
|
||||
}
|
||||
|
||||
// the constants here are from Sean O'Neil's GPU Gems entry
|
||||
// (http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html), GameEngine.cpp
|
||||
program->bind();
|
||||
program->setUniform(locations[CAMERA_POS_LOCATION], relativeCameraPos);
|
||||
glm::vec3 lightDirection = glm::normalize(getSunLocation());
|
||||
program->setUniform(locations[LIGHT_POS_LOCATION], lightDirection);
|
||||
program->setUniform(locations[INV_WAVELENGTH_LOCATION],
|
||||
1 / powf(getScatteringWavelengths().r, 4.0f),
|
||||
1 / powf(getScatteringWavelengths().g, 4.0f),
|
||||
1 / powf(getScatteringWavelengths().b, 4.0f));
|
||||
program->setUniform(locations[CAMERA_HEIGHT2_LOCATION], height * height);
|
||||
program->setUniform(locations[OUTER_RADIUS_LOCATION], getAtmosphereOuterRadius());
|
||||
program->setUniform(locations[OUTER_RADIUS2_LOCATION], getAtmosphereOuterRadius() * getAtmosphereOuterRadius());
|
||||
program->setUniform(locations[INNER_RADIUS_LOCATION], getAtmosphereInnerRadius());
|
||||
program->setUniform(locations[KR_ESUN_LOCATION], getRayleighScattering() * getSunBrightness());
|
||||
program->setUniform(locations[KM_ESUN_LOCATION], getMieScattering() * getSunBrightness());
|
||||
program->setUniform(locations[KR_4PI_LOCATION], getRayleighScattering() * 4.0f * PIf);
|
||||
program->setUniform(locations[KM_4PI_LOCATION], getMieScattering() * 4.0f * PIf);
|
||||
program->setUniform(locations[SCALE_LOCATION], 1.0f / (getAtmosphereOuterRadius() - getAtmosphereInnerRadius()));
|
||||
program->setUniform(locations[SCALE_DEPTH_LOCATION], 0.25f);
|
||||
program->setUniform(locations[SCALE_OVER_SCALE_DEPTH_LOCATION],
|
||||
(1.0f / (getAtmosphereOuterRadius() - getAtmosphereInnerRadius())) / 0.25f);
|
||||
program->setUniform(locations[G_LOCATION], -0.990f);
|
||||
program->setUniform(locations[G2_LOCATION], -0.990f * -0.990f);
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glutSolidSphere(getAtmosphereOuterRadius(), 100, 50);
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
program->release();
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
ProgramObject* Environment::createSkyProgram(const char* from, int* locations) {
|
||||
ProgramObject* program = new ProgramObject();
|
||||
QByteArray prefix = QByteArray("resources/shaders/SkyFrom") + from;
|
||||
program->attachFromSourceFile(GL_VERTEX_SHADER_ARB, prefix + ".vert");
|
||||
program->attachFromSourceFile(GL_FRAGMENT_SHADER_ARB, prefix + ".frag");
|
||||
program->link();
|
||||
|
||||
locations[CAMERA_POS_LOCATION] = program->getUniformLocation("v3CameraPos");
|
||||
locations[LIGHT_POS_LOCATION] = program->getUniformLocation("v3LightPos");
|
||||
locations[INV_WAVELENGTH_LOCATION] = program->getUniformLocation("v3InvWavelength");
|
||||
locations[CAMERA_HEIGHT2_LOCATION] = program->getUniformLocation("fCameraHeight2");
|
||||
locations[OUTER_RADIUS_LOCATION] = program->getUniformLocation("fOuterRadius");
|
||||
locations[OUTER_RADIUS2_LOCATION] = program->getUniformLocation("fOuterRadius2");
|
||||
locations[INNER_RADIUS_LOCATION] = program->getUniformLocation("fInnerRadius");
|
||||
locations[KR_ESUN_LOCATION] = program->getUniformLocation("fKrESun");
|
||||
locations[KM_ESUN_LOCATION] = program->getUniformLocation("fKmESun");
|
||||
locations[KR_4PI_LOCATION] = program->getUniformLocation("fKr4PI");
|
||||
locations[KM_4PI_LOCATION] = program->getUniformLocation("fKm4PI");
|
||||
locations[SCALE_LOCATION] = program->getUniformLocation("fScale");
|
||||
locations[SCALE_DEPTH_LOCATION] = program->getUniformLocation("fScaleDepth");
|
||||
locations[SCALE_OVER_SCALE_DEPTH_LOCATION] = program->getUniformLocation("fScaleOverScaleDepth");
|
||||
locations[G_LOCATION] = program->getUniformLocation("g");
|
||||
locations[G2_LOCATION] = program->getUniformLocation("g2");
|
||||
|
||||
return program;
|
||||
}
|
55
interface/src/Environment.h
Normal file
55
interface/src/Environment.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
//
|
||||
// Environment.h
|
||||
// interface
|
||||
//
|
||||
// Created by Andrzej Kapolka on 5/6/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __interface__Environment__
|
||||
#define __interface__Environment__
|
||||
|
||||
#include "EnvironmentData.h"
|
||||
#include "InterfaceConfig.h"
|
||||
|
||||
class Camera;
|
||||
class ProgramObject;
|
||||
|
||||
class Environment : public EnvironmentData {
|
||||
public:
|
||||
|
||||
void init();
|
||||
void renderAtmosphere(Camera& camera);
|
||||
|
||||
private:
|
||||
|
||||
ProgramObject* createSkyProgram(const char* from, int* locations);
|
||||
|
||||
ProgramObject* _skyFromAtmosphereProgram;
|
||||
ProgramObject* _skyFromSpaceProgram;
|
||||
|
||||
enum {
|
||||
CAMERA_POS_LOCATION,
|
||||
LIGHT_POS_LOCATION,
|
||||
INV_WAVELENGTH_LOCATION,
|
||||
CAMERA_HEIGHT2_LOCATION,
|
||||
OUTER_RADIUS_LOCATION,
|
||||
OUTER_RADIUS2_LOCATION,
|
||||
INNER_RADIUS_LOCATION,
|
||||
KR_ESUN_LOCATION,
|
||||
KM_ESUN_LOCATION,
|
||||
KR_4PI_LOCATION,
|
||||
KM_4PI_LOCATION,
|
||||
SCALE_LOCATION,
|
||||
SCALE_DEPTH_LOCATION,
|
||||
SCALE_OVER_SCALE_DEPTH_LOCATION,
|
||||
G_LOCATION,
|
||||
G2_LOCATION,
|
||||
LOCATION_COUNT
|
||||
};
|
||||
|
||||
int _skyFromAtmosphereUniformLocations[LOCATION_COUNT];
|
||||
int _skyFromSpaceUniformLocations[LOCATION_COUNT];
|
||||
};
|
||||
|
||||
#endif /* defined(__interface__Environment__) */
|
|
@ -34,7 +34,7 @@ float Stars::changeLOD(float fraction, float overalloc, float realloc) {
|
|||
return float(_ptrController->changeLOD(fraction, overalloc, realloc));
|
||||
}
|
||||
|
||||
void Stars::render(float fovY, float aspect, float nearZ) {
|
||||
void Stars::render(float fovY, float aspect, float nearZ, float alpha) {
|
||||
|
||||
// determine length of screen diagonal from quadrant height and aspect ratio
|
||||
float quadrantHeight = nearZ * tan(angleConvert<Degrees,Radians>(fovY) * 0.5f);
|
||||
|
@ -46,7 +46,7 @@ void Stars::render(float fovY, float aspect, float nearZ) {
|
|||
// pull the modelview matrix off the GL stack
|
||||
glm::mat4 view; glGetFloatv(GL_MODELVIEW_MATRIX, glm::value_ptr(view));
|
||||
|
||||
_ptrController->render(fovDiagonal, aspect, glm::affineInverse(view));
|
||||
_ptrController->render(fovDiagonal, aspect, glm::affineInverse(view), alpha);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ class Stars {
|
|||
// Renders the starfield from a local viewer's perspective.
|
||||
// The parameters specifiy the field of view.
|
||||
//
|
||||
void render(float fovY, float aspect, float nearZ);
|
||||
void render(float fovY, float aspect, float nearZ, float alpha);
|
||||
|
||||
//
|
||||
// Sets the resolution for FOV culling.
|
||||
|
|
|
@ -58,12 +58,15 @@
|
|||
#include "ui/MenuColumn.h"
|
||||
#include "ui/Menu.h"
|
||||
#include "ui/TextRenderer.h"
|
||||
#include "renderer/ProgramObject.h"
|
||||
#include "renderer/ShaderObject.h"
|
||||
|
||||
#include "Camera.h"
|
||||
#include "Avatar.h"
|
||||
#include <AgentList.h>
|
||||
#include <AgentTypes.h>
|
||||
#include "VoxelSystem.h"
|
||||
#include "Environment.h"
|
||||
#include "Oscilloscope.h"
|
||||
#include "UDPSocket.h"
|
||||
#include "SerialInterface.h"
|
||||
|
@ -125,6 +128,8 @@ VoxelSystem voxels;
|
|||
|
||||
bool wantToKillLocalVoxels = false;
|
||||
|
||||
Environment environment;
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
Audio audio(&audioScope, &myAvatar);
|
||||
|
@ -140,6 +145,7 @@ bool renderWarningsOn = false; // Whether to show render pipeline warnings
|
|||
|
||||
bool statsOn = false; // Whether to show onscreen text overlay with stats
|
||||
bool starsOn = false; // Whether to display the stars
|
||||
bool atmosphereOn = true; // Whether to display the atmosphere
|
||||
bool paintOn = false; // Whether to paint voxels as you fly around
|
||||
VoxelDetail paintingVoxel; // The voxel we're painting if we're painting
|
||||
unsigned char dominantColor = 0; // The dominant color of the voxel we're painting
|
||||
|
@ -174,7 +180,7 @@ bool chatEntryOn = false; // Whether to show the chat entry
|
|||
|
||||
bool oculusOn = false; // Whether to configure the display for the Oculus Rift
|
||||
GLuint oculusTextureID = 0; // The texture to which we render for Oculus distortion
|
||||
GLhandleARB oculusProgramID = 0; // The GLSL program containing the distortion shader
|
||||
ProgramObject* oculusProgram = 0; // The GLSL program containing the distortion shader
|
||||
float oculusDistortionScale = 1.25; // Controls the Oculus field of view
|
||||
|
||||
//
|
||||
|
@ -299,6 +305,8 @@ void init(void) {
|
|||
voxels.setViewerAvatar(&myAvatar);
|
||||
voxels.setCamera(&myCamera);
|
||||
|
||||
environment.init();
|
||||
|
||||
handControl.setScreenDimensions(WIDTH, HEIGHT);
|
||||
|
||||
headMouseX = WIDTH/2;
|
||||
|
@ -678,10 +686,28 @@ void displaySide(Camera& whichCamera) {
|
|||
if (::starsOn) {
|
||||
// should be the first rendering pass - w/o depth buffer / lighting
|
||||
|
||||
// compute starfield alpha based on distance from atmosphere
|
||||
float alpha = 1.0f;
|
||||
if (::atmosphereOn) {
|
||||
float height = glm::distance(whichCamera.getPosition(), environment.getAtmosphereCenter());
|
||||
if (height < environment.getAtmosphereInnerRadius()) {
|
||||
alpha = 0.0f;
|
||||
|
||||
} else if (height < environment.getAtmosphereOuterRadius()) {
|
||||
alpha = (height - environment.getAtmosphereInnerRadius()) /
|
||||
(environment.getAtmosphereOuterRadius() - environment.getAtmosphereInnerRadius());
|
||||
}
|
||||
}
|
||||
|
||||
// finally render the starfield
|
||||
stars.render(whichCamera.getFieldOfView(), aspectRatio, whichCamera.getNearClip());
|
||||
stars.render(whichCamera.getFieldOfView(), aspectRatio, whichCamera.getNearClip(), alpha);
|
||||
}
|
||||
|
||||
// draw the sky dome
|
||||
if (::atmosphereOn) {
|
||||
environment.renderAtmosphere(whichCamera);
|
||||
}
|
||||
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
|
@ -802,18 +828,16 @@ void displayOculus(Camera& whichCamera) {
|
|||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, WIDTH, HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
GLhandleARB shaderID = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
|
||||
glShaderSourceARB(shaderID, 1, &DISTORTION_FRAGMENT_SHADER, 0);
|
||||
glCompileShaderARB(shaderID);
|
||||
::oculusProgramID = glCreateProgramObjectARB();
|
||||
glAttachObjectARB(::oculusProgramID, shaderID);
|
||||
glLinkProgramARB(::oculusProgramID);
|
||||
textureLocation = glGetUniformLocationARB(::oculusProgramID, "texture");
|
||||
lensCenterLocation = glGetUniformLocationARB(::oculusProgramID, "lensCenter");
|
||||
screenCenterLocation = glGetUniformLocationARB(::oculusProgramID, "screenCenter");
|
||||
scaleLocation = glGetUniformLocationARB(::oculusProgramID, "scale");
|
||||
scaleInLocation = glGetUniformLocationARB(::oculusProgramID, "scaleIn");
|
||||
hmdWarpParamLocation = glGetUniformLocationARB(::oculusProgramID, "hmdWarpParam");
|
||||
::oculusProgram = new ProgramObject();
|
||||
::oculusProgram->attachFromSourceCode(GL_FRAGMENT_SHADER_ARB, DISTORTION_FRAGMENT_SHADER);
|
||||
::oculusProgram->link();
|
||||
|
||||
textureLocation = ::oculusProgram->getUniformLocation("texture");
|
||||
lensCenterLocation = ::oculusProgram->getUniformLocation("lensCenter");
|
||||
screenCenterLocation = ::oculusProgram->getUniformLocation("screenCenter");
|
||||
scaleLocation = ::oculusProgram->getUniformLocation("scale");
|
||||
scaleInLocation = ::oculusProgram->getUniformLocation("scaleIn");
|
||||
hmdWarpParamLocation = ::oculusProgram->getUniformLocation("hmdWarpParam");
|
||||
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_2D, ::oculusTextureID);
|
||||
|
@ -833,13 +857,13 @@ void displayOculus(Camera& whichCamera) {
|
|||
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glUseProgramObjectARB(::oculusProgramID);
|
||||
glUniform1iARB(textureLocation, 0);
|
||||
glUniform2fARB(lensCenterLocation, 0.287994, 0.5); // see SDK docs, p. 29
|
||||
glUniform2fARB(screenCenterLocation, 0.25, 0.5);
|
||||
glUniform2fARB(scaleLocation, 0.25 * scaleFactor, 0.5 * scaleFactor * aspectRatio);
|
||||
glUniform2fARB(scaleInLocation, 4, 2 / aspectRatio);
|
||||
glUniform4fARB(hmdWarpParamLocation, 1.0, 0.22, 0.24, 0);
|
||||
::oculusProgram->bind();
|
||||
::oculusProgram->setUniform(textureLocation, 0);
|
||||
::oculusProgram->setUniform(lensCenterLocation, 0.287994, 0.5); // see SDK docs, p. 29
|
||||
::oculusProgram->setUniform(screenCenterLocation, 0.25, 0.5);
|
||||
::oculusProgram->setUniform(scaleLocation, 0.25 * scaleFactor, 0.5 * scaleFactor * aspectRatio);
|
||||
::oculusProgram->setUniform(scaleInLocation, 4, 2 / aspectRatio);
|
||||
::oculusProgram->setUniform(hmdWarpParamLocation, 1.0, 0.22, 0.24, 0);
|
||||
|
||||
glColor3f(1, 0, 1);
|
||||
glBegin(GL_QUADS);
|
||||
|
@ -853,8 +877,8 @@ void displayOculus(Camera& whichCamera) {
|
|||
glVertex2f(0, HEIGHT);
|
||||
glEnd();
|
||||
|
||||
glUniform2fARB(lensCenterLocation, 0.787994, 0.5);
|
||||
glUniform2fARB(screenCenterLocation, 0.75, 0.5);
|
||||
::oculusProgram->setUniform(lensCenterLocation, 0.787994, 0.5);
|
||||
::oculusProgram->setUniform(screenCenterLocation, 0.75, 0.5);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.5, 0);
|
||||
|
@ -870,7 +894,7 @@ void displayOculus(Camera& whichCamera) {
|
|||
glEnable(GL_BLEND);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glUseProgramObjectARB(0);
|
||||
::oculusProgram->release();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
@ -1205,6 +1229,10 @@ int setStars(int state) {
|
|||
return setValue(state, &::starsOn);
|
||||
}
|
||||
|
||||
int setAtmosphere(int state) {
|
||||
return setValue(state, &::atmosphereOn);
|
||||
}
|
||||
|
||||
int setOculus(int state) {
|
||||
bool wasOn = ::oculusOn;
|
||||
int value = setValue(state, &::oculusOn);
|
||||
|
@ -1350,6 +1378,7 @@ void initMenu() {
|
|||
menuColumnRender = menu.addColumn("Render");
|
||||
menuColumnRender->addRow("Voxels (V)", setVoxels);
|
||||
menuColumnRender->addRow("Stars (*)", setStars);
|
||||
menuColumnRender->addRow("Atmosphere (A)", setAtmosphere);
|
||||
menuColumnRender->addRow("Oculus (o)", setOculus);
|
||||
|
||||
// Tools
|
||||
|
@ -1515,6 +1544,7 @@ void key(unsigned char k, int x, int y) {
|
|||
if (k == '/') ::statsOn = !::statsOn; // toggle stats
|
||||
if (k == '*') ::starsOn = !::starsOn; // toggle stars
|
||||
if (k == 'V' || k == 'v') ::showingVoxels = !::showingVoxels; // toggle voxels
|
||||
if (k == 'A') ::atmosphereOn = !::atmosphereOn;
|
||||
if (k == 'F') ::frustumOn = !::frustumOn; // toggle view frustum debugging
|
||||
if (k == 'C') ::cameraFrustum = !::cameraFrustum; // toggle which frustum to look at
|
||||
if (k == 'O' || k == 'G') setFrustumOffset(MENU_ROW_PICKED); // toggle view frustum offset debugging
|
||||
|
@ -1608,6 +1638,9 @@ void* networkReceive(void* args) {
|
|||
case PACKET_HEADER_ERASE_VOXEL:
|
||||
voxels.parseData(incomingPacket, bytesReceived);
|
||||
break;
|
||||
case PACKET_HEADER_ENVIRONMENT_DATA:
|
||||
environment.parseData(incomingPacket, bytesReceived);
|
||||
break;
|
||||
case PACKET_HEADER_BULK_AVATAR_DATA:
|
||||
AgentList::getInstance()->processBulkAgentData(&senderAddress,
|
||||
incomingPacket,
|
||||
|
@ -1712,6 +1745,7 @@ void reshape(int width, int height) {
|
|||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
} else {
|
||||
camera.setAspectRatio(aspectRatio);
|
||||
camera.setFieldOfView(fov = 60);
|
||||
}
|
||||
|
||||
|
|
119
interface/src/renderer/ProgramObject.cpp
Normal file
119
interface/src/renderer/ProgramObject.cpp
Normal file
|
@ -0,0 +1,119 @@
|
|||
//
|
||||
// ProgramObject.cpp
|
||||
// interface
|
||||
//
|
||||
// Created by Andrzej Kapolka on 5/7/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
|
||||
#include "ProgramObject.h"
|
||||
#include "ShaderObject.h"
|
||||
|
||||
ProgramObject::ProgramObject() : _handle(glCreateProgramObjectARB()) {
|
||||
}
|
||||
|
||||
ProgramObject::~ProgramObject() {
|
||||
glDeleteObjectARB(_handle);
|
||||
}
|
||||
|
||||
void ProgramObject::attach(ShaderObject* shader) {
|
||||
glAttachObjectARB(_handle, shader->getHandle());
|
||||
}
|
||||
|
||||
bool ProgramObject::attachFromSourceCode(int type, const char* source) {
|
||||
ShaderObject* shader = new ShaderObject(type);
|
||||
if (shader->compileSourceCode(source)) {
|
||||
attach(shader);
|
||||
return true;
|
||||
|
||||
} else {
|
||||
delete shader;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ProgramObject::attachFromSourceFile(int type, const char* filename) {
|
||||
ShaderObject* shader = new ShaderObject(type);
|
||||
if (shader->compileSourceFile(filename)) {
|
||||
attach(shader);
|
||||
return true;
|
||||
|
||||
} else {
|
||||
delete shader;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ProgramObject::link() {
|
||||
glLinkProgramARB(_handle);
|
||||
int status;
|
||||
glGetObjectParameterivARB(_handle, GL_OBJECT_LINK_STATUS_ARB, &status);
|
||||
return status;
|
||||
}
|
||||
|
||||
QByteArray ProgramObject::getLog() const {
|
||||
int length;
|
||||
glGetObjectParameterivARB(_handle, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
|
||||
QByteArray log(length, 0);
|
||||
glGetInfoLogARB(_handle, length, 0, log.data());
|
||||
return log;
|
||||
}
|
||||
|
||||
void ProgramObject::bind() const {
|
||||
glUseProgramObjectARB(_handle);
|
||||
}
|
||||
|
||||
void ProgramObject::release() const {
|
||||
glUseProgramObjectARB(0);
|
||||
}
|
||||
|
||||
int ProgramObject::getUniformLocation(const char* name) const {
|
||||
return glGetUniformLocationARB(_handle, name);
|
||||
}
|
||||
|
||||
void ProgramObject::setUniform(int location, int value) {
|
||||
glUniform1iARB(location, value);
|
||||
}
|
||||
|
||||
void ProgramObject::setUniform(const char* name, int value) {
|
||||
setUniform(getUniformLocation(name), value);
|
||||
}
|
||||
|
||||
void ProgramObject::setUniform(int location, float value) {
|
||||
glUniform1fARB(location, value);
|
||||
}
|
||||
|
||||
void ProgramObject::setUniform(const char* name, float value) {
|
||||
setUniform(getUniformLocation(name), value);
|
||||
}
|
||||
|
||||
void ProgramObject::setUniform(int location, float x, float y) {
|
||||
glUniform2fARB(location, x, y);
|
||||
}
|
||||
|
||||
void ProgramObject::setUniform(const char* name, float x, float y) {
|
||||
setUniform(getUniformLocation(name), x, y);
|
||||
}
|
||||
|
||||
void ProgramObject::setUniform(int location, const glm::vec3& value) {
|
||||
glUniform3fARB(location, value.x, value.y, value.z);
|
||||
}
|
||||
|
||||
void ProgramObject::setUniform(const char* name, const glm::vec3& value) {
|
||||
setUniform(getUniformLocation(name), value);
|
||||
}
|
||||
|
||||
void ProgramObject::setUniform(int location, float x, float y, float z) {
|
||||
glUniform3fARB(location, x, y, z);
|
||||
}
|
||||
|
||||
void ProgramObject::setUniform(const char* name, float x, float y, float z) {
|
||||
setUniform(getUniformLocation(name), x, y, z);
|
||||
}
|
||||
|
||||
void ProgramObject::setUniform(int location, float x, float y, float z, float w) {
|
||||
glUniform4fARB(location, x, y, z, w);
|
||||
}
|
||||
|
||||
void ProgramObject::setUniform(const char* name, float x, float y, float z, float w) {
|
||||
setUniform(getUniformLocation(name), x, y, z, w);
|
||||
}
|
66
interface/src/renderer/ProgramObject.h
Normal file
66
interface/src/renderer/ProgramObject.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
//
|
||||
// ProgramObject.h
|
||||
// interface
|
||||
//
|
||||
// Created by Andrzej Kapolka on 5/7/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __interface__ProgramObject__
|
||||
#define __interface__ProgramObject__
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "InterfaceConfig.h"
|
||||
|
||||
class ShaderObject;
|
||||
|
||||
class ProgramObject {
|
||||
public:
|
||||
|
||||
ProgramObject();
|
||||
~ProgramObject();
|
||||
|
||||
GLhandleARB getHandle() const { return _handle; }
|
||||
|
||||
void attach(ShaderObject* shader);
|
||||
bool attachFromSourceCode(int type, const char* source);
|
||||
bool attachFromSourceFile(int type, const char* filename);
|
||||
|
||||
bool link();
|
||||
|
||||
QByteArray getLog() const;
|
||||
|
||||
void bind() const;
|
||||
void release() const;
|
||||
|
||||
int getUniformLocation(const char* name) const;
|
||||
|
||||
void setUniform(int location, int value);
|
||||
void setUniform(const char* name, int value);
|
||||
|
||||
void setUniform(int location, float value);
|
||||
void setUniform(const char* name, float value);
|
||||
|
||||
void setUniform(int location, float x, float y);
|
||||
void setUniform(const char* name, float x, float y);
|
||||
|
||||
void setUniform(int location, const glm::vec3& value);
|
||||
void setUniform(const char* name, const glm::vec3& value);
|
||||
|
||||
void setUniform(int location, float x, float y, float z);
|
||||
void setUniform(const char* name, float x, float y, float z);
|
||||
|
||||
void setUniform(int location, float x, float y, float z, float w);
|
||||
void setUniform(const char* name, float x, float y, float z, float w);
|
||||
|
||||
private:
|
||||
|
||||
Q_DISABLE_COPY(ProgramObject)
|
||||
|
||||
GLhandleARB _handle;
|
||||
};
|
||||
|
||||
#endif /* defined(__interface__ProgramObject__) */
|
39
interface/src/renderer/ShaderObject.cpp
Normal file
39
interface/src/renderer/ShaderObject.cpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
//
|
||||
// ShaderObject.cpp
|
||||
// interface
|
||||
//
|
||||
// Created by Andrzej Kapolka on 5/7/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
|
||||
#include <QFile>
|
||||
|
||||
#include "ShaderObject.h"
|
||||
|
||||
ShaderObject::ShaderObject(int type)
|
||||
: _handle(glCreateShaderObjectARB(type)) {
|
||||
}
|
||||
|
||||
ShaderObject::~ShaderObject() {
|
||||
glDeleteObjectARB(_handle);
|
||||
}
|
||||
|
||||
bool ShaderObject::compileSourceCode(const char* data) {
|
||||
glShaderSource(_handle, 1, &data, 0);
|
||||
glCompileShaderARB(_handle);
|
||||
int status;
|
||||
glGetObjectParameterivARB(_handle, GL_OBJECT_COMPILE_STATUS_ARB, &status);
|
||||
return status;
|
||||
}
|
||||
|
||||
bool ShaderObject::compileSourceFile(const char* filename) {
|
||||
QFile file(filename);
|
||||
return file.open(QIODevice::ReadOnly) && compileSourceCode(file.readAll().constData());
|
||||
}
|
||||
|
||||
QByteArray ShaderObject::getLog() const {
|
||||
int length;
|
||||
glGetObjectParameterivARB(_handle, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
|
||||
QByteArray log(length, 0);
|
||||
glGetInfoLogARB(_handle, length, 0, log.data());
|
||||
return log;
|
||||
}
|
36
interface/src/renderer/ShaderObject.h
Normal file
36
interface/src/renderer/ShaderObject.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// ShaderObject.h
|
||||
// interface
|
||||
//
|
||||
// Created by Andrzej Kapolka on 5/7/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __interface__ShaderObject__
|
||||
#define __interface__ShaderObject__
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "InterfaceConfig.h"
|
||||
|
||||
class ShaderObject {
|
||||
public:
|
||||
|
||||
ShaderObject(int type);
|
||||
~ShaderObject();
|
||||
|
||||
GLhandleARB getHandle() const { return _handle; }
|
||||
|
||||
bool compileSourceCode(const char* data);
|
||||
bool compileSourceFile(const char* filename);
|
||||
|
||||
QByteArray getLog() const;
|
||||
|
||||
private:
|
||||
|
||||
Q_DISABLE_COPY(ShaderObject)
|
||||
|
||||
GLhandleARB _handle;
|
||||
};
|
||||
|
||||
#endif /* defined(__interface__ShaderObject__) */
|
|
@ -361,7 +361,7 @@ namespace starfield {
|
|||
|
||||
public:
|
||||
|
||||
void render(float perspective, float angle, mat4 const& orientation) {
|
||||
void render(float perspective, float angle, mat4 const& orientation, float alpha) {
|
||||
|
||||
#if STARFIELD_MULTITHREADING
|
||||
// check out renderer
|
||||
|
@ -377,7 +377,7 @@ namespace starfield {
|
|||
#else
|
||||
BrightnessLevel b = _valLodBrightness;
|
||||
#endif
|
||||
renderer->render(perspective, angle, orientation, b);
|
||||
renderer->render(perspective, angle, orientation, b, alpha);
|
||||
}
|
||||
|
||||
#if STARFIELD_MULTITHREADING
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#error "This is an implementation file - not intended for direct inclusion."
|
||||
#endif
|
||||
|
||||
#include "renderer/ProgramObject.h"
|
||||
|
||||
#include "starfield/Config.h"
|
||||
#include "starfield/data/InputVertex.h"
|
||||
#include "starfield/data/BrightnessLevel.h"
|
||||
|
@ -70,7 +72,8 @@ namespace starfield {
|
|||
GLint* _arrBatchOffs;
|
||||
GLsizei* _arrBatchCount;
|
||||
GLuint _hndVertexArray;
|
||||
OGlProgram _objProgram;
|
||||
ProgramObject _objProgram;
|
||||
int _alphaLocation;
|
||||
|
||||
Tiling _objTiling;
|
||||
|
||||
|
@ -123,7 +126,8 @@ namespace starfield {
|
|||
void render(float perspective,
|
||||
float aspect,
|
||||
mat4 const& orientation,
|
||||
BrightnessLevel minBright) {
|
||||
BrightnessLevel minBright,
|
||||
float alpha) {
|
||||
|
||||
// printLog("
|
||||
// Stars.cpp: rendering at minimal brightness %d\n", minBright);
|
||||
|
@ -186,7 +190,7 @@ namespace starfield {
|
|||
# define matrix matrix_debug
|
||||
#endif
|
||||
this->glBatch(glm::value_ptr(matrix), prepareBatch(
|
||||
(unsigned*) _arrBatchOffs, _itrOutIndex) );
|
||||
(unsigned*) _arrBatchOffs, _itrOutIndex), alpha);
|
||||
|
||||
#if STARFIELD_DEBUG_CULLING
|
||||
# undef matrix
|
||||
|
@ -463,24 +467,26 @@ namespace starfield {
|
|||
|
||||
GLchar const* const VERTEX_SHADER =
|
||||
"#version 120\n"
|
||||
"uniform float alpha;\n"
|
||||
"void main(void) {\n"
|
||||
|
||||
" vec3 c = gl_Color.rgb * 1.0125;\n"
|
||||
" float s = max(1.0, dot(c, c) * 0.7);\n"
|
||||
|
||||
" gl_Position = ftransform();\n"
|
||||
" gl_FrontColor= gl_Color;\n"
|
||||
" gl_FrontColor= gl_Color * alpha;\n"
|
||||
" gl_PointSize = s;\n"
|
||||
"}\n";
|
||||
|
||||
_objProgram.addShader(GL_VERTEX_SHADER, VERTEX_SHADER);
|
||||
_objProgram.attachFromSourceCode(GL_VERTEX_SHADER, VERTEX_SHADER);
|
||||
GLchar const* const FRAGMENT_SHADER =
|
||||
"#version 120\n"
|
||||
"void main(void) {\n"
|
||||
" gl_FragColor = gl_Color;\n"
|
||||
"}\n";
|
||||
_objProgram.addShader(GL_FRAGMENT_SHADER, FRAGMENT_SHADER);
|
||||
_objProgram.attachFromSourceCode(GL_FRAGMENT_SHADER, FRAGMENT_SHADER);
|
||||
_objProgram.link();
|
||||
_alphaLocation = _objProgram.getUniformLocation("alpha");
|
||||
|
||||
glGenBuffersARB(1, & _hndVertexArray);
|
||||
}
|
||||
|
@ -499,7 +505,7 @@ namespace starfield {
|
|||
glBindBufferARB(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void glBatch(GLfloat const* matrix, GLsizei n_ranges) {
|
||||
void glBatch(GLfloat const* matrix, GLsizei n_ranges, float alpha) {
|
||||
|
||||
// printLog("Stars.cpp: rendering %d-multibatch\n", n_ranges);
|
||||
|
||||
|
@ -527,7 +533,8 @@ namespace starfield {
|
|||
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||
|
||||
// select shader and vertex array
|
||||
_objProgram.activate();
|
||||
_objProgram.bind();
|
||||
_objProgram.setUniform(_alphaLocation, alpha);
|
||||
glBindBufferARB(GL_ARRAY_BUFFER, _hndVertexArray);
|
||||
glInterleavedArrays(GL_C4UB_V3F, sizeof(GpuVertex), 0l);
|
||||
|
||||
|
@ -537,7 +544,7 @@ namespace starfield {
|
|||
|
||||
// restore state
|
||||
glBindBufferARB(GL_ARRAY_BUFFER, 0);
|
||||
glUseProgram(0);
|
||||
_objProgram.release();
|
||||
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||
glDisable(GL_POINT_SMOOTH);
|
||||
glPopMatrix();
|
||||
|
|
|
@ -25,6 +25,7 @@ const PACKET_HEADER PACKET_HEADER_ERASE_VOXEL = 'E';
|
|||
const PACKET_HEADER PACKET_HEADER_VOXEL_DATA = 'V';
|
||||
const PACKET_HEADER PACKET_HEADER_BULK_AVATAR_DATA = 'X';
|
||||
const PACKET_HEADER PACKET_HEADER_TRANSMITTER_DATA = 't';
|
||||
const PACKET_HEADER PACKET_HEADER_ENVIRONMENT_DATA = 'e';
|
||||
const PACKET_HEADER PACKET_HEADER_DOMAIN_LIST_REQUEST = 'L';
|
||||
const PACKET_HEADER PACKET_HEADER_DOMAIN_RFD = 'C';
|
||||
|
||||
|
|
90
libraries/voxels/src/EnvironmentData.cpp
Normal file
90
libraries/voxels/src/EnvironmentData.cpp
Normal file
|
@ -0,0 +1,90 @@
|
|||
//
|
||||
// EnvironmentData.cpp
|
||||
// interface
|
||||
//
|
||||
// Created by Andrzej Kapolka on 5/6/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "EnvironmentData.h"
|
||||
#include "PacketHeaders.h"
|
||||
|
||||
// initial values from Sean O'Neil's GPU Gems entry (http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html),
|
||||
// GameEngine.cpp (and the radius of the earth)
|
||||
EnvironmentData::EnvironmentData() :
|
||||
_atmosphereCenter(0, -1000, 0),
|
||||
_atmosphereInnerRadius(1000),
|
||||
_atmosphereOuterRadius(1025),
|
||||
_rayleighScattering(0.0025f),
|
||||
_mieScattering(0.0010f),
|
||||
_scatteringWavelengths(0.650f, 0.570f, 0.475f),
|
||||
_sunLocation(1000, 1000, 0),
|
||||
_sunBrightness(20.0f) {
|
||||
}
|
||||
|
||||
int EnvironmentData::getBroadcastData(unsigned char* destinationBuffer) const {
|
||||
unsigned char* bufferStart = destinationBuffer;
|
||||
|
||||
*destinationBuffer++ = PACKET_HEADER_ENVIRONMENT_DATA;
|
||||
|
||||
memcpy(destinationBuffer, &_atmosphereCenter, sizeof(_atmosphereCenter));
|
||||
destinationBuffer += sizeof(_atmosphereCenter);
|
||||
|
||||
memcpy(destinationBuffer, &_atmosphereInnerRadius, sizeof(_atmosphereInnerRadius));
|
||||
destinationBuffer += sizeof(_atmosphereInnerRadius);
|
||||
|
||||
memcpy(destinationBuffer, &_atmosphereOuterRadius, sizeof(_atmosphereOuterRadius));
|
||||
destinationBuffer += sizeof(_atmosphereOuterRadius);
|
||||
|
||||
memcpy(destinationBuffer, &_rayleighScattering, sizeof(_rayleighScattering));
|
||||
destinationBuffer += sizeof(_rayleighScattering);
|
||||
|
||||
memcpy(destinationBuffer, &_mieScattering, sizeof(_mieScattering));
|
||||
destinationBuffer += sizeof(_mieScattering);
|
||||
|
||||
memcpy(destinationBuffer, &_scatteringWavelengths, sizeof(_scatteringWavelengths));
|
||||
destinationBuffer += sizeof(_scatteringWavelengths);
|
||||
|
||||
memcpy(destinationBuffer, &_sunLocation, sizeof(_sunLocation));
|
||||
destinationBuffer += sizeof(_sunLocation);
|
||||
|
||||
memcpy(destinationBuffer, &_sunBrightness, sizeof(_sunBrightness));
|
||||
destinationBuffer += sizeof(_sunBrightness);
|
||||
|
||||
return destinationBuffer - bufferStart;
|
||||
}
|
||||
|
||||
int EnvironmentData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||
// increment to push past the packet header
|
||||
sourceBuffer++;
|
||||
|
||||
unsigned char* startPosition = sourceBuffer;
|
||||
|
||||
memcpy(&_atmosphereCenter, sourceBuffer, sizeof(_atmosphereCenter));
|
||||
sourceBuffer += sizeof(_atmosphereCenter);
|
||||
|
||||
memcpy(&_atmosphereInnerRadius, sourceBuffer, sizeof(_atmosphereInnerRadius));
|
||||
sourceBuffer += sizeof(_atmosphereInnerRadius);
|
||||
|
||||
memcpy(&_atmosphereOuterRadius, sourceBuffer, sizeof(_atmosphereOuterRadius));
|
||||
sourceBuffer += sizeof(_atmosphereOuterRadius);
|
||||
|
||||
memcpy(&_rayleighScattering, sourceBuffer, sizeof(_rayleighScattering));
|
||||
sourceBuffer += sizeof(_rayleighScattering);
|
||||
|
||||
memcpy(&_mieScattering, sourceBuffer, sizeof(_mieScattering));
|
||||
sourceBuffer += sizeof(_mieScattering);
|
||||
|
||||
memcpy(&_scatteringWavelengths, sourceBuffer, sizeof(_scatteringWavelengths));
|
||||
sourceBuffer += sizeof(_scatteringWavelengths);
|
||||
|
||||
memcpy(&_sunLocation, sourceBuffer, sizeof(_sunLocation));
|
||||
sourceBuffer += sizeof(_sunLocation);
|
||||
|
||||
memcpy(&_sunBrightness, sourceBuffer, sizeof(_sunBrightness));
|
||||
sourceBuffer += sizeof(_sunBrightness);
|
||||
|
||||
return sourceBuffer - startPosition;
|
||||
}
|
||||
|
57
libraries/voxels/src/EnvironmentData.h
Normal file
57
libraries/voxels/src/EnvironmentData.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
//
|
||||
// EnvironmentData.h
|
||||
// interface
|
||||
//
|
||||
// Created by Andrzej Kapolka on 5/6/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __interface__EnvironmentData__
|
||||
#define __interface__EnvironmentData__
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
class EnvironmentData {
|
||||
public:
|
||||
|
||||
EnvironmentData();
|
||||
|
||||
void setAtmosphereCenter(const glm::vec3& center) { _atmosphereCenter = center; }
|
||||
void setAtmosphereInnerRadius(float radius) { _atmosphereInnerRadius = radius; }
|
||||
void setAtmosphereOuterRadius(float radius) { _atmosphereOuterRadius = radius; }
|
||||
const glm::vec3& getAtmosphereCenter() const { return _atmosphereCenter; }
|
||||
float getAtmosphereInnerRadius() const { return _atmosphereInnerRadius; }
|
||||
float getAtmosphereOuterRadius() const { return _atmosphereOuterRadius; }
|
||||
|
||||
void setRayleighScattering(float scattering) { _rayleighScattering = scattering; }
|
||||
void setMieScattering(float scattering) { _mieScattering = scattering; }
|
||||
float getRayleighScattering() const { return _rayleighScattering; }
|
||||
float getMieScattering() const { return _mieScattering; }
|
||||
|
||||
void setScatteringWavelengths(const glm::vec3& wavelengths) { _scatteringWavelengths = wavelengths; }
|
||||
const glm::vec3& getScatteringWavelengths() const { return _scatteringWavelengths; }
|
||||
|
||||
void setSunLocation(const glm::vec3& location) { _sunLocation = location; }
|
||||
void setSunBrightness(float brightness) { _sunBrightness = brightness; }
|
||||
const glm::vec3& getSunLocation() const { return _sunLocation; }
|
||||
float getSunBrightness() const { return _sunBrightness; }
|
||||
|
||||
int getBroadcastData(unsigned char* destinationBuffer) const;
|
||||
int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||
|
||||
private:
|
||||
|
||||
glm::vec3 _atmosphereCenter;
|
||||
float _atmosphereInnerRadius;
|
||||
float _atmosphereOuterRadius;
|
||||
|
||||
float _rayleighScattering;
|
||||
float _mieScattering;
|
||||
|
||||
glm::vec3 _scatteringWavelengths;
|
||||
|
||||
glm::vec3 _sunLocation;
|
||||
float _sunBrightness;
|
||||
};
|
||||
|
||||
#endif /* defined(__interface__EnvironmentData__) */
|
|
@ -13,6 +13,7 @@
|
|||
#include <OctalCode.h>
|
||||
#include <AgentList.h>
|
||||
#include <AgentTypes.h>
|
||||
#include <EnvironmentData.h>
|
||||
#include <VoxelTree.h>
|
||||
#include "VoxelAgentData.h"
|
||||
#include <SharedUtil.h>
|
||||
|
@ -54,6 +55,9 @@ bool wantLocalDomain = false;
|
|||
bool wantColorRandomizer = false;
|
||||
bool debugVoxelSending = false;
|
||||
|
||||
EnvironmentData environmentData;
|
||||
|
||||
|
||||
void randomlyFillVoxelTree(int levelsToGo, VoxelNode *currentRootNode) {
|
||||
// randomly generate children for this node
|
||||
// the first level of the tree (where levelsToGo = MAX_VOXEL_TREE_DEPTH_LEVELS) has all 8
|
||||
|
@ -149,7 +153,7 @@ void voxelDistributor(AgentList* agentList, AgentList::iterator& agent, VoxelAge
|
|||
int trueBytesSent = 0;
|
||||
double start = usecTimestampNow();
|
||||
|
||||
while (packetsSentThisInterval < PACKETS_PER_CLIENT_PER_INTERVAL) {
|
||||
while (packetsSentThisInterval < PACKETS_PER_CLIENT_PER_INTERVAL - 1) {
|
||||
if (!agentData->nodeBag.isEmpty()) {
|
||||
VoxelNode* subTree = agentData->nodeBag.extract();
|
||||
bytesWritten = randomTree.encodeTreeBitstream(agentData->getMaxSearchLevel(), subTree,
|
||||
|
@ -179,6 +183,12 @@ void voxelDistributor(AgentList* agentList, AgentList::iterator& agent, VoxelAge
|
|||
packetsSentThisInterval = PACKETS_PER_CLIENT_PER_INTERVAL; // done for now, no nodes left
|
||||
}
|
||||
}
|
||||
// send the environment packet
|
||||
int envPacketLength = environmentData.getBroadcastData(tempOutputBuffer);
|
||||
agentList->getAgentSocket().send(agent->getActiveSocket(), tempOutputBuffer, envPacketLength);
|
||||
trueBytesSent += envPacketLength;
|
||||
truePacketsSent++;
|
||||
|
||||
double end = usecTimestampNow();
|
||||
double elapsedmsec = (end - start)/1000.0;
|
||||
if (elapsedmsec > 100) {
|
||||
|
@ -464,4 +474,4 @@ int main(int argc, const char * argv[])
|
|||
pthread_join(sendVoxelThread, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue