Support glow effect in 3D line overlays

This commit is contained in:
Brad Davis 2016-07-06 12:37:36 -07:00
parent 790f74da1d
commit 8ca3630cfa
7 changed files with 545 additions and 244 deletions

View file

@ -55,12 +55,14 @@ void Line3DOverlay::render(RenderArgs* args) {
batch->setModelTransform(_transform);
auto geometryCache = DependencyManager::get<GeometryCache>();
geometryCache->bindSimpleProgram(*batch, false, false, true, true);
if (getIsDashedLine()) {
// TODO: add support for color to renderDashedLine()
geometryCache->bindSimpleProgram(*batch, false, false, true, true);
geometryCache->renderDashedLine(*batch, _start, _end, colorv4, _geometryCacheID);
} else if (_glow > 0.0f) {
geometryCache->renderGlowLine(*batch, _start, _end, colorv4, _glow, _glowWidth, _geometryCacheID);
} else {
geometryCache->bindSimpleProgram(*batch, false, false, true, true);
geometryCache->renderLine(*batch, _start, _end, colorv4, _geometryCacheID);
}
}
@ -68,7 +70,7 @@ void Line3DOverlay::render(RenderArgs* args) {
const render::ShapeKey Line3DOverlay::getShapeKey() {
auto builder = render::ShapeKey::Builder().withOwnPipeline();
if (getAlpha() != 1.0f) {
if (getAlpha() != 1.0f || _glow > 0.0f) {
builder.withTranslucent();
}
return builder.build();
@ -94,6 +96,19 @@ void Line3DOverlay::setProperties(const QVariantMap& properties) {
if (end.isValid()) {
setEnd(vec3FromVariant(end));
}
auto glow = properties["glow"];
if (glow.isValid()) {
setGlow(glow.toFloat());
if (_glow > 0.0f) {
_alpha = 0.5f;
}
}
auto glowWidth = properties["glow"];
if (glowWidth.isValid()) {
setGlow(glowWidth.toFloat());
}
}
QVariant Line3DOverlay::getProperty(const QString& property) {

View file

@ -30,10 +30,14 @@ public:
// getters
const glm::vec3& getStart() const { return _start; }
const glm::vec3& getEnd() const { return _end; }
const float& getGlow() const { return _glow; }
const float& getGlowWidth() const { return _glowWidth; }
// setters
void setStart(const glm::vec3& start) { _start = start; }
void setEnd(const glm::vec3& end) { _end = end; }
void setGlow(const float& glow) { _glow = glow; }
void setGlowWidth(const float& glowWidth) { _glowWidth = glowWidth; }
void setProperties(const QVariantMap& properties) override;
QVariant getProperty(const QString& property) override;
@ -43,6 +47,8 @@ public:
protected:
glm::vec3 _start;
glm::vec3 _end;
float _glow { 0.0 };
float _glowWidth { 0.0 };
int _geometryCacheID;
};

View file

@ -15,6 +15,7 @@
#include <QNetworkReply>
#include <QThreadPool>
#include <QtCore/QFileInfo>
#include <FSTReader.h>
#include <NumericalConstants.h>
@ -33,6 +34,9 @@
#include "simple_vert.h"
#include "simple_textured_frag.h"
#include "simple_textured_unlit_frag.h"
#include "glowLine_vert.h"
#include "glowLine_geom.h"
#include "glowLine_frag.h"
#include "grid_frag.h"
@ -43,9 +47,9 @@ const int GeometryCache::UNKNOWN_ID = -1;
static const int VERTICES_PER_TRIANGLE = 3;
static const gpu::Element POSITION_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ };
static const gpu::Element NORMAL_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ };
static const gpu::Element COLOR_ELEMENT{ gpu::VEC4, gpu::NUINT8, gpu::RGBA };
static const gpu::Element POSITION_ELEMENT { gpu::VEC3, gpu::FLOAT, gpu::XYZ };
static const gpu::Element NORMAL_ELEMENT { gpu::VEC3, gpu::FLOAT, gpu::XYZ };
static const gpu::Element COLOR_ELEMENT { gpu::VEC4, gpu::NUINT8, gpu::RGBA };
static gpu::Stream::FormatPointer SOLID_STREAM_FORMAT;
static gpu::Stream::FormatPointer INSTANCED_SOLID_STREAM_FORMAT;
@ -266,7 +270,7 @@ void GeometryCache::buildShapes() {
{
Index baseVertex = (Index)(_shapeVertices->getSize() / SHAPE_VERTEX_STRIDE);
ShapeData& shapeData = _shapes[Line];
shapeData.setupVertices(_shapeVertices, VertexVector{
shapeData.setupVertices(_shapeVertices, VertexVector {
vec3(-0.5, 0, 0), vec3(-0.5f, 0, 0),
vec3(0.5f, 0, 0), vec3(0.5f, 0, 0)
});
@ -312,32 +316,31 @@ render::ShapePipelinePointer GeometryCache::_simplePipeline;
render::ShapePipelinePointer GeometryCache::_simpleWirePipeline;
GeometryCache::GeometryCache() :
_nextID(0)
{
_nextID(0) {
buildShapes();
GeometryCache::_simplePipeline =
std::make_shared<render::ShapePipeline>(getSimplePipeline(), nullptr,
[](const render::ShapePipeline&, gpu::Batch& batch) {
// Set the defaults needed for a simple program
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::ALBEDO,
DependencyManager::get<TextureCache>()->getWhiteTexture());
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::NORMAL_FITTING,
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
}
);
[](const render::ShapePipeline&, gpu::Batch& batch) {
// Set the defaults needed for a simple program
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::ALBEDO,
DependencyManager::get<TextureCache>()->getWhiteTexture());
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::NORMAL_FITTING,
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
}
);
GeometryCache::_simpleWirePipeline =
std::make_shared<render::ShapePipeline>(getSimplePipeline(false, false, true, true), nullptr,
[](const render::ShapePipeline&, gpu::Batch& batch) { }
);
[](const render::ShapePipeline&, gpu::Batch& batch) {}
);
}
GeometryCache::~GeometryCache() {
#ifdef WANT_DEBUG
qCDebug(renderutils) << "GeometryCache::~GeometryCache()... ";
qCDebug(renderutils) << " _registeredLine3DVBOs.size():" << _registeredLine3DVBOs.size();
qCDebug(renderutils) << " _line3DVBOs.size():" << _line3DVBOs.size();
qCDebug(renderutils) << " BatchItemDetails... population:" << GeometryCache::BatchItemDetails::population;
#endif //def WANT_DEBUG
#ifdef WANT_DEBUG
qCDebug(renderutils) << "GeometryCache::~GeometryCache()... ";
qCDebug(renderutils) << " _registeredLine3DVBOs.size():" << _registeredLine3DVBOs.size();
qCDebug(renderutils) << " _line3DVBOs.size():" << _line3DVBOs.size();
qCDebug(renderutils) << " BatchItemDetails... population:" << GeometryCache::BatchItemDetails::population;
#endif //def WANT_DEBUG
}
void setupBatchInstance(gpu::Batch& batch, gpu::BufferPointer colorBuffer) {
@ -384,9 +387,9 @@ void GeometryCache::renderWireSphere(gpu::Batch& batch) {
}
void GeometryCache::renderGrid(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner,
int majorRows, int majorCols, float majorEdge,
int minorRows, int minorCols, float minorEdge,
const glm::vec4& color, bool isLayered, int id) {
int majorRows, int majorCols, float majorEdge,
int minorRows, int minorCols, float minorEdge,
const glm::vec4& color, bool isLayered, int id) {
static const glm::vec2 MIN_TEX_COORD(0.0f, 0.0f);
static const glm::vec2 MAX_TEX_COORD(1.0f, 1.0f);
@ -433,9 +436,9 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec2>& points, con
if (details.isCreated) {
details.clear();
#ifdef WANT_DEBUG
qCDebug(renderutils) << "updateVertices()... RELEASING REGISTERED";
#endif // def WANT_DEBUG
#ifdef WANT_DEBUG
qCDebug(renderutils) << "updateVertices()... RELEASING REGISTERED";
#endif // def WANT_DEBUG
}
const int FLOATS_PER_VERTEX = 2 + 3; // vertices + normals
@ -466,9 +469,9 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec2>& points, con
details.vertexSize = FLOATS_PER_VERTEX;
int compactColor = ((int(color.x * 255.0f) & 0xFF)) |
((int(color.y * 255.0f) & 0xFF) << 8) |
((int(color.z * 255.0f) & 0xFF) << 16) |
((int(color.w * 255.0f) & 0xFF) << 24);
((int(color.y * 255.0f) & 0xFF) << 8) |
((int(color.z * 255.0f) & 0xFF) << 16) |
((int(color.w * 255.0f) & 0xFF) << 24);
float* vertexData = new float[details.vertices * FLOATS_PER_VERTEX];
float* vertex = vertexData;
@ -477,7 +480,7 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec2>& points, con
int* colorDataAt = colorData;
const glm::vec3 NORMAL(0.0f, 0.0f, 1.0f);
foreach (const glm::vec2& point, points) {
foreach(const glm::vec2& point, points) {
*(vertex++) = point.x;
*(vertex++) = point.y;
*(vertex++) = NORMAL.x;
@ -492,18 +495,18 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec2>& points, con
delete[] vertexData;
delete[] colorData;
#ifdef WANT_DEBUG
qCDebug(renderutils) << "new registered linestrip buffer made -- _registeredVertices.size():" << _registeredVertices.size();
#endif
#ifdef WANT_DEBUG
qCDebug(renderutils) << "new registered linestrip buffer made -- _registeredVertices.size():" << _registeredVertices.size();
#endif
}
void GeometryCache::updateVertices(int id, const QVector<glm::vec3>& points, const glm::vec4& color) {
BatchItemDetails& details = _registeredVertices[id];
if (details.isCreated) {
details.clear();
#ifdef WANT_DEBUG
qCDebug(renderutils) << "updateVertices()... RELEASING REGISTERED";
#endif // def WANT_DEBUG
#ifdef WANT_DEBUG
qCDebug(renderutils) << "updateVertices()... RELEASING REGISTERED";
#endif // def WANT_DEBUG
}
const int FLOATS_PER_VERTEX = 3 + 3; // vertices + normals
@ -534,9 +537,9 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec3>& points, con
details.vertexSize = FLOATS_PER_VERTEX;
int compactColor = ((int(color.x * 255.0f) & 0xFF)) |
((int(color.y * 255.0f) & 0xFF) << 8) |
((int(color.z * 255.0f) & 0xFF) << 16) |
((int(color.w * 255.0f) & 0xFF) << 24);
((int(color.y * 255.0f) & 0xFF) << 8) |
((int(color.z * 255.0f) & 0xFF) << 16) |
((int(color.w * 255.0f) & 0xFF) << 24);
float* vertexData = new float[details.vertices * FLOATS_PER_VERTEX];
float* vertex = vertexData;
@ -545,7 +548,7 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec3>& points, con
int* colorDataAt = colorData;
const glm::vec3 NORMAL(0.0f, 0.0f, 1.0f);
foreach (const glm::vec3& point, points) {
foreach(const glm::vec3& point, points) {
*(vertex++) = point.x;
*(vertex++) = point.y;
*(vertex++) = point.z;
@ -561,9 +564,9 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec3>& points, con
delete[] vertexData;
delete[] colorData;
#ifdef WANT_DEBUG
qCDebug(renderutils) << "new registered linestrip buffer made -- _registeredVertices.size():" << _registeredVertices.size();
#endif
#ifdef WANT_DEBUG
qCDebug(renderutils) << "new registered linestrip buffer made -- _registeredVertices.size():" << _registeredVertices.size();
#endif
}
void GeometryCache::updateVertices(int id, const QVector<glm::vec3>& points, const QVector<glm::vec2>& texCoords, const glm::vec4& color) {
@ -571,9 +574,9 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec3>& points, con
if (details.isCreated) {
details.clear();
#ifdef WANT_DEBUG
qCDebug(renderutils) << "updateVertices()... RELEASING REGISTERED";
#endif // def WANT_DEBUG
#ifdef WANT_DEBUG
qCDebug(renderutils) << "updateVertices()... RELEASING REGISTERED";
#endif // def WANT_DEBUG
}
const int FLOATS_PER_VERTEX = 3 + 3 + 2; // vertices + normals + tex coords
@ -609,9 +612,9 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec3>& points, con
details.vertexSize = FLOATS_PER_VERTEX;
int compactColor = ((int(color.x * 255.0f) & 0xFF)) |
((int(color.y * 255.0f) & 0xFF) << 8) |
((int(color.z * 255.0f) & 0xFF) << 16) |
((int(color.w * 255.0f) & 0xFF) << 24);
((int(color.y * 255.0f) & 0xFF) << 8) |
((int(color.z * 255.0f) & 0xFF) << 16) |
((int(color.w * 255.0f) & 0xFF) << 24);
float* vertexData = new float[details.vertices * FLOATS_PER_VERTEX];
float* vertex = vertexData;
@ -640,9 +643,9 @@ void GeometryCache::updateVertices(int id, const QVector<glm::vec3>& points, con
delete[] vertexData;
delete[] colorData;
#ifdef WANT_DEBUG
qCDebug(renderutils) << "new registered linestrip buffer made -- _registeredVertices.size():" << _registeredVertices.size();
#endif
#ifdef WANT_DEBUG
qCDebug(renderutils) << "new registered linestrip buffer made -- _registeredVertices.size():" << _registeredVertices.size();
#endif
}
void GeometryCache::renderVertices(gpu::Batch& batch, gpu::Primitive primitiveType, int id) {
@ -665,15 +668,15 @@ void GeometryCache::renderBevelCornersRect(gpu::Batch& batch, int x, int y, int
if (lastKey != key) {
details.clear();
_lastRegisteredBevelRects[id] = key;
#ifdef WANT_DEBUG
qCDebug(renderutils) << "renderBevelCornersRect()... RELEASING REGISTERED";
#endif // def WANT_DEBUG
#ifdef WANT_DEBUG
qCDebug(renderutils) << "renderBevelCornersRect()... RELEASING REGISTERED";
#endif // def WANT_DEBUG
}
#ifdef WANT_DEBUG
#ifdef WANT_DEBUG
else {
qCDebug(renderutils) << "renderBevelCornersRect()... REUSING PREVIOUSLY REGISTERED";
}
#endif // def WANT_DEBUG
#endif // def WANT_DEBUG
}
if (!details.isCreated) {
@ -740,11 +743,11 @@ void GeometryCache::renderBevelCornersRect(gpu::Batch& batch, int x, int y, int
vertexBuffer[vertexPoint++] = y + bevelDistance;
int compactColor = ((int(color.x * 255.0f) & 0xFF)) |
((int(color.y * 255.0f) & 0xFF) << 8) |
((int(color.z * 255.0f) & 0xFF) << 16) |
((int(color.w * 255.0f) & 0xFF) << 24);
((int(color.y * 255.0f) & 0xFF) << 8) |
((int(color.z * 255.0f) & 0xFF) << 16) |
((int(color.w * 255.0f) & 0xFF) << 24);
int colors[NUM_VERTICES] = { compactColor, compactColor, compactColor, compactColor,
compactColor, compactColor, compactColor, compactColor };
compactColor, compactColor, compactColor, compactColor };
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);
@ -767,15 +770,15 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
if (lastKey != key) {
details.clear();
_lastRegisteredQuad2D[id] = key;
#ifdef WANT_DEBUG
qCDebug(renderutils) << "renderQuad() 2D ... RELEASING REGISTERED";
#endif // def WANT_DEBUG
#ifdef WANT_DEBUG
qCDebug(renderutils) << "renderQuad() 2D ... RELEASING REGISTERED";
#endif // def WANT_DEBUG
}
#ifdef WANT_DEBUG
#ifdef WANT_DEBUG
else {
qCDebug(renderutils) << "renderQuad() 2D ... REUSING PREVIOUSLY REGISTERED";
}
#endif // def WANT_DEBUG
#endif // def WANT_DEBUG
}
const int FLOATS_PER_VERTEX = 2 + 3; // vertices + normals
@ -817,9 +820,9 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
const int NUM_COLOR_SCALARS_PER_QUAD = 4;
int compactColor = ((int(color.x * 255.0f) & 0xFF)) |
((int(color.y * 255.0f) & 0xFF) << 8) |
((int(color.z * 255.0f) & 0xFF) << 16) |
((int(color.w * 255.0f) & 0xFF) << 24);
((int(color.y * 255.0f) & 0xFF) << 8) |
((int(color.z * 255.0f) & 0xFF) << 16) |
((int(color.w * 255.0f) & 0xFF) << 24);
int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor };
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);
@ -841,13 +844,13 @@ void GeometryCache::renderUnitQuad(gpu::Batch& batch, const glm::vec4& color, in
void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner,
const glm::vec2& texCoordMinCorner, const glm::vec2& texCoordMaxCorner,
const glm::vec4& color, int id) {
const glm::vec2& texCoordMinCorner, const glm::vec2& texCoordMaxCorner,
const glm::vec4& color, int id) {
bool registered = (id != UNKNOWN_ID);
Vec4PairVec4 key(Vec4Pair(glm::vec4(minCorner.x, minCorner.y, maxCorner.x, maxCorner.y),
glm::vec4(texCoordMinCorner.x, texCoordMinCorner.y, texCoordMaxCorner.x, texCoordMaxCorner.y)),
color);
glm::vec4(texCoordMinCorner.x, texCoordMinCorner.y, texCoordMaxCorner.x, texCoordMaxCorner.y)),
color);
BatchItemDetails& details = registered ? _registeredQuad2DTextures[id] : _quad2DTextures[key];
// if this is a registered quad, and we have buffers, then check to see if the geometry changed and rebuild if needed
@ -856,15 +859,15 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
if (lastKey != key) {
details.clear();
_lastRegisteredQuad2DTexture[id] = key;
#ifdef WANT_DEBUG
qCDebug(renderutils) << "renderQuad() 2D+texture ... RELEASING REGISTERED";
#endif // def WANT_DEBUG
#ifdef WANT_DEBUG
qCDebug(renderutils) << "renderQuad() 2D+texture ... RELEASING REGISTERED";
#endif // def WANT_DEBUG
}
#ifdef WANT_DEBUG
#ifdef WANT_DEBUG
else {
qCDebug(renderutils) << "renderQuad() 2D+texture ... REUSING PREVIOUSLY REGISTERED";
}
#endif // def WANT_DEBUG
#endif // def WANT_DEBUG
}
const int FLOATS_PER_VERTEX = 2 + 3 + 2; // vertices + normals + tex coords
@ -913,9 +916,9 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
const int NUM_COLOR_SCALARS_PER_QUAD = 4;
int compactColor = ((int(color.x * 255.0f) & 0xFF)) |
((int(color.y * 255.0f) & 0xFF) << 8) |
((int(color.z * 255.0f) & 0xFF) << 16) |
((int(color.w * 255.0f) & 0xFF) << 24);
((int(color.y * 255.0f) & 0xFF) << 8) |
((int(color.z * 255.0f) & 0xFF) << 16) |
((int(color.w * 255.0f) & 0xFF) << 24);
int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor };
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);
@ -938,15 +941,15 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, co
if (lastKey != key) {
details.clear();
_lastRegisteredQuad3D[id] = key;
#ifdef WANT_DEBUG
qCDebug(renderutils) << "renderQuad() 3D ... RELEASING REGISTERED";
#endif // def WANT_DEBUG
#ifdef WANT_DEBUG
qCDebug(renderutils) << "renderQuad() 3D ... RELEASING REGISTERED";
#endif // def WANT_DEBUG
}
#ifdef WANT_DEBUG
#ifdef WANT_DEBUG
else {
qCDebug(renderutils) << "renderQuad() 3D ... REUSING PREVIOUSLY REGISTERED";
}
#endif // def WANT_DEBUG
#endif // def WANT_DEBUG
}
const int FLOATS_PER_VERTEX = 3 + 3; // vertices + normals
@ -990,9 +993,9 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, co
const int NUM_COLOR_SCALARS_PER_QUAD = 4;
int compactColor = ((int(color.x * 255.0f) & 0xFF)) |
((int(color.y * 255.0f) & 0xFF) << 8) |
((int(color.z * 255.0f) & 0xFF) << 16) |
((int(color.w * 255.0f) & 0xFF) << 24);
((int(color.y * 255.0f) & 0xFF) << 8) |
((int(color.z * 255.0f) & 0xFF) << 16) |
((int(color.w * 255.0f) & 0xFF) << 24);
int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor };
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);
@ -1005,26 +1008,26 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, co
}
void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, const glm::vec3& bottomLeft,
const glm::vec3& bottomRight, const glm::vec3& topRight,
const glm::vec2& texCoordTopLeft, const glm::vec2& texCoordBottomLeft,
const glm::vec2& texCoordBottomRight, const glm::vec2& texCoordTopRight,
const glm::vec4& color, int id) {
const glm::vec3& bottomRight, const glm::vec3& topRight,
const glm::vec2& texCoordTopLeft, const glm::vec2& texCoordBottomLeft,
const glm::vec2& texCoordBottomRight, const glm::vec2& texCoordTopRight,
const glm::vec4& color, int id) {
#ifdef WANT_DEBUG
qCDebug(renderutils) << "renderQuad() vec3 + texture VBO...";
qCDebug(renderutils) << " topLeft:" << topLeft;
qCDebug(renderutils) << " bottomLeft:" << bottomLeft;
qCDebug(renderutils) << " bottomRight:" << bottomRight;
qCDebug(renderutils) << " topRight:" << topRight;
qCDebug(renderutils) << " texCoordTopLeft:" << texCoordTopLeft;
qCDebug(renderutils) << " texCoordBottomRight:" << texCoordBottomRight;
qCDebug(renderutils) << " color:" << color;
#endif //def WANT_DEBUG
#ifdef WANT_DEBUG
qCDebug(renderutils) << "renderQuad() vec3 + texture VBO...";
qCDebug(renderutils) << " topLeft:" << topLeft;
qCDebug(renderutils) << " bottomLeft:" << bottomLeft;
qCDebug(renderutils) << " bottomRight:" << bottomRight;
qCDebug(renderutils) << " topRight:" << topRight;
qCDebug(renderutils) << " texCoordTopLeft:" << texCoordTopLeft;
qCDebug(renderutils) << " texCoordBottomRight:" << texCoordBottomRight;
qCDebug(renderutils) << " color:" << color;
#endif //def WANT_DEBUG
bool registered = (id != UNKNOWN_ID);
Vec3PairVec4Pair key(Vec3Pair(topLeft, bottomRight),
Vec4Pair(glm::vec4(texCoordTopLeft.x,texCoordTopLeft.y,texCoordBottomRight.x,texCoordBottomRight.y),
color));
Vec4Pair(glm::vec4(texCoordTopLeft.x, texCoordTopLeft.y, texCoordBottomRight.x, texCoordBottomRight.y),
color));
BatchItemDetails& details = registered ? _registeredQuad3DTextures[id] : _quad3DTextures[key];
@ -1034,15 +1037,15 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, cons
if (lastKey != key) {
details.clear();
_lastRegisteredQuad3DTexture[id] = key;
#ifdef WANT_DEBUG
qCDebug(renderutils) << "renderQuad() 3D+texture ... RELEASING REGISTERED";
#endif // def WANT_DEBUG
#ifdef WANT_DEBUG
qCDebug(renderutils) << "renderQuad() 3D+texture ... RELEASING REGISTERED";
#endif // def WANT_DEBUG
}
#ifdef WANT_DEBUG
#ifdef WANT_DEBUG
else {
qCDebug(renderutils) << "renderQuad() 3D+texture ... REUSING PREVIOUSLY REGISTERED";
}
#endif // def WANT_DEBUG
#endif // def WANT_DEBUG
}
const int FLOATS_PER_VERTEX = 3 + 3 + 2; // vertices + normals + tex coords
@ -1088,9 +1091,9 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, cons
const int NUM_COLOR_SCALARS_PER_QUAD = 4;
int compactColor = ((int(color.x * 255.0f) & 0xFF)) |
((int(color.y * 255.0f) & 0xFF) << 8) |
((int(color.z * 255.0f) & 0xFF) << 16) |
((int(color.w * 255.0f) & 0xFF) << 24);
((int(color.y * 255.0f) & 0xFF) << 8) |
((int(color.z * 255.0f) & 0xFF) << 16) |
((int(color.w * 255.0f) & 0xFF) << 24);
int colors[NUM_COLOR_SCALARS_PER_QUAD] = { compactColor, compactColor, compactColor, compactColor };
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);
@ -1103,7 +1106,7 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, cons
}
void GeometryCache::renderDashedLine(gpu::Batch& batch, const glm::vec3& start, const glm::vec3& end, const glm::vec4& color,
const float dash_length, const float gap_length, int id) {
const float dash_length, const float gap_length, int id) {
bool registered = (id != UNKNOWN_ID);
Vec3PairVec2Pair key(Vec3Pair(start, end), Vec2Pair(glm::vec2(color.x, color.y), glm::vec2(color.z, color.w)));
@ -1114,18 +1117,18 @@ void GeometryCache::renderDashedLine(gpu::Batch& batch, const glm::vec3& start,
if (_lastRegisteredDashedLines[id] != key) {
details.clear();
_lastRegisteredDashedLines[id] = key;
#ifdef WANT_DEBUG
qCDebug(renderutils) << "renderDashedLine()... RELEASING REGISTERED";
#endif // def WANT_DEBUG
#ifdef WANT_DEBUG
qCDebug(renderutils) << "renderDashedLine()... RELEASING REGISTERED";
#endif // def WANT_DEBUG
}
}
if (!details.isCreated) {
int compactColor = ((int(color.x * 255.0f) & 0xFF)) |
((int(color.y * 255.0f) & 0xFF) << 8) |
((int(color.z * 255.0f) & 0xFF) << 16) |
((int(color.w * 255.0f) & 0xFF) << 24);
((int(color.y * 255.0f) & 0xFF) << 8) |
((int(color.z * 255.0f) & 0xFF) << 16) |
((int(color.w * 255.0f) & 0xFF) << 24);
// draw each line segment with appropriate gaps
const float SEGMENT_LENGTH = dash_length + gap_length;
@ -1209,13 +1212,13 @@ void GeometryCache::renderDashedLine(gpu::Batch& batch, const glm::vec3& start,
delete[] vertexData;
delete[] colorData;
#ifdef WANT_DEBUG
#ifdef WANT_DEBUG
if (registered) {
qCDebug(renderutils) << "new registered dashed line buffer made -- _registeredVertices:" << _registeredDashedLines.size();
} else {
qCDebug(renderutils) << "new dashed lines buffer made -- _dashedLines:" << _dashedLines.size();
}
#endif
#endif
}
batch.setInputFormat(details.streamFormat);
@ -1227,41 +1230,39 @@ void GeometryCache::renderDashedLine(gpu::Batch& batch, const glm::vec3& start,
int GeometryCache::BatchItemDetails::population = 0;
GeometryCache::BatchItemDetails::BatchItemDetails() :
verticesBuffer(NULL),
colorBuffer(NULL),
streamFormat(NULL),
stream(NULL),
vertices(0),
vertexSize(0),
isCreated(false)
{
verticesBuffer(NULL),
colorBuffer(NULL),
streamFormat(NULL),
stream(NULL),
vertices(0),
vertexSize(0),
isCreated(false) {
population++;
#ifdef WANT_DEBUG
qCDebug(renderutils) << "BatchItemDetails()... population:" << population << "**********************************";
#endif
#ifdef WANT_DEBUG
qCDebug(renderutils) << "BatchItemDetails()... population:" << population << "**********************************";
#endif
}
GeometryCache::BatchItemDetails::BatchItemDetails(const GeometryCache::BatchItemDetails& other) :
verticesBuffer(other.verticesBuffer),
colorBuffer(other.colorBuffer),
streamFormat(other.streamFormat),
stream(other.stream),
vertices(other.vertices),
vertexSize(other.vertexSize),
isCreated(other.isCreated)
{
verticesBuffer(other.verticesBuffer),
colorBuffer(other.colorBuffer),
streamFormat(other.streamFormat),
stream(other.stream),
vertices(other.vertices),
vertexSize(other.vertexSize),
isCreated(other.isCreated) {
population++;
#ifdef WANT_DEBUG
qCDebug(renderutils) << "BatchItemDetails()... population:" << population << "**********************************";
#endif
#ifdef WANT_DEBUG
qCDebug(renderutils) << "BatchItemDetails()... population:" << population << "**********************************";
#endif
}
GeometryCache::BatchItemDetails::~BatchItemDetails() {
population--;
clear();
#ifdef WANT_DEBUG
qCDebug(renderutils) << "~BatchItemDetails()... population:" << population << "**********************************";
#endif
#ifdef WANT_DEBUG
qCDebug(renderutils) << "~BatchItemDetails()... population:" << population << "**********************************";
#endif
}
void GeometryCache::BatchItemDetails::clear() {
@ -1273,7 +1274,7 @@ void GeometryCache::BatchItemDetails::clear() {
}
void GeometryCache::renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2,
const glm::vec4& color1, const glm::vec4& color2, int id) {
const glm::vec4& color1, const glm::vec4& color2, int id) {
bool registered = (id != UNKNOWN_ID);
Vec3Pair key(p1, p2);
@ -1281,14 +1282,14 @@ void GeometryCache::renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm
BatchItemDetails& details = registered ? _registeredLine3DVBOs[id] : _line3DVBOs[key];
int compactColor1 = ((int(color1.x * 255.0f) & 0xFF)) |
((int(color1.y * 255.0f) & 0xFF) << 8) |
((int(color1.z * 255.0f) & 0xFF) << 16) |
((int(color1.w * 255.0f) & 0xFF) << 24);
((int(color1.y * 255.0f) & 0xFF) << 8) |
((int(color1.z * 255.0f) & 0xFF) << 16) |
((int(color1.w * 255.0f) & 0xFF) << 24);
int compactColor2 = ((int(color2.x * 255.0f) & 0xFF)) |
((int(color2.y * 255.0f) & 0xFF) << 8) |
((int(color2.z * 255.0f) & 0xFF) << 16) |
((int(color2.w * 255.0f) & 0xFF) << 24);
((int(color2.y * 255.0f) & 0xFF) << 8) |
((int(color2.z * 255.0f) & 0xFF) << 16) |
((int(color2.w * 255.0f) & 0xFF) << 24);
// if this is a registered quad, and we have buffers, then check to see if the geometry changed and rebuild if needed
@ -1297,15 +1298,15 @@ void GeometryCache::renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm
if (lastKey != key) {
details.clear();
_lastRegisteredLine3D[id] = key;
#ifdef WANT_DEBUG
qCDebug(renderutils) << "renderLine() 3D ... RELEASING REGISTERED line";
#endif // def WANT_DEBUG
#ifdef WANT_DEBUG
qCDebug(renderutils) << "renderLine() 3D ... RELEASING REGISTERED line";
#endif // def WANT_DEBUG
}
#ifdef WANT_DEBUG
#ifdef WANT_DEBUG
else {
qCDebug(renderutils) << "renderLine() 3D ... REUSING PREVIOUSLY REGISTERED line";
}
#endif // def WANT_DEBUG
#endif // def WANT_DEBUG
}
const int FLOATS_PER_VERTEX = 3 + 3; // vertices + normals
@ -1338,7 +1339,7 @@ void GeometryCache::renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm
const glm::vec3 NORMAL(1.0f, 0.0f, 0.0f);
float vertexBuffer[vertices * FLOATS_PER_VERTEX] = {
p1.x, p1.y, p1.z, NORMAL.x, NORMAL.y, NORMAL.z,
p2.x, p2.y, p2.z, NORMAL.x, NORMAL.y, NORMAL.z};
p2.x, p2.y, p2.z, NORMAL.x, NORMAL.y, NORMAL.z };
const int NUM_COLOR_SCALARS = 2;
int colors[NUM_COLOR_SCALARS] = { compactColor1, compactColor2 };
@ -1346,13 +1347,13 @@ void GeometryCache::renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);
details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
#ifdef WANT_DEBUG
if (id == UNKNOWN_ID) {
qCDebug(renderutils) << "new renderLine() 3D VBO made -- _line3DVBOs.size():" << _line3DVBOs.size();
} else {
qCDebug(renderutils) << "new registered renderLine() 3D VBO made -- _registeredLine3DVBOs.size():" << _registeredLine3DVBOs.size();
}
#endif
#ifdef WANT_DEBUG
if (id == UNKNOWN_ID) {
qCDebug(renderutils) << "new renderLine() 3D VBO made -- _line3DVBOs.size():" << _line3DVBOs.size();
} else {
qCDebug(renderutils) << "new registered renderLine() 3D VBO made -- _registeredLine3DVBOs.size():" << _registeredLine3DVBOs.size();
}
#endif
}
// this is what it takes to render a quad
@ -1362,7 +1363,7 @@ void GeometryCache::renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm
}
void GeometryCache::renderLine(gpu::Batch& batch, const glm::vec2& p1, const glm::vec2& p2,
const glm::vec4& color1, const glm::vec4& color2, int id) {
const glm::vec4& color1, const glm::vec4& color2, int id) {
bool registered = (id != UNKNOWN_ID);
Vec2Pair key(p1, p2);
@ -1370,14 +1371,14 @@ void GeometryCache::renderLine(gpu::Batch& batch, const glm::vec2& p1, const glm
BatchItemDetails& details = registered ? _registeredLine2DVBOs[id] : _line2DVBOs[key];
int compactColor1 = ((int(color1.x * 255.0f) & 0xFF)) |
((int(color1.y * 255.0f) & 0xFF) << 8) |
((int(color1.z * 255.0f) & 0xFF) << 16) |
((int(color1.w * 255.0f) & 0xFF) << 24);
((int(color1.y * 255.0f) & 0xFF) << 8) |
((int(color1.z * 255.0f) & 0xFF) << 16) |
((int(color1.w * 255.0f) & 0xFF) << 24);
int compactColor2 = ((int(color2.x * 255.0f) & 0xFF)) |
((int(color2.y * 255.0f) & 0xFF) << 8) |
((int(color2.z * 255.0f) & 0xFF) << 16) |
((int(color2.w * 255.0f) & 0xFF) << 24);
((int(color2.y * 255.0f) & 0xFF) << 8) |
((int(color2.z * 255.0f) & 0xFF) << 16) |
((int(color2.w * 255.0f) & 0xFF) << 24);
// if this is a registered quad, and we have buffers, then check to see if the geometry changed and rebuild if needed
@ -1386,15 +1387,15 @@ void GeometryCache::renderLine(gpu::Batch& batch, const glm::vec2& p1, const glm
if (lastKey != key) {
details.clear();
_lastRegisteredLine2D[id] = key;
#ifdef WANT_DEBUG
qCDebug(renderutils) << "renderLine() 2D ... RELEASING REGISTERED line";
#endif // def WANT_DEBUG
#ifdef WANT_DEBUG
qCDebug(renderutils) << "renderLine() 2D ... RELEASING REGISTERED line";
#endif // def WANT_DEBUG
}
#ifdef WANT_DEBUG
#ifdef WANT_DEBUG
else {
qCDebug(renderutils) << "renderLine() 2D ... REUSING PREVIOUSLY REGISTERED line";
}
#endif // def WANT_DEBUG
#endif // def WANT_DEBUG
}
const int FLOATS_PER_VERTEX = 2;
@ -1430,13 +1431,103 @@ void GeometryCache::renderLine(gpu::Batch& batch, const glm::vec2& p1, const glm
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);
details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
#ifdef WANT_DEBUG
if (id == UNKNOWN_ID) {
qCDebug(renderutils) << "new renderLine() 2D VBO made -- _line3DVBOs.size():" << _line2DVBOs.size();
} else {
qCDebug(renderutils) << "new registered renderLine() 2D VBO made -- _registeredLine2DVBOs.size():" << _registeredLine2DVBOs.size();
}
#endif
#ifdef WANT_DEBUG
if (id == UNKNOWN_ID) {
qCDebug(renderutils) << "new renderLine() 2D VBO made -- _line3DVBOs.size():" << _line2DVBOs.size();
} else {
qCDebug(renderutils) << "new registered renderLine() 2D VBO made -- _registeredLine2DVBOs.size():" << _registeredLine2DVBOs.size();
}
#endif
}
// this is what it takes to render a quad
batch.setInputFormat(details.streamFormat);
batch.setInputStream(0, *details.stream);
batch.draw(gpu::LINES, 2, 0);
}
void GeometryCache::renderGlowLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2,
const glm::vec4& color, float glowIntensity, float glowWidth, int id) {
if (glowIntensity <= 0) {
renderLine(batch, p1, p2, color, id);
return;
}
// Compile the shaders
static std::once_flag once;
std::call_once(once, [&] {
auto state = std::make_shared<gpu::State>();
auto VS = gpu::Shader::createVertex(std::string(glowLine_vert));
auto GS = gpu::Shader::createGeometry(std::string(glowLine_geom));
auto PS = gpu::Shader::createPixel(std::string(glowLine_frag));
auto program = gpu::Shader::createProgram(VS, GS, PS);
state->setCullMode(gpu::State::CULL_BACK);
state->setDepthTest(true, true, gpu::LESS_EQUAL);
state->setDepthBias(1.0f);
state->setDepthBiasSlopeScale(1.0f);
state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA);
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), render::ShapePipeline::Slot::MAP::NORMAL_FITTING));
gpu::Shader::makeProgram(*program, slotBindings);
_glowLinePipeline = gpu::Pipeline::create(program, state);
});
batch.setPipeline(_glowLinePipeline);
Vec3Pair key(p1, p2);
bool registered = (id != UNKNOWN_ID);
BatchItemDetails& details = registered ? _registeredLine3DVBOs[id] : _line3DVBOs[key];
int compactColor = ((int(color.x * 255.0f) & 0xFF)) |
((int(color.y * 255.0f) & 0xFF) << 8) |
((int(color.z * 255.0f) & 0xFF) << 16) |
((int(color.w * 255.0f) & 0xFF) << 24);
// if this is a registered quad, and we have buffers, then check to see if the geometry changed and rebuild if needed
if (registered && details.isCreated) {
Vec3Pair& lastKey = _lastRegisteredLine3D[id];
if (lastKey != key) {
details.clear();
_lastRegisteredLine3D[id] = key;
}
}
const int FLOATS_PER_VERTEX = 3 + 3; // vertices + normals
const int NUM_POS_COORDS = 3;
const int VERTEX_NORMAL_OFFSET = NUM_POS_COORDS * sizeof(float);
const int vertices = 2;
if (!details.isCreated) {
details.isCreated = true;
details.vertices = vertices;
details.vertexSize = FLOATS_PER_VERTEX;
auto verticesBuffer = std::make_shared<gpu::Buffer>();
auto colorBuffer = std::make_shared<gpu::Buffer>();
auto streamFormat = std::make_shared<gpu::Stream::Format>();
auto stream = std::make_shared<gpu::BufferStream>();
details.verticesBuffer = verticesBuffer;
details.colorBuffer = colorBuffer;
details.streamFormat = streamFormat;
details.stream = stream;
details.streamFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
details.streamFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), VERTEX_NORMAL_OFFSET);
details.streamFormat->setAttribute(gpu::Stream::COLOR, 1, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));
details.stream->addBuffer(details.verticesBuffer, 0, details.streamFormat->getChannels().at(0)._stride);
details.stream->addBuffer(details.colorBuffer, 0, details.streamFormat->getChannels().at(1)._stride);
const glm::vec3 NORMAL(1.0f, 0.0f, 0.0f);
float vertexBuffer[vertices * FLOATS_PER_VERTEX] = {
p1.x, p1.y, p1.z, NORMAL.x, NORMAL.y, NORMAL.z,
p2.x, p2.y, p2.z, NORMAL.x, NORMAL.y, NORMAL.z };
const int NUM_COLOR_SCALARS = 2;
int colors[NUM_COLOR_SCALARS] = { compactColor, compactColor };
details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Byte*) vertexBuffer);
details.colorBuffer->append(sizeof(colors), (gpu::Byte*) colors);
}
// this is what it takes to render a quad
@ -1532,7 +1623,7 @@ public:
SimpleProgramKey(bool textured = false, bool culled = true,
bool unlit = false, bool depthBias = false) {
bool unlit = false, bool depthBias = false) {
_flags = (textured ? IS_TEXTURED : 0) | (culled ? IS_CULLED : 0) |
(unlit ? IS_UNLIT : 0) | (depthBias ? HAS_DEPTH_BIAS : 0);
}
@ -1562,7 +1653,7 @@ void GeometryCache::bindSimpleProgram(gpu::Batch& batch, bool textured, bool cul
}
gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool culled, bool unlit, bool depthBiased) {
SimpleProgramKey config{ textured, culled, unlit, depthBiased };
SimpleProgramKey config { textured, culled, unlit, depthBiased };
// Compile the shaders
static std::once_flag once;
@ -1610,16 +1701,16 @@ gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool culled
uint32_t toCompactColor(const glm::vec4& color) {
uint32_t compactColor = ((int(color.x * 255.0f) & 0xFF)) |
((int(color.y * 255.0f) & 0xFF) << 8) |
((int(color.z * 255.0f) & 0xFF) << 16) |
((int(color.w * 255.0f) & 0xFF) << 24);
((int(color.y * 255.0f) & 0xFF) << 8) |
((int(color.z * 255.0f) & 0xFF) << 16) |
((int(color.w * 255.0f) & 0xFF) << 24);
return compactColor;
}
static const size_t INSTANCE_COLOR_BUFFER = 0;
void renderInstances(gpu::Batch& batch, const glm::vec4& color, bool isWire,
const render::ShapePipelinePointer& pipeline, GeometryCache::Shape shape) {
const render::ShapePipelinePointer& pipeline, GeometryCache::Shape shape) {
// Add pipeline to name
std::string instanceName = (isWire ? "wire_shapes_" : "solid_shapes_") + std::to_string(shape) + "_" + std::to_string(std::hash<render::ShapePipelinePointer>()(pipeline));

View file

@ -259,6 +259,9 @@ public:
void renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2,
const glm::vec4& color1, const glm::vec4& color2, int id = UNKNOWN_ID);
void renderGlowLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2,
const glm::vec4& color, float glowIntensity = 1.0f, float glowWidth = 0.05f, int id = UNKNOWN_ID);
void renderDashedLine(gpu::Batch& batch, const glm::vec3& start, const glm::vec3& end, const glm::vec4& color,
int id = UNKNOWN_ID)
{ renderDashedLine(batch, start, end, color, 0.05f, 0.025f, id); }
@ -403,6 +406,7 @@ private:
gpu::ShaderPointer _unlitShader;
static render::ShapePipelinePointer _simplePipeline;
static render::ShapePipelinePointer _simpleWirePipeline;
gpu::PipelinePointer _glowLinePipeline;
QHash<SimpleProgramKey, gpu::PipelinePointer> _simplePrograms;
};

View file

@ -0,0 +1,32 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// Created by Bradley Austin Davis on 2016/07/05
// Copyright 2013-2016 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
//
layout(location = 0) in vec4 inColor;
layout(location = 1) in vec3 inLineDistance;
out vec4 _fragColor;
void main(void) {
vec2 d = inLineDistance.xy;
d.y = abs(d.y);
d.x = abs(d.x);
if (d.x > 1.0) {
d.x = (d.x - 1.0) / 0.02;
} else {
d.x = 0.0;
}
float alpha = 1.0 - length(d);
if (alpha < 0.01) {
discard;
}
alpha = pow(alpha, 10.0);
_fragColor = vec4(inColor.rgb, alpha);
}

View file

@ -0,0 +1,127 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// Created by Bradley Austin Davis on 2016/07/05
// Copyright 2013-2016 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
//
#extension GL_EXT_geometry_shader4 : enable
layout(location = 0) in vec4 inColor[];
layout(location = 0) out vec4 outColor;
layout(location = 1) out vec3 outLineDistance;
layout(lines) in;
layout(triangle_strip, max_vertices = 24) out;
struct TransformCamera {
mat4 _view;
mat4 _viewInverse;
mat4 _projectionViewUntranslated;
mat4 _projection;
mat4 _projectionInverse;
vec4 _viewport;
};
layout(std140) uniform transformCameraBuffer {
TransformCamera _camera;
};
TransformCamera getTransformCamera() {
return _camera;
}
vec3 getEyeWorldPos() {
return _camera._viewInverse[3].xyz;
}
vec3 ndcToEyeSpace(in vec4 v) {
TransformCamera cam = getTransformCamera();
vec4 u = cam._projectionInverse * v;
return u.xyz / u.w;
}
vec2 toScreenSpace(in vec4 v)
{
TransformCamera cam = getTransformCamera();
vec4 u = cam._projection * cam._view * v;
return u.xy / u.w;
}
vec3[2] getOrthogonals(in vec3 n, float scale) {
float yDot = abs(dot(n, vec3(0, 1, 0)));
vec3 result[2];
if (yDot < 0.9) {
result[0] = normalize(cross(n, vec3(0, 1, 0)));
} else {
result[0] = normalize(cross(n, vec3(1, 0, 0)));
}
// The cross of result[0] and n is orthogonal to both, which are orthogonal to each other
result[1] = cross(result[0], n);
result[0] *= scale;
result[1] *= scale;
return result;
}
vec2 orthogonal(vec2 v) {
vec2 result = v.yx;
result.y *= -1.0;
return result;
}
void main() {
vec2 endpoints[2];
vec3 eyeSpace[2];
TransformCamera cam = getTransformCamera();
for (int i = 0; i < 2; ++i) {
eyeSpace[i] = ndcToEyeSpace(gl_PositionIn[i]);
endpoints[i] = gl_PositionIn[i].xy / gl_PositionIn[i].w;
}
vec2 lineNormal = normalize(endpoints[1] - endpoints[0]);
vec2 lineOrthogonal = orthogonal(lineNormal);
lineNormal *= 0.02;
lineOrthogonal *= 0.02;
gl_Position = gl_PositionIn[0];
gl_Position.xy -= lineNormal;
gl_Position.xy -= lineOrthogonal;
outColor = inColor[0];
outLineDistance = vec3(-1.02, -1, gl_Position.z);
EmitVertex();
gl_Position = gl_PositionIn[0];
gl_Position.xy -= lineNormal;
gl_Position.xy += lineOrthogonal;
outColor = inColor[0];
outLineDistance = vec3(-1.02, 1, gl_Position.z);
EmitVertex();
gl_Position = gl_PositionIn[1];
gl_Position.xy += lineNormal;
gl_Position.xy -= lineOrthogonal;
outColor = inColor[1];
outLineDistance = vec3(1.02, -1, gl_Position.z);
EmitVertex();
gl_Position = gl_PositionIn[1];
gl_Position.xy += lineNormal;
gl_Position.xy += lineOrthogonal;
outColor = inColor[1];
outLineDistance = vec3(1.02, 1, gl_Position.z);
EmitVertex();
EndPrimitive();
}

View file

@ -0,0 +1,26 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// Created by Bradley Austin Davis on 2016/07/05
// Copyright 2013-2016 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/Inputs.slh@>
<@include gpu/Color.slh@>
<@include gpu/Transform.slh@>
<$declareStandardTransform()$>
layout(location = 0) out vec4 _color;
void main(void) {
_color = inColor;
// standard transform
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
}