Merge remote-tracking branch 'upstream/master' into overlay

This commit is contained in:
Brad Davis 2015-06-17 10:50:01 -07:00
commit 5ded9e7eb9
26 changed files with 852 additions and 446 deletions

View file

@ -3245,6 +3245,9 @@ namespace render {
template <> const Item::Bound payloadGetBound(const BackgroundRenderData::Pointer& stuff) { return Item::Bound(); }
template <> void payloadRender(const BackgroundRenderData::Pointer& background, RenderArgs* args) {
Q_ASSERT(args->_batch);
gpu::Batch& batch = *args->_batch;
// Background rendering decision
auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
auto skybox = model::SkyboxPointer();
@ -3312,7 +3315,8 @@ namespace render {
PerformanceTimer perfTimer("atmosphere");
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"Application::displaySide() ... atmosphere...");
background->_environment->renderAtmospheres(*(args->_viewFrustum));
background->_environment->renderAtmospheres(batch, *(args->_viewFrustum));
}
}
@ -3321,13 +3325,13 @@ namespace render {
skybox = skyStage->getSkybox();
if (skybox) {
gpu::Batch batch;
model::Skybox::render(batch, *(Application::getInstance()->getDisplayViewFrustum()), *skybox);
gpu::GLBackend::renderBatch(batch, true);
glUseProgram(0);
}
}
// FIX ME - If I don't call this renderBatch() here, then the atmosphere and skybox don't render, but it
// seems like these payloadRender() methods shouldn't be doing this. We need to investigate why the engine
// isn't rendering our batch
gpu::GLBackend::renderBatch(batch, true);
}
}

View file

@ -43,72 +43,90 @@ void BillboardOverlay::render(RenderArgs* args) {
return;
}
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5f);
glm::quat rotation;
if (_isFacingAvatar) {
// rotate about vertical to face the camera
rotation = Application::getInstance()->getCamera()->getRotation();
rotation *= glm::angleAxis(glm::pi<float>(), glm::vec3(0.0f, 1.0f, 0.0f));
rotation *= getRotation();
} else {
rotation = getRotation();
}
glEnable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
float imageWidth = _texture->getWidth();
float imageHeight = _texture->getHeight();
glBindTexture(GL_TEXTURE_2D, _texture->getID());
QRect fromImage;
if (_fromImage.isNull()) {
fromImage.setX(0);
fromImage.setY(0);
fromImage.setWidth(imageWidth);
fromImage.setHeight(imageHeight);
} else {
float scaleX = imageWidth / _texture->getOriginalWidth();
float scaleY = imageHeight / _texture->getOriginalHeight();
glPushMatrix(); {
glTranslatef(_position.x, _position.y, _position.z);
glm::quat rotation;
if (_isFacingAvatar) {
// rotate about vertical to face the camera
rotation = Application::getInstance()->getCamera()->getRotation();
rotation *= glm::angleAxis(glm::pi<float>(), glm::vec3(0.0f, 1.0f, 0.0f));
rotation *= getRotation();
} else {
rotation = getRotation();
}
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
glScalef(_scale, _scale, _scale);
fromImage.setX(scaleX * _fromImage.x());
fromImage.setY(scaleY * _fromImage.y());
fromImage.setWidth(scaleX * _fromImage.width());
fromImage.setHeight(scaleY * _fromImage.height());
}
const float MAX_COLOR = 255.0f;
xColor color = getColor();
float alpha = getAlpha();
float maxSize = glm::max(fromImage.width(), fromImage.height());
float x = fromImage.width() / (2.0f * maxSize);
float y = -fromImage.height() / (2.0f * maxSize);
float imageWidth = _texture->getWidth();
float imageHeight = _texture->getHeight();
glm::vec2 topLeft(-x, -y);
glm::vec2 bottomRight(x, y);
glm::vec2 texCoordTopLeft(fromImage.x() / imageWidth, fromImage.y() / imageHeight);
glm::vec2 texCoordBottomRight((fromImage.x() + fromImage.width()) / imageWidth,
(fromImage.y() + fromImage.height()) / imageHeight);
QRect fromImage;
if (_fromImage.isNull()) {
fromImage.setX(0);
fromImage.setY(0);
fromImage.setWidth(imageWidth);
fromImage.setHeight(imageHeight);
} else {
float scaleX = imageWidth / _texture->getOriginalWidth();
float scaleY = imageHeight / _texture->getOriginalHeight();
const float MAX_COLOR = 255.0f;
xColor color = getColor();
float alpha = getAlpha();
fromImage.setX(scaleX * _fromImage.x());
fromImage.setY(scaleY * _fromImage.y());
fromImage.setWidth(scaleX * _fromImage.width());
fromImage.setHeight(scaleY * _fromImage.height());
}
auto batch = args->_batch;
float maxSize = glm::max(fromImage.width(), fromImage.height());
float x = fromImage.width() / (2.0f * maxSize);
float y = -fromImage.height() / (2.0f * maxSize);
if (batch) {
Transform transform;
transform.setTranslation(_position);
transform.setRotation(rotation);
transform.setScale(_scale);
glm::vec2 topLeft(-x, -y);
glm::vec2 bottomRight(x, y);
glm::vec2 texCoordTopLeft(fromImage.x() / imageWidth, fromImage.y() / imageHeight);
glm::vec2 texCoordBottomRight((fromImage.x() + fromImage.width()) / imageWidth,
(fromImage.y() + fromImage.height()) / imageHeight);
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
batch->setModelTransform(transform);
batch->setUniformTexture(0, _texture->getGPUTexture());
DependencyManager::get<GeometryCache>()->renderQuad(*batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha));
batch->setUniformTexture(0, args->_whiteTexture); // restore default white color after me
} else {
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5f);
} glPopMatrix();
glEnable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glDisable(GL_ALPHA_TEST);
glBindTexture(GL_TEXTURE_2D, _texture->getID());
glBindTexture(GL_TEXTURE_2D, 0);
glPushMatrix(); {
glTranslatef(_position.x, _position.y, _position.z);
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
glScalef(_scale, _scale, _scale);
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha));
} glPopMatrix();
glDisable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glDisable(GL_ALPHA_TEST);
glBindTexture(GL_TEXTURE_2D, 0);
}
}
void BillboardOverlay::setProperties(const QScriptValue &properties) {

View file

@ -35,13 +35,6 @@ void Cube3DOverlay::render(RenderArgs* args) {
return; // do nothing if we're not visible
}
float glowLevel = getGlowLevel();
Glower* glower = NULL;
if (glowLevel > 0.0f) {
glower = new Glower(glowLevel);
}
float alpha = getAlpha();
xColor color = getColor();
const float MAX_COLOR = 255.0f;
@ -49,91 +42,161 @@ void Cube3DOverlay::render(RenderArgs* args) {
//glDisable(GL_LIGHTING);
// TODO: handle registration point??
// TODO: handle registration point??
glm::vec3 position = getPosition();
glm::vec3 center = getCenter();
glm::vec3 dimensions = getDimensions();
glm::quat rotation = getRotation();
glPushMatrix();
glTranslatef(position.x, position.y, position.z);
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
glPushMatrix();
glm::vec3 positionToCenter = center - position;
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
if (_isSolid) {
if (_borderSize > 0) {
// Draw a cube at a larger size behind the main cube, creating
// a border effect.
// Disable writing to the depth mask so that the "border" cube will not
// occlude the main cube. This means the border could be covered by
// overlays that are further back and drawn later, but this is good
// enough for the use-case.
glDepthMask(GL_FALSE);
glPushMatrix();
glScalef(dimensions.x * _borderSize, dimensions.y * _borderSize, dimensions.z * _borderSize);
if (_drawOnHUD) {
DependencyManager::get<GeometryCache>()->renderSolidCube(1.0f, glm::vec4(1.0f, 1.0f, 1.0f, alpha));
} else {
DependencyManager::get<GeometryCache>()->renderSolidCube(1.0f, glm::vec4(1.0f, 1.0f, 1.0f, alpha));
}
auto batch = args->_batch;
glPopMatrix();
glDepthMask(GL_TRUE);
}
if (batch) {
Transform transform;
transform.setTranslation(position);
transform.setRotation(rotation);
if (_isSolid) {
// if (_borderSize > 0) {
// // Draw a cube at a larger size behind the main cube, creating
// // a border effect.
// // Disable writing to the depth mask so that the "border" cube will not
// // occlude the main cube. This means the border could be covered by
// // overlays that are further back and drawn later, but this is good
// // enough for the use-case.
// transform.setScale(dimensions * _borderSize);
// batch->setModelTransform(transform);
// DependencyManager::get<GeometryCache>()->renderSolidCube(*batch, 1.0f, glm::vec4(1.0f, 1.0f, 1.0f, alpha));
// }
transform.setScale(dimensions);
batch->setModelTransform(transform);
DependencyManager::get<GeometryCache>()->renderSolidCube(*batch, 1.0f, cubeColor);
} else {
if (getIsDashedLine()) {
transform.setScale(1.0f);
batch->setModelTransform(transform);
glm::vec3 halfDimensions = dimensions / 2.0f;
glm::vec3 bottomLeftNear(-halfDimensions.x, -halfDimensions.y, -halfDimensions.z);
glm::vec3 bottomRightNear(halfDimensions.x, -halfDimensions.y, -halfDimensions.z);
glm::vec3 topLeftNear(-halfDimensions.x, halfDimensions.y, -halfDimensions.z);
glm::vec3 topRightNear(halfDimensions.x, halfDimensions.y, -halfDimensions.z);
glm::vec3 bottomLeftFar(-halfDimensions.x, -halfDimensions.y, halfDimensions.z);
glm::vec3 bottomRightFar(halfDimensions.x, -halfDimensions.y, halfDimensions.z);
glm::vec3 topLeftFar(-halfDimensions.x, halfDimensions.y, halfDimensions.z);
glm::vec3 topRightFar(halfDimensions.x, halfDimensions.y, halfDimensions.z);
auto geometryCache = DependencyManager::get<GeometryCache>();
geometryCache->renderDashedLine(*batch, bottomLeftNear, bottomRightNear, cubeColor);
geometryCache->renderDashedLine(*batch, bottomRightNear, bottomRightFar, cubeColor);
geometryCache->renderDashedLine(*batch, bottomRightFar, bottomLeftFar, cubeColor);
geometryCache->renderDashedLine(*batch, bottomLeftFar, bottomLeftNear, cubeColor);
geometryCache->renderDashedLine(*batch, topLeftNear, topRightNear, cubeColor);
geometryCache->renderDashedLine(*batch, topRightNear, topRightFar, cubeColor);
geometryCache->renderDashedLine(*batch, topRightFar, topLeftFar, cubeColor);
geometryCache->renderDashedLine(*batch, topLeftFar, topLeftNear, cubeColor);
geometryCache->renderDashedLine(*batch, bottomLeftNear, topLeftNear, cubeColor);
geometryCache->renderDashedLine(*batch, bottomRightNear, topRightNear, cubeColor);
geometryCache->renderDashedLine(*batch, bottomLeftFar, topLeftFar, cubeColor);
geometryCache->renderDashedLine(*batch, bottomRightFar, topRightFar, cubeColor);
glPushMatrix();
glScalef(dimensions.x, dimensions.y, dimensions.z);
if (_drawOnHUD) {
DependencyManager::get<GeometryCache>()->renderSolidCube(1.0f, cubeColor);
} else {
DependencyManager::get<GeometryCache>()->renderSolidCube(1.0f, cubeColor);
}
glPopMatrix();
} else {
glLineWidth(_lineWidth);
if (getIsDashedLine()) {
glm::vec3 halfDimensions = dimensions / 2.0f;
glm::vec3 bottomLeftNear(-halfDimensions.x, -halfDimensions.y, -halfDimensions.z);
glm::vec3 bottomRightNear(halfDimensions.x, -halfDimensions.y, -halfDimensions.z);
glm::vec3 topLeftNear(-halfDimensions.x, halfDimensions.y, -halfDimensions.z);
glm::vec3 topRightNear(halfDimensions.x, halfDimensions.y, -halfDimensions.z);
glm::vec3 bottomLeftFar(-halfDimensions.x, -halfDimensions.y, halfDimensions.z);
glm::vec3 bottomRightFar(halfDimensions.x, -halfDimensions.y, halfDimensions.z);
glm::vec3 topLeftFar(-halfDimensions.x, halfDimensions.y, halfDimensions.z);
glm::vec3 topRightFar(halfDimensions.x, halfDimensions.y, halfDimensions.z);
auto geometryCache = DependencyManager::get<GeometryCache>();
geometryCache->renderDashedLine(bottomLeftNear, bottomRightNear, cubeColor);
geometryCache->renderDashedLine(bottomRightNear, bottomRightFar, cubeColor);
geometryCache->renderDashedLine(bottomRightFar, bottomLeftFar, cubeColor);
geometryCache->renderDashedLine(bottomLeftFar, bottomLeftNear, cubeColor);
geometryCache->renderDashedLine(topLeftNear, topRightNear, cubeColor);
geometryCache->renderDashedLine(topRightNear, topRightFar, cubeColor);
geometryCache->renderDashedLine(topRightFar, topLeftFar, cubeColor);
geometryCache->renderDashedLine(topLeftFar, topLeftNear, cubeColor);
geometryCache->renderDashedLine(bottomLeftNear, topLeftNear, cubeColor);
geometryCache->renderDashedLine(bottomRightNear, topRightNear, cubeColor);
geometryCache->renderDashedLine(bottomLeftFar, topLeftFar, cubeColor);
geometryCache->renderDashedLine(bottomRightFar, topRightFar, cubeColor);
} else {
glScalef(dimensions.x, dimensions.y, dimensions.z);
DependencyManager::get<GeometryCache>()->renderWireCube(1.0f, cubeColor);
}
transform.setScale(dimensions);
batch->setModelTransform(transform);
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(*batch, 1.0f, cubeColor);
}
glPopMatrix();
glPopMatrix();
}
} else {
float glowLevel = getGlowLevel();
Glower* glower = NULL;
if (glowLevel > 0.0f) {
glower = new Glower(glowLevel);
}
if (glower) {
delete glower;
glPushMatrix();
glTranslatef(position.x, position.y, position.z);
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
glPushMatrix();
glm::vec3 positionToCenter = center - position;
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
if (_isSolid) {
if (_borderSize > 0) {
// Draw a cube at a larger size behind the main cube, creating
// a border effect.
// Disable writing to the depth mask so that the "border" cube will not
// occlude the main cube. This means the border could be covered by
// overlays that are further back and drawn later, but this is good
// enough for the use-case.
glDepthMask(GL_FALSE);
glPushMatrix();
glScalef(dimensions.x * _borderSize, dimensions.y * _borderSize, dimensions.z * _borderSize);
if (_drawOnHUD) {
DependencyManager::get<GeometryCache>()->renderSolidCube(1.0f, glm::vec4(1.0f, 1.0f, 1.0f, alpha));
} else {
DependencyManager::get<GeometryCache>()->renderSolidCube(1.0f, glm::vec4(1.0f, 1.0f, 1.0f, alpha));
}
glPopMatrix();
glDepthMask(GL_TRUE);
}
glPushMatrix();
glScalef(dimensions.x, dimensions.y, dimensions.z);
if (_drawOnHUD) {
DependencyManager::get<GeometryCache>()->renderSolidCube(1.0f, cubeColor);
} else {
DependencyManager::get<GeometryCache>()->renderSolidCube(1.0f, cubeColor);
}
glPopMatrix();
} else {
glLineWidth(_lineWidth);
if (getIsDashedLine()) {
glm::vec3 halfDimensions = dimensions / 2.0f;
glm::vec3 bottomLeftNear(-halfDimensions.x, -halfDimensions.y, -halfDimensions.z);
glm::vec3 bottomRightNear(halfDimensions.x, -halfDimensions.y, -halfDimensions.z);
glm::vec3 topLeftNear(-halfDimensions.x, halfDimensions.y, -halfDimensions.z);
glm::vec3 topRightNear(halfDimensions.x, halfDimensions.y, -halfDimensions.z);
glm::vec3 bottomLeftFar(-halfDimensions.x, -halfDimensions.y, halfDimensions.z);
glm::vec3 bottomRightFar(halfDimensions.x, -halfDimensions.y, halfDimensions.z);
glm::vec3 topLeftFar(-halfDimensions.x, halfDimensions.y, halfDimensions.z);
glm::vec3 topRightFar(halfDimensions.x, halfDimensions.y, halfDimensions.z);
auto geometryCache = DependencyManager::get<GeometryCache>();
geometryCache->renderDashedLine(bottomLeftNear, bottomRightNear, cubeColor);
geometryCache->renderDashedLine(bottomRightNear, bottomRightFar, cubeColor);
geometryCache->renderDashedLine(bottomRightFar, bottomLeftFar, cubeColor);
geometryCache->renderDashedLine(bottomLeftFar, bottomLeftNear, cubeColor);
geometryCache->renderDashedLine(topLeftNear, topRightNear, cubeColor);
geometryCache->renderDashedLine(topRightNear, topRightFar, cubeColor);
geometryCache->renderDashedLine(topRightFar, topLeftFar, cubeColor);
geometryCache->renderDashedLine(topLeftFar, topLeftNear, cubeColor);
geometryCache->renderDashedLine(bottomLeftNear, topLeftNear, cubeColor);
geometryCache->renderDashedLine(bottomRightNear, topRightNear, cubeColor);
geometryCache->renderDashedLine(bottomLeftFar, topLeftFar, cubeColor);
geometryCache->renderDashedLine(bottomRightFar, topRightFar, cubeColor);
} else {
glScalef(dimensions.x, dimensions.y, dimensions.z);
DependencyManager::get<GeometryCache>()->renderWireCube(1.0f, cubeColor);
}
}
glPopMatrix();
glPopMatrix();
if (glower) {
delete glower;
}
}
}

View file

@ -36,87 +36,128 @@ void Grid3DOverlay::render(RenderArgs* args) {
return; // do nothing if we're not visible
}
if (!_gridProgram.isLinked()) {
if (!_gridProgram.addShaderFromSourceFile(QGLShader::Vertex, PathUtils::resourcesPath() + "shaders/grid.vert")) {
qDebug() << "Failed to compile: " + _gridProgram.log();
return;
}
if (!_gridProgram.addShaderFromSourceFile(QGLShader::Fragment, PathUtils::resourcesPath() + "shaders/grid.frag")) {
qDebug() << "Failed to compile: " + _gridProgram.log();
return;
}
if (!_gridProgram.link()) {
qDebug() << "Failed to link: " + _gridProgram.log();
return;
}
}
// Render code largely taken from MetavoxelEditor::render()
glDisable(GL_LIGHTING);
glDepthMask(GL_FALSE);
glPushMatrix();
glm::quat rotation = getRotation();
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
glLineWidth(1.5f);
// center the grid around the camera position on the plane
glm::vec3 rotated = glm::inverse(rotation) * Application::getInstance()->getCamera()->getPosition();
float spacing = _minorGridWidth;
float alpha = getAlpha();
xColor color = getColor();
glm::vec3 position = getPosition();
const int MINOR_GRID_DIVISIONS = 200;
const int MAJOR_GRID_DIVISIONS = 100;
const float MAX_COLOR = 255.0f;
// center the grid around the camera position on the plane
glm::vec3 rotated = glm::inverse(_rotation) * Application::getInstance()->getCamera()->getPosition();
float spacing = _minorGridWidth;
float alpha = getAlpha();
xColor color = getColor();
glm::vec4 gridColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
_gridProgram.bind();
auto batch = args->_batch;
// Minor grid
glPushMatrix();
{
glTranslatef(_minorGridWidth * (floorf(rotated.x / spacing) - MINOR_GRID_DIVISIONS / 2),
spacing * (floorf(rotated.y / spacing) - MINOR_GRID_DIVISIONS / 2), position.z);
if (batch) {
Transform transform;
transform.setRotation(_rotation);
float scale = MINOR_GRID_DIVISIONS * spacing;
glScalef(scale, scale, scale);
DependencyManager::get<GeometryCache>()->renderGrid(MINOR_GRID_DIVISIONS, MINOR_GRID_DIVISIONS, gridColor);
// Minor grid
{
batch->_glLineWidth(1.0f);
auto position = glm::vec3(_minorGridWidth * (floorf(rotated.x / spacing) - MINOR_GRID_DIVISIONS / 2),
spacing * (floorf(rotated.y / spacing) - MINOR_GRID_DIVISIONS / 2),
_position.z);
float scale = MINOR_GRID_DIVISIONS * spacing;
transform.setTranslation(position);
transform.setScale(scale);
batch->setModelTransform(transform);
DependencyManager::get<GeometryCache>()->renderGrid(*batch, MINOR_GRID_DIVISIONS, MINOR_GRID_DIVISIONS, gridColor);
}
// Major grid
{
batch->_glLineWidth(4.0f);
spacing *= _majorGridEvery;
auto position = glm::vec3(spacing * (floorf(rotated.x / spacing) - MAJOR_GRID_DIVISIONS / 2),
spacing * (floorf(rotated.y / spacing) - MAJOR_GRID_DIVISIONS / 2),
_position.z);
float scale = MAJOR_GRID_DIVISIONS * spacing;
transform.setTranslation(position);
transform.setScale(scale);
batch->setModelTransform(transform);
DependencyManager::get<GeometryCache>()->renderGrid(*batch, MAJOR_GRID_DIVISIONS, MAJOR_GRID_DIVISIONS, gridColor);
}
} else {
if (!_gridProgram.isLinked()) {
if (!_gridProgram.addShaderFromSourceFile(QGLShader::Vertex, PathUtils::resourcesPath() + "shaders/grid.vert")) {
qDebug() << "Failed to compile: " + _gridProgram.log();
return;
}
if (!_gridProgram.addShaderFromSourceFile(QGLShader::Fragment, PathUtils::resourcesPath() + "shaders/grid.frag")) {
qDebug() << "Failed to compile: " + _gridProgram.log();
return;
}
if (!_gridProgram.link()) {
qDebug() << "Failed to link: " + _gridProgram.log();
return;
}
}
// Render code largely taken from MetavoxelEditor::render()
glDisable(GL_LIGHTING);
glDepthMask(GL_FALSE);
glPushMatrix();
glm::quat rotation = getRotation();
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
glLineWidth(1.5f);
glm::vec3 position = getPosition();
_gridProgram.bind();
// Minor grid
glPushMatrix();
{
glTranslatef(_minorGridWidth * (floorf(rotated.x / spacing) - MINOR_GRID_DIVISIONS / 2),
spacing * (floorf(rotated.y / spacing) - MINOR_GRID_DIVISIONS / 2), position.z);
float scale = MINOR_GRID_DIVISIONS * spacing;
glScalef(scale, scale, scale);
DependencyManager::get<GeometryCache>()->renderGrid(MINOR_GRID_DIVISIONS, MINOR_GRID_DIVISIONS, gridColor);
}
glPopMatrix();
// Major grid
glPushMatrix();
{
glLineWidth(4.0f);
spacing *= _majorGridEvery;
glTranslatef(spacing * (floorf(rotated.x / spacing) - MAJOR_GRID_DIVISIONS / 2),
spacing * (floorf(rotated.y / spacing) - MAJOR_GRID_DIVISIONS / 2), position.z);
float scale = MAJOR_GRID_DIVISIONS * spacing;
glScalef(scale, scale, scale);
DependencyManager::get<GeometryCache>()->renderGrid(MAJOR_GRID_DIVISIONS, MAJOR_GRID_DIVISIONS, gridColor);
}
glPopMatrix();
_gridProgram.release();
glPopMatrix();
glEnable(GL_LIGHTING);
glDepthMask(GL_TRUE);
}
glPopMatrix();
// Major grid
glPushMatrix();
{
glLineWidth(4.0f);
spacing *= _majorGridEvery;
glTranslatef(spacing * (floorf(rotated.x / spacing) - MAJOR_GRID_DIVISIONS / 2),
spacing * (floorf(rotated.y / spacing) - MAJOR_GRID_DIVISIONS / 2), position.z);
float scale = MAJOR_GRID_DIVISIONS * spacing;
glScalef(scale, scale, scale);
DependencyManager::get<GeometryCache>()->renderGrid(MAJOR_GRID_DIVISIONS, MAJOR_GRID_DIVISIONS, gridColor);
}
glPopMatrix();
_gridProgram.release();
glPopMatrix();
glEnable(GL_LIGHTING);
glDepthMask(GL_TRUE);
}
void Grid3DOverlay::setProperties(const QScriptValue& properties) {

View file

@ -37,41 +37,57 @@ void Line3DOverlay::render(RenderArgs* args) {
return; // do nothing if we're not visible
}
float glowLevel = getGlowLevel();
Glower* glower = NULL;
if (glowLevel > 0.0f) {
glower = new Glower(glowLevel);
}
glPushMatrix();
glDisable(GL_LIGHTING);
glLineWidth(_lineWidth);
float alpha = getAlpha();
xColor color = getColor();
const float MAX_COLOR = 255.0f;
glm::vec4 colorv4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
glm::vec3 position = getPosition();
glm::quat rotation = getRotation();
auto batch = args->_batch;
glTranslatef(position.x, position.y, position.z);
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
if (batch) {
Transform transform;
transform.setTranslation(_position);
transform.setRotation(_rotation);
batch->setModelTransform(transform);
if (getIsDashedLine()) {
// TODO: add support for color to renderDashedLine()
DependencyManager::get<GeometryCache>()->renderDashedLine(_position, _end, colorv4, _geometryCacheID);
if (getIsDashedLine()) {
// TODO: add support for color to renderDashedLine()
DependencyManager::get<GeometryCache>()->renderDashedLine(*batch, _position, _end, colorv4, _geometryCacheID);
} else {
DependencyManager::get<GeometryCache>()->renderLine(*batch, _start, _end, colorv4, _geometryCacheID);
}
} else {
DependencyManager::get<GeometryCache>()->renderLine(_start, _end, colorv4, _geometryCacheID);
}
glEnable(GL_LIGHTING);
float glowLevel = getGlowLevel();
Glower* glower = NULL;
if (glowLevel > 0.0f) {
glower = new Glower(glowLevel);
}
glPopMatrix();
glPushMatrix();
if (glower) {
delete glower;
glDisable(GL_LIGHTING);
glLineWidth(_lineWidth);
glm::vec3 position = getPosition();
glm::quat rotation = getRotation();
glTranslatef(position.x, position.y, position.z);
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
if (getIsDashedLine()) {
// TODO: add support for color to renderDashedLine()
DependencyManager::get<GeometryCache>()->renderDashedLine(_position, _end, colorv4, _geometryCacheID);
} else {
DependencyManager::get<GeometryCache>()->renderLine(_start, _end, colorv4, _geometryCacheID);
}
glEnable(GL_LIGHTING);
glPopMatrix();
if (glower) {
delete glower;
}
}
}

View file

@ -66,8 +66,8 @@ namespace render {
}
template <> void payloadRender(const Overlay::Pointer& overlay, RenderArgs* args) {
if (args) {
glPushMatrix();
if (overlay->getAnchor() == Overlay::MY_AVATAR) {
glPushMatrix();
MyAvatar* avatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
glm::quat myAvatarRotation = avatar->getOrientation();
glm::vec3 myAvatarPosition = avatar->getPosition();
@ -78,9 +78,11 @@ namespace render {
glTranslatef(myAvatarPosition.x, myAvatarPosition.y, myAvatarPosition.z);
glRotatef(angle, axis.x, axis.y, axis.z);
glScalef(myAvatarScale, myAvatarScale, myAvatarScale);
overlay->render(args);
glPopMatrix();
} else {
overlay->render(args);
}
overlay->render(args);
glPopMatrix();
}
}
}

View file

@ -41,74 +41,116 @@ void Rectangle3DOverlay::render(RenderArgs* args) {
const float MAX_COLOR = 255.0f;
glm::vec4 rectangleColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
glDisable(GL_LIGHTING);
glm::vec3 position = getPosition();
glm::vec3 center = getCenter();
glm::vec2 dimensions = getDimensions();
glm::vec2 halfDimensions = dimensions * 0.5f;
glm::quat rotation = getRotation();
float glowLevel = getGlowLevel();
Glower* glower = NULL;
if (glowLevel > 0.0f) {
glower = new Glower(glowLevel);
}
auto batch = args->_batch;
glPushMatrix();
glTranslatef(position.x, position.y, position.z);
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
glPushMatrix();
glm::vec3 positionToCenter = center - position;
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
//glScalef(dimensions.x, dimensions.y, 1.0f);
if (batch) {
Transform transform;
transform.setTranslation(position);
transform.setRotation(rotation);
glLineWidth(_lineWidth);
batch->setModelTransform(transform);
if (getIsSolid()) {
glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, 0.0f);
glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, 0.0f);
DependencyManager::get<GeometryCache>()->renderQuad(*batch, topLeft, bottomRight, rectangleColor);
} else {
auto geometryCache = DependencyManager::get<GeometryCache>();
if (getIsDashedLine()) {
glm::vec3 point1(-halfDimensions.x, -halfDimensions.y, 0.0f);
glm::vec3 point2(halfDimensions.x, -halfDimensions.y, 0.0f);
glm::vec3 point3(halfDimensions.x, halfDimensions.y, 0.0f);
glm::vec3 point4(-halfDimensions.x, halfDimensions.y, 0.0f);
// for our overlay, is solid means we draw a solid "filled" rectangle otherwise we just draw a border line...
if (getIsSolid()) {
glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, 0.0f);
glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, 0.0f);
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, rectangleColor);
geometryCache->renderDashedLine(*batch, point1, point2, rectangleColor);
geometryCache->renderDashedLine(*batch, point2, point3, rectangleColor);
geometryCache->renderDashedLine(*batch, point3, point4, rectangleColor);
geometryCache->renderDashedLine(*batch, point4, point1, rectangleColor);
} else {
if (getIsDashedLine()) {
if (halfDimensions != _previousHalfDimensions) {
QVector<glm::vec3> border;
border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f);
border << glm::vec3(halfDimensions.x, -halfDimensions.y, 0.0f);
border << glm::vec3(halfDimensions.x, halfDimensions.y, 0.0f);
border << glm::vec3(-halfDimensions.x, halfDimensions.y, 0.0f);
border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f);
geometryCache->updateVertices(_geometryCacheID, border, rectangleColor);
glm::vec3 point1(-halfDimensions.x, -halfDimensions.y, 0.0f);
glm::vec3 point2(halfDimensions.x, -halfDimensions.y, 0.0f);
glm::vec3 point3(halfDimensions.x, halfDimensions.y, 0.0f);
glm::vec3 point4(-halfDimensions.x, halfDimensions.y, 0.0f);
geometryCache->renderDashedLine(point1, point2, rectangleColor);
geometryCache->renderDashedLine(point2, point3, rectangleColor);
geometryCache->renderDashedLine(point3, point4, rectangleColor);
geometryCache->renderDashedLine(point4, point1, rectangleColor);
} else {
if (halfDimensions != _previousHalfDimensions) {
QVector<glm::vec3> border;
border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f);
border << glm::vec3(halfDimensions.x, -halfDimensions.y, 0.0f);
border << glm::vec3(halfDimensions.x, halfDimensions.y, 0.0f);
border << glm::vec3(-halfDimensions.x, halfDimensions.y, 0.0f);
border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f);
geometryCache->updateVertices(_geometryCacheID, border, rectangleColor);
_previousHalfDimensions = halfDimensions;
}
geometryCache->renderVertices(gpu::LINE_STRIP, _geometryCacheID);
_previousHalfDimensions = halfDimensions;
}
geometryCache->renderVertices(*batch, gpu::LINE_STRIP, _geometryCacheID);
}
}
} else {
glDisable(GL_LIGHTING);
float glowLevel = getGlowLevel();
Glower* glower = NULL;
if (glowLevel > 0.0f) {
glower = new Glower(glowLevel);
}
glPushMatrix();
glTranslatef(position.x, position.y, position.z);
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
glPushMatrix();
glm::vec3 positionToCenter = center - position;
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
//glScalef(dimensions.x, dimensions.y, 1.0f);
glLineWidth(_lineWidth);
auto geometryCache = DependencyManager::get<GeometryCache>();
// for our overlay, is solid means we draw a solid "filled" rectangle otherwise we just draw a border line...
if (getIsSolid()) {
glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, 0.0f);
glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, 0.0f);
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, rectangleColor);
} else {
if (getIsDashedLine()) {
glm::vec3 point1(-halfDimensions.x, -halfDimensions.y, 0.0f);
glm::vec3 point2(halfDimensions.x, -halfDimensions.y, 0.0f);
glm::vec3 point3(halfDimensions.x, halfDimensions.y, 0.0f);
glm::vec3 point4(-halfDimensions.x, halfDimensions.y, 0.0f);
geometryCache->renderDashedLine(point1, point2, rectangleColor);
geometryCache->renderDashedLine(point2, point3, rectangleColor);
geometryCache->renderDashedLine(point3, point4, rectangleColor);
geometryCache->renderDashedLine(point4, point1, rectangleColor);
} else {
if (halfDimensions != _previousHalfDimensions) {
QVector<glm::vec3> border;
border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f);
border << glm::vec3(halfDimensions.x, -halfDimensions.y, 0.0f);
border << glm::vec3(halfDimensions.x, halfDimensions.y, 0.0f);
border << glm::vec3(-halfDimensions.x, halfDimensions.y, 0.0f);
border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f);
geometryCache->updateVertices(_geometryCacheID, border, rectangleColor);
_previousHalfDimensions = halfDimensions;
}
geometryCache->renderVertices(gpu::LINE_STRIP, _geometryCacheID);
}
}
glPopMatrix();
glPopMatrix();
glPopMatrix();
if (glower) {
delete glower;
if (glower) {
delete glower;
}
}
}

View file

@ -39,33 +39,45 @@ void Sphere3DOverlay::render(RenderArgs* args) {
const float MAX_COLOR = 255.0f;
glm::vec4 sphereColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
glDisable(GL_LIGHTING);
glm::vec3 position = getPosition();
glm::vec3 center = getCenter();
glm::vec3 dimensions = getDimensions();
glm::quat rotation = getRotation();
auto batch = args->_batch;
float glowLevel = getGlowLevel();
Glower* glower = NULL;
if (glowLevel > 0.0f) {
glower = new Glower(glowLevel);
}
if (batch) {
Transform transform;
transform.setTranslation(_position);
transform.setRotation(_rotation);
transform.setScale(_dimensions);
batch->setModelTransform(transform);
DependencyManager::get<GeometryCache>()->renderSphere(*batch, 1.0f, SLICES, SLICES, sphereColor, _isSolid);
} else {
glDisable(GL_LIGHTING);
glm::vec3 position = getPosition();
glm::vec3 center = getCenter();
glm::vec3 dimensions = getDimensions();
glm::quat rotation = getRotation();
float glowLevel = getGlowLevel();
Glower* glower = NULL;
if (glowLevel > 0.0f) {
glower = new Glower(glowLevel);
}
glPushMatrix();
glTranslatef(position.x, position.y, position.z);
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
glPushMatrix();
glm::vec3 positionToCenter = center - position;
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
glScalef(dimensions.x, dimensions.y, dimensions.z);
DependencyManager::get<GeometryCache>()->renderSphere(1.0f, SLICES, SLICES, sphereColor, _isSolid);
glTranslatef(position.x, position.y, position.z);
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
glPushMatrix();
glm::vec3 positionToCenter = center - position;
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
glScalef(dimensions.x, dimensions.y, dimensions.z);
DependencyManager::get<GeometryCache>()->renderSphere(1.0f, SLICES, SLICES, sphereColor, _isSolid);
glPopMatrix();
glPopMatrix();
glPopMatrix();
if (glower) {
delete glower;
if (glower) {
delete glower;
}
}
}

View file

@ -150,6 +150,8 @@ public:
void _glUseProgram(GLuint program);
void _glUniform1f(GLint location, GLfloat v0);
void _glUniform2f(GLint location, GLfloat v0, GLfloat v1);
void _glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
void _glUniform3fv(GLint location, GLsizei count, const GLfloat* value);
void _glUniform4fv(GLint location, GLsizei count, const GLfloat* value);
void _glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
@ -210,6 +212,8 @@ public:
COMMAND_glUseProgram,
COMMAND_glUniform1f,
COMMAND_glUniform2f,
COMMAND_glUniform3f,
COMMAND_glUniform3fv,
COMMAND_glUniform4fv,
COMMAND_glUniformMatrix4fv,

View file

@ -61,6 +61,8 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
(&::gpu::GLBackend::do_glUseProgram),
(&::gpu::GLBackend::do_glUniform1f),
(&::gpu::GLBackend::do_glUniform2f),
(&::gpu::GLBackend::do_glUniform3f),
(&::gpu::GLBackend::do_glUniform3fv),
(&::gpu::GLBackend::do_glUniform4fv),
(&::gpu::GLBackend::do_glUniformMatrix4fv),
@ -462,6 +464,7 @@ void Batch::_glUniform2f(GLint location, GLfloat v0, GLfloat v1) {
DO_IT_NOW(_glUniform2f, 1);
}
void GLBackend::do_glUniform2f(Batch& batch, uint32 paramOffset) {
if (_pipeline._program == 0) {
// We should call updatePipeline() to bind the program but we are not doing that
@ -475,6 +478,56 @@ void GLBackend::do_glUniform2f(Batch& batch, uint32 paramOffset) {
(void) CHECK_GL_ERROR();
}
void Batch::_glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {
ADD_COMMAND_GL(glUniform3f);
_params.push_back(v2);
_params.push_back(v1);
_params.push_back(v0);
_params.push_back(location);
DO_IT_NOW(_glUniform3f, 1);
}
void GLBackend::do_glUniform3f(Batch& batch, uint32 paramOffset) {
if (_pipeline._program == 0) {
// We should call updatePipeline() to bind the program but we are not doing that
// because these uniform setters are deprecated and we don;t want to create side effect
return;
}
glUniform3f(
batch._params[paramOffset + 3]._int,
batch._params[paramOffset + 2]._float,
batch._params[paramOffset + 1]._float,
batch._params[paramOffset + 0]._float);
(void) CHECK_GL_ERROR();
}
void Batch::_glUniform3fv(GLint location, GLsizei count, const GLfloat* value) {
ADD_COMMAND_GL(glUniform3fv);
const int VEC3_SIZE = 3 * sizeof(float);
_params.push_back(cacheData(count * VEC3_SIZE, value));
_params.push_back(count);
_params.push_back(location);
DO_IT_NOW(_glUniform3fv, 3);
}
void GLBackend::do_glUniform3fv(Batch& batch, uint32 paramOffset) {
if (_pipeline._program == 0) {
// We should call updatePipeline() to bind the program but we are not doing that
// because these uniform setters are deprecated and we don;t want to create side effect
return;
}
glUniform3fv(
batch._params[paramOffset + 2]._int,
batch._params[paramOffset + 1]._uint,
(const GLfloat*)batch.editData(batch._params[paramOffset + 0]._uint));
(void) CHECK_GL_ERROR();
}
void Batch::_glUniform4fv(GLint location, GLsizei count, const GLfloat* value) {
ADD_COMMAND_GL(glUniform4fv);

View file

@ -379,6 +379,8 @@ protected:
void do_glUseProgram(Batch& batch, uint32 paramOffset);
void do_glUniform1f(Batch& batch, uint32 paramOffset);
void do_glUniform2f(Batch& batch, uint32 paramOffset);
void do_glUniform3f(Batch& batch, uint32 paramOffset);
void do_glUniform3fv(Batch& batch, uint32 paramOffset);
void do_glUniform4fv(Batch& batch, uint32 paramOffset);
void do_glUniformMatrix4fv(Batch& batch, uint32 paramOffset);

View file

@ -61,7 +61,11 @@ void makeBindings(GLBackend::GLShader* shader) {
if (loc >= 0) {
glBindAttribLocation(glprogram, gpu::Stream::TEXCOORD, "texcoord");
}
loc = glGetAttribLocation(glprogram, "attribTexcoord");
if (loc >= 0) {
glBindAttribLocation(glprogram, gpu::Stream::TEXCOORD, "attribTexcoord");
}
loc = glGetAttribLocation(glprogram, "tangent");
if (loc >= 0) {
glBindAttribLocation(glprogram, gpu::Stream::TANGENT, "tangent");

View file

@ -14,9 +14,6 @@
#include <math.h>
#include <qcompilerdetection.h>
#include "SkyFromAtmosphere_vert.h"
#include "SkyFromAtmosphere_frag.h"
using namespace model;
@ -207,17 +204,6 @@ SunSkyStage::SunSkyStage() :
// Begining of march
setYearTime(60.0f);
auto skyFromAtmosphereVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(SkyFromAtmosphere_vert)));
auto skyFromAtmosphereFragment = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(SkyFromAtmosphere_frag)));
auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyFromAtmosphereVertex, skyFromAtmosphereFragment));
auto skyState = gpu::StatePointer(new gpu::State());
// skyState->setStencilEnable(false);
// skyState->setBlendEnable(false);
_skyPipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState));
_skybox.reset(new Skybox());
_skybox->setColor(Color(1.0f, 0.0f, 0.0f));
@ -306,12 +292,6 @@ void SunSkyStage::updateGraphicsObject() const {
case NUM_BACKGROUND_MODES:
Q_UNREACHABLE();
};
static int firstTime = 0;
if (firstTime == 0) {
firstTime++;
gpu::Shader::makeProgram(*(_skyPipeline->getProgram()));
}
}
void SunSkyStage::setBackgroundMode(BackgroundMode mode) {

View file

@ -229,8 +229,6 @@ protected:
AtmospherePointer _atmosphere;
mutable SkyboxPointer _skybox;
gpu::PipelinePointer _skyPipeline;
float _dayTime = 12.0f;
int _yearTime = 0;
mutable EarthSunModel _earthSunModel;

View file

@ -72,6 +72,8 @@ public slots:
void goBack();
void goForward();
void goToUser(const QString& username);
void storeCurrentAddress();
void copyAddress();
@ -100,7 +102,6 @@ private slots:
void handleAPIResponse(QNetworkReply& requestReply);
void handleAPIError(QNetworkReply& errorReply);
void goToUser(const QString& username);
void goToAddressFromObject(const QVariantMap& addressMap, const QNetworkReply& reply);
private:
void setHost(const QString& host, LookupTrigger trigger);

View file

@ -9,25 +9,25 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "InterfaceConfig.h"
#include <QByteArray>
#include <QMutexLocker>
#include <QtDebug>
#include "GeometryCache.h"
#include <GeometryUtil.h>
#include <NumericalConstants.h>
#include <OctreePacketData.h>
#include <PacketHeaders.h>
#include <PathUtils.h>
#include <ProgramObject.h>
#include <SharedUtil.h>
#include "Application.h"
#include "Camera.h"
#include "world.h"
#include "InterfaceLogging.h"
#include "Environment.h"
#include "SkyFromSpace_vert.h"
#include "SkyFromSpace_frag.h"
#include "SkyFromAtmosphere_vert.h"
#include "SkyFromAtmosphere_frag.h"
uint qHash(const HifiSockAddr& sockAddr) {
if (sockAddr.getAddress().isNull()) {
return 0; // shouldn't happen, but if it does, zero is a perfectly valid hash
@ -42,20 +42,15 @@ Environment::Environment()
}
Environment::~Environment() {
if (_initialized) {
delete _skyFromAtmosphereProgram;
delete _skyFromSpaceProgram;
}
}
void Environment::init() {
if (_initialized) {
qCDebug(interfaceapp, "[ERROR] Environment is already initialized.");
return;
}
_skyFromAtmosphereProgram = createSkyProgram("Atmosphere", _skyFromAtmosphereUniformLocations);
_skyFromSpaceProgram = createSkyProgram("Space", _skyFromSpaceUniformLocations);
setupAtmosphereProgram(SkyFromSpace_vert, SkyFromSpace_frag, _skyFromSpaceProgram, _skyFromSpaceUniformLocations);
setupAtmosphereProgram(SkyFromAtmosphere_vert, SkyFromAtmosphere_frag, _skyFromAtmosphereProgram, _skyFromAtmosphereUniformLocations);
// start off with a default-constructed environment data
_data[HifiSockAddr()][0];
@ -63,22 +58,60 @@ void Environment::init() {
_initialized = true;
}
void Environment::setupAtmosphereProgram(const char* vertSource, const char* fragSource, gpu::PipelinePointer& pipeline, int* locations) {
auto VS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(vertSource)));
auto PS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(fragSource)));
gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(VS, PS));
gpu::Shader::BindingSet slotBindings;
gpu::Shader::makeProgram(*program, slotBindings);
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
state->setCullMode(gpu::State::CULL_NONE);
state->setDepthTest(false);
state->setBlendFunction(true,
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state));
locations[CAMERA_POS_LOCATION] = program->getUniforms().findLocation("v3CameraPos");
locations[LIGHT_POS_LOCATION] = program->getUniforms().findLocation("v3LightPos");
locations[INV_WAVELENGTH_LOCATION] = program->getUniforms().findLocation("v3InvWavelength");
locations[CAMERA_HEIGHT2_LOCATION] = program->getUniforms().findLocation("fCameraHeight2");
locations[OUTER_RADIUS_LOCATION] = program->getUniforms().findLocation("fOuterRadius");
locations[OUTER_RADIUS2_LOCATION] = program->getUniforms().findLocation("fOuterRadius2");
locations[INNER_RADIUS_LOCATION] = program->getUniforms().findLocation("fInnerRadius");
locations[KR_ESUN_LOCATION] = program->getUniforms().findLocation("fKrESun");
locations[KM_ESUN_LOCATION] = program->getUniforms().findLocation("fKmESun");
locations[KR_4PI_LOCATION] = program->getUniforms().findLocation("fKr4PI");
locations[KM_4PI_LOCATION] = program->getUniforms().findLocation("fKm4PI");
locations[SCALE_LOCATION] = program->getUniforms().findLocation("fScale");
locations[SCALE_DEPTH_LOCATION] = program->getUniforms().findLocation("fScaleDepth");
locations[SCALE_OVER_SCALE_DEPTH_LOCATION] = program->getUniforms().findLocation("fScaleOverScaleDepth");
locations[G_LOCATION] = program->getUniforms().findLocation("g");
locations[G2_LOCATION] = program->getUniforms().findLocation("g2");
}
void Environment::resetToDefault() {
_data.clear();
_data[HifiSockAddr()][0];
}
void Environment::renderAtmospheres(ViewFrustum& camera) {
void Environment::renderAtmospheres(gpu::Batch& batch, ViewFrustum& camera) {
// get the lock for the duration of the call
QMutexLocker locker(&_mutex);
if (_environmentIsOverridden) {
renderAtmosphere(camera, _overrideData);
renderAtmosphere(batch, camera, _overrideData);
} else {
foreach (const ServerData& serverData, _data) {
// TODO: do something about EnvironmentData
foreach (const EnvironmentData& environmentData, serverData) {
renderAtmosphere(camera, environmentData);
renderAtmosphere(batch, camera, environmentData);
}
}
}
@ -201,87 +234,51 @@ int Environment::parseData(const HifiSockAddr& senderAddress, const QByteArray&
return bytesRead;
}
ProgramObject* Environment::createSkyProgram(const char* from, int* locations) {
ProgramObject* program = new ProgramObject();
QByteArray prefix = QString(PathUtils::resourcesPath() + "/shaders/SkyFrom" + from).toUtf8();
program->addShaderFromSourceFile(QGLShader::Vertex, prefix + ".vert");
program->addShaderFromSourceFile(QGLShader::Fragment, prefix + ".frag");
program->link();
locations[CAMERA_POS_LOCATION] = program->uniformLocation("v3CameraPos");
locations[LIGHT_POS_LOCATION] = program->uniformLocation("v3LightPos");
locations[INV_WAVELENGTH_LOCATION] = program->uniformLocation("v3InvWavelength");
locations[CAMERA_HEIGHT2_LOCATION] = program->uniformLocation("fCameraHeight2");
locations[OUTER_RADIUS_LOCATION] = program->uniformLocation("fOuterRadius");
locations[OUTER_RADIUS2_LOCATION] = program->uniformLocation("fOuterRadius2");
locations[INNER_RADIUS_LOCATION] = program->uniformLocation("fInnerRadius");
locations[KR_ESUN_LOCATION] = program->uniformLocation("fKrESun");
locations[KM_ESUN_LOCATION] = program->uniformLocation("fKmESun");
locations[KR_4PI_LOCATION] = program->uniformLocation("fKr4PI");
locations[KM_4PI_LOCATION] = program->uniformLocation("fKm4PI");
locations[SCALE_LOCATION] = program->uniformLocation("fScale");
locations[SCALE_DEPTH_LOCATION] = program->uniformLocation("fScaleDepth");
locations[SCALE_OVER_SCALE_DEPTH_LOCATION] = program->uniformLocation("fScaleOverScaleDepth");
locations[G_LOCATION] = program->uniformLocation("g");
locations[G2_LOCATION] = program->uniformLocation("g2");
return program;
}
void Environment::renderAtmosphere(gpu::Batch& batch, ViewFrustum& camera, const EnvironmentData& data) {
void Environment::renderAtmosphere(ViewFrustum& camera, const EnvironmentData& data) {
glm::vec3 center = data.getAtmosphereCenter();
glPushMatrix();
glTranslatef(center.x, center.y, center.z);
Transform transform;
transform.setTranslation(center);
batch.setModelTransform(transform);
glm::vec3 relativeCameraPos = camera.getPosition() - center;
float height = glm::length(relativeCameraPos);
// use the appropriate shader depending on whether we're inside or outside
ProgramObject* program;
int* locations;
if (height < data.getAtmosphereOuterRadius()) {
program = _skyFromAtmosphereProgram;
batch.setPipeline(_skyFromAtmosphereProgram);
locations = _skyFromAtmosphereUniformLocations;
} else {
program = _skyFromSpaceProgram;
batch.setPipeline(_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);
batch._glUniform3f(locations[CAMERA_POS_LOCATION], relativeCameraPos.x, relativeCameraPos.y, relativeCameraPos.z);
glm::vec3 lightDirection = glm::normalize(data.getSunLocation());
program->setUniform(locations[LIGHT_POS_LOCATION], lightDirection);
program->setUniformValue(locations[INV_WAVELENGTH_LOCATION],
1 / powf(data.getScatteringWavelengths().r, 4.0f),
1 / powf(data.getScatteringWavelengths().g, 4.0f),
1 / powf(data.getScatteringWavelengths().b, 4.0f));
program->setUniformValue(locations[CAMERA_HEIGHT2_LOCATION], height * height);
program->setUniformValue(locations[OUTER_RADIUS_LOCATION], data.getAtmosphereOuterRadius());
program->setUniformValue(locations[OUTER_RADIUS2_LOCATION], data.getAtmosphereOuterRadius() * data.getAtmosphereOuterRadius());
program->setUniformValue(locations[INNER_RADIUS_LOCATION], data.getAtmosphereInnerRadius());
program->setUniformValue(locations[KR_ESUN_LOCATION], data.getRayleighScattering() * data.getSunBrightness());
program->setUniformValue(locations[KM_ESUN_LOCATION], data.getMieScattering() * data.getSunBrightness());
program->setUniformValue(locations[KR_4PI_LOCATION], data.getRayleighScattering() * 4.0f * PI);
program->setUniformValue(locations[KM_4PI_LOCATION], data.getMieScattering() * 4.0f * PI);
program->setUniformValue(locations[SCALE_LOCATION], 1.0f / (data.getAtmosphereOuterRadius() - data.getAtmosphereInnerRadius()));
program->setUniformValue(locations[SCALE_DEPTH_LOCATION], 0.25f);
program->setUniformValue(locations[SCALE_OVER_SCALE_DEPTH_LOCATION],
batch._glUniform3f(locations[LIGHT_POS_LOCATION], lightDirection.x, lightDirection.y, lightDirection.z);
batch._glUniform3f(locations[INV_WAVELENGTH_LOCATION],
1 / powf(data.getScatteringWavelengths().r, 4.0f),
1 / powf(data.getScatteringWavelengths().g, 4.0f),
1 / powf(data.getScatteringWavelengths().b, 4.0f));
batch._glUniform1f(locations[CAMERA_HEIGHT2_LOCATION], height * height);
batch._glUniform1f(locations[OUTER_RADIUS_LOCATION], data.getAtmosphereOuterRadius());
batch._glUniform1f(locations[OUTER_RADIUS2_LOCATION], data.getAtmosphereOuterRadius() * data.getAtmosphereOuterRadius());
batch._glUniform1f(locations[INNER_RADIUS_LOCATION], data.getAtmosphereInnerRadius());
batch._glUniform1f(locations[KR_ESUN_LOCATION], data.getRayleighScattering() * data.getSunBrightness());
batch._glUniform1f(locations[KM_ESUN_LOCATION], data.getMieScattering() * data.getSunBrightness());
batch._glUniform1f(locations[KR_4PI_LOCATION], data.getRayleighScattering() * 4.0f * PI);
batch._glUniform1f(locations[KM_4PI_LOCATION], data.getMieScattering() * 4.0f * PI);
batch._glUniform1f(locations[SCALE_LOCATION], 1.0f / (data.getAtmosphereOuterRadius() - data.getAtmosphereInnerRadius()));
batch._glUniform1f(locations[SCALE_DEPTH_LOCATION], 0.25f);
batch._glUniform1f(locations[SCALE_OVER_SCALE_DEPTH_LOCATION],
(1.0f / (data.getAtmosphereOuterRadius() - data.getAtmosphereInnerRadius())) / 0.25f);
program->setUniformValue(locations[G_LOCATION], -0.990f);
program->setUniformValue(locations[G2_LOCATION], -0.990f * -0.990f);
batch._glUniform1f(locations[G_LOCATION], -0.990f);
batch._glUniform1f(locations[G2_LOCATION], -0.990f * -0.990f);
glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glEnable(GL_BLEND);
DependencyManager::get<GeometryCache>()->renderSphere(1.0f, 100, 50, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); //Draw a unit sphere
glDepthMask(GL_TRUE);
program->release();
glPopMatrix();
DependencyManager::get<GeometryCache>()->renderSphere(batch,1.0f, 100, 50, glm::vec4(1.0f, 0.0f, 0.0f, 0.5f)); //Draw a unit sphere
}

View file

@ -16,8 +16,9 @@
#include <QMutex>
#include <HifiSockAddr.h>
#include <gpu/Batch.h>
#include "EnvironmentData.h"
#include <EnvironmentData.h>
class ViewFrustum;
class ProgramObject;
@ -29,7 +30,7 @@ public:
void init();
void resetToDefault();
void renderAtmospheres(ViewFrustum& camera);
void renderAtmospheres(gpu::Batch& batch, ViewFrustum& camera);
void override(const EnvironmentData& overrideData) { _overrideData = overrideData; _environmentIsOverridden = true; }
void endOverride() { _environmentIsOverridden = false; }
@ -44,14 +45,10 @@ private:
bool findCapsulePenetration(const glm::vec3& start,
const glm::vec3& end, float radius, glm::vec3& penetration); // NOTE: Deprecated
ProgramObject* createSkyProgram(const char* from, int* locations);
void renderAtmosphere(ViewFrustum& camera, const EnvironmentData& data);
void renderAtmosphere(gpu::Batch& batch, ViewFrustum& camera, const EnvironmentData& data);
bool _initialized;
ProgramObject* _skyFromAtmosphereProgram;
ProgramObject* _skyFromSpaceProgram;
enum {
CAMERA_POS_LOCATION,
LIGHT_POS_LOCATION,
@ -72,6 +69,11 @@ private:
LOCATION_COUNT
};
void setupAtmosphereProgram(const char* vertSource, const char* fragSource, gpu::PipelinePointer& pipelineProgram, int* locations);
gpu::PipelinePointer _skyFromAtmosphereProgram;
gpu::PipelinePointer _skyFromSpaceProgram;
int _skyFromAtmosphereUniformLocations[LOCATION_COUNT];
int _skyFromSpaceUniformLocations[LOCATION_COUNT];

View file

@ -15,9 +15,12 @@
#include "DeferredLightingEffect.h"
#include "ViewFrustum.h"
#include "RenderArgs.h"
#include "TextureCache.h"
#include <PerfStat.h>
#include "overlay3D_vert.h"
#include "overlay3D_frag.h"
using namespace render;
@ -50,7 +53,7 @@ RenderDeferredTask::RenderDeferredTask() : Task() {
_jobs.push_back(Job(RenderDeferred()));
_jobs.push_back(Job(ResolveDeferred()));
_jobs.push_back(Job(DrawTransparentDeferred()));
_jobs.push_back(Job(DrawPostLayered()));
_jobs.push_back(Job(DrawOverlay3D()));
_jobs.push_back(Job(ResetGLState()));
}
@ -225,10 +228,76 @@ template <> void render::jobRun(const DrawTransparentDeferred& job, const SceneC
renderItems(sceneContext, renderContext, renderedItems, renderContext->_maxDrawnTransparentItems);
// Before rendering the batch make sure we re in sync with gl state
args->_context->syncCache();
args->_context->render((*args->_batch));
args->_batch = nullptr;
// reset blend function to standard...
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
// glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
}
}
const gpu::PipelinePointer& DrawOverlay3D::getOpaquePipeline() const {
if (!_opaquePipeline) {
auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(overlay3D_vert)));
auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(overlay3D_frag)));
auto program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps));
auto state = gpu::StatePointer(new gpu::State());
state->setDepthTest(true, true, gpu::LESS_EQUAL);
_opaquePipeline.reset(gpu::Pipeline::create(program, state));
}
return _opaquePipeline;
}
template <> void render::jobRun(const DrawOverlay3D& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
PerformanceTimer perfTimer("DrawOverlay3D");
assert(renderContext->args);
assert(renderContext->args->_viewFrustum);
// render backgrounds
auto& scene = sceneContext->_scene;
auto& items = scene->getMasterBucket().at(ItemFilter::Builder::opaqueShape().withLayered());
ItemIDsBounds inItems;
inItems.reserve(items.size());
for (auto id : items) {
auto& item = scene->getItem(id);
if (item.getKey().isVisible() && (item.getLayer() == 1)) {
inItems.emplace_back(id);
}
}
RenderArgs* args = renderContext->args;
gpu::Batch batch;
args->_batch = &batch;
args->_whiteTexture = DependencyManager::get<TextureCache>()->getWhiteTexture();
glm::mat4 projMat;
Transform viewMat;
args->_viewFrustum->evalProjectionMatrix(projMat);
args->_viewFrustum->evalViewTransform(viewMat);
if (args->_renderMode == RenderArgs::MIRROR_RENDER_MODE) {
viewMat.postScale(glm::vec3(-1.0f, 1.0f, 1.0f));
}
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
batch.setPipeline(job.getOpaquePipeline());
batch.setUniformTexture(0, args->_whiteTexture);
if (!inItems.empty()) {
batch.clearFramebuffer(gpu::Framebuffer::BUFFER_DEPTH, glm::vec4(), 1.f, 0);
renderItems(sceneContext, renderContext, inItems);
}
// Before rendering the batch make sure we re in sync with gl state
args->_context->syncCache();
args->_context->render((*args->_batch));
args->_batch = nullptr;
args->_whiteTexture.reset();
}

View file

@ -14,6 +14,8 @@
#include "render/DrawTask.h"
#include "gpu/Pipeline.h"
class PrepareDeferred {
public:
};
@ -50,6 +52,15 @@ namespace render {
template <> void jobRun(const DrawTransparentDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
}
class DrawOverlay3D {
mutable gpu::PipelinePointer _opaquePipeline; //lazy evaluation hence mutable
public:
const gpu::PipelinePointer& getOpaquePipeline() const;
};
namespace render {
template <> void jobRun(const DrawOverlay3D& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
}
class RenderDeferredTask : public render::Task {
public:

View file

@ -53,12 +53,14 @@ uniform float g2;
varying vec3 position;
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)
@ -102,7 +104,8 @@ 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.rgb = frontColor.rgb + fMiePhase * secondaryFrontColor.rgb;
gl_FragColor.a = gl_FragColor.b;
gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(1.0/2.2));
vec3 finalColor = frontColor.rgb + fMiePhase * secondaryFrontColor.rgb;
gl_FragColor.a = finalColor.b;
gl_FragColor.rgb = pow(finalColor.rgb, vec3(1.0/2.2));
}

View file

@ -33,6 +33,9 @@
// Copyright (c) 2004 Sean O'Neil
//
<@include gpu/Transform.slh@>
<$declareStandardTransform()$>
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
@ -52,17 +55,14 @@ const float fSamples = 2.0;
varying vec3 position;
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)
position = gl_Vertex.xyz * fOuterRadius;
gl_Position = gl_ModelViewProjectionMatrix * vec4(position, 1.0);
// standard transform
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
vec4 v4pos = vec4(position, 1.0);
<$transformModelToClipPos(cam, obj, v4pos, gl_Position)$>
}

View file

@ -108,7 +108,8 @@ void main (void)
float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos*fCos) / pow(1.0 + g2 - 2.0*g*fCos, 1.5);
vec3 color = v3FrontColor * (v3InvWavelength * fKrESun);
vec3 secondaryColor = v3FrontColor * fKmESun;
gl_FragColor.rgb = color + fMiePhase * secondaryColor;
gl_FragColor.a = gl_FragColor.b;
gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(1.0/2.2));
vec3 finalColor = color + fMiePhase * secondaryColor;
gl_FragColor.a = finalColor.b;
gl_FragColor.rgb = pow(finalColor.rgb, vec3(1.0/2.2));
}

View file

@ -1,5 +1,6 @@
#version 120
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// For licensing information, see http://http.developer.nvidia.com/GPUGems/gpugems_app01.html:
//
@ -32,12 +33,20 @@
// Copyright (c) 2004 Sean O'Neil
//
<@include gpu/Transform.slh@>
<$declareStandardTransform()$>
uniform float fOuterRadius; // The outer (atmosphere) radius
varying vec3 position;
void main(void)
{
void main(void) {
position = gl_Vertex.xyz * fOuterRadius;
gl_Position = gl_ModelViewProjectionMatrix * vec4(position, 1.0);
// standard transform
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
vec4 v4pos = vec4(position, 1.0);
<$transformModelToClipPos(cam, obj, v4pos, gl_Position)$>
}

View file

@ -0,0 +1,29 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
// model.frag
// fragment shader
//
// Created by Sam Gateau on 6/16/15.
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
uniform sampler2D diffuseMap;
varying vec2 varTexcoord;
varying vec3 varEyeNormal;
varying vec4 varColor;
void main(void) {
vec4 diffuse = texture2D(diffuseMap, varTexcoord.st);
if (diffuse.a < 0.5) {
discard;
}
gl_FragColor = vec4(varColor * diffuse);
}

View file

@ -0,0 +1,40 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
// overlay3D.slv
//
// Created by Sam Gateau on 6/16/15.
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
<@include gpu/Transform.slh@>
<$declareStandardTransform()$>
//attribute vec2 texcoord;
varying vec2 varTexcoord;
// interpolated eye position
varying vec4 varEyePosition;
// the interpolated normal
varying vec3 varEyeNormal;
varying vec4 varColor;
void main(void) {
varTexcoord = gl_MultiTexCoord0.xy;
// pass along the color
varColor = gl_Color;
// standard transform
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
<$transformModelToEyeAndClipPos(cam, obj, gl_Vertex, varEyePosition, gl_Position)$>
<$transformModelToEyeDir(cam, obj, gl_Normal, varEyeNormal.xyz)$>
}

View file

@ -13,6 +13,8 @@
#define hifi_RenderArgs_h
#include <functional>
#include <memory>
class AABox;
class OctreeRenderer;
@ -20,6 +22,7 @@ class ViewFrustum;
namespace gpu {
class Batch;
class Context;
class Texture;
}
class RenderDetails {
@ -109,6 +112,8 @@ public:
gpu::Batch* _batch = nullptr;
ShoudRenderFunctor _shouldRender;
std::shared_ptr<gpu::Texture> _whiteTexture;
RenderDetails _details;
float _alphaThreshold = 0.5f;