diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index cd01996622..3d106895df 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -36,22 +36,18 @@ void renderWorldBox() { GeometryCache::SharedPointer geometryCache = DependencyManager::get(); // Show edge of world - float red[] = {1, 0, 0}; - float green[] = {0, 1, 0}; - float blue[] = {0, 0, 1}; - float gray[] = {0.5, 0.5, 0.5}; + glm::vec3 red(1.0f, 0.0f, 0.0f); + glm::vec3 green(0.0f, 1.0f, 0.0f); + glm::vec3 blue(0.0f, 0.0f, 1.0f); + glm::vec3 grey(0.5f, 0.5f, 0.5f); glDisable(GL_LIGHTING); glLineWidth(1.0); - glColor3fv(red); - geometryCache->renderLine(glm::vec3(0, 0, 0), glm::vec3(TREE_SCALE, 0, 0)); - glColor3fv(green); - geometryCache->renderLine(glm::vec3(0, 0, 0), glm::vec3(0, TREE_SCALE, 0)); - glColor3fv(blue); - geometryCache->renderLine(glm::vec3(0, 0, 0), glm::vec3(0, 0, TREE_SCALE)); - glColor3fv(gray); - geometryCache->renderLine(glm::vec3(0, 0, TREE_SCALE), glm::vec3(TREE_SCALE, 0, TREE_SCALE)); - geometryCache->renderLine(glm::vec3(TREE_SCALE, 0, TREE_SCALE), glm::vec3(TREE_SCALE, 0, 0)); + geometryCache->renderLine(glm::vec3(0, 0, 0), glm::vec3(TREE_SCALE, 0, 0), red); + geometryCache->renderLine(glm::vec3(0, 0, 0), glm::vec3(0, TREE_SCALE, 0), green); + geometryCache->renderLine(glm::vec3(0, 0, 0), glm::vec3(0, 0, TREE_SCALE), blue); + geometryCache->renderLine(glm::vec3(0, 0, TREE_SCALE), glm::vec3(TREE_SCALE, 0, TREE_SCALE), grey); + geometryCache->renderLine(glm::vec3(TREE_SCALE, 0, TREE_SCALE), glm::vec3(TREE_SCALE, 0, 0), grey); // Draw meter markers along the 3 axis to help with measuring things @@ -60,21 +56,21 @@ void renderWorldBox() { glEnable(GL_LIGHTING); glPushMatrix(); glTranslatef(MARKER_DISTANCE, 0, 0); - glColor3fv(red); + glColor3f(red.x, red.y, red.z); geometryCache->renderSphere(MARKER_RADIUS, 10, 10); glPopMatrix(); glPushMatrix(); glTranslatef(0, MARKER_DISTANCE, 0); - glColor3fv(green); + glColor3f(green.x, green.y, green.z); geometryCache->renderSphere(MARKER_RADIUS, 10, 10); glPopMatrix(); glPushMatrix(); glTranslatef(0, 0, MARKER_DISTANCE); - glColor3fv(blue); + glColor3f(blue.x, blue.y, blue.z); geometryCache->renderSphere(MARKER_RADIUS, 10, 10); glPopMatrix(); glPushMatrix(); - glColor3fv(gray); + glColor3f(grey.x, grey.y, grey.z); glTranslatef(MARKER_DISTANCE, 0, MARKER_DISTANCE); geometryCache->renderSphere(MARKER_RADIUS, 10, 10); glPopMatrix(); diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index ddbaeece72..c97db94eb6 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -301,8 +301,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool glm::vec3 axis = glm::axis(rotation); glRotatef(angle, axis.x, axis.y, axis.z); - glColor3f(laserColor.x, laserColor.y, laserColor.z); - geometryCache->renderLine(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, laserLength, 0.0f)); + geometryCache->renderLine(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, laserLength, 0.0f), laserColor); } glPopMatrix(); } @@ -327,8 +326,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool float angle = glm::degrees(glm::angle(rotation)); glm::vec3 axis = glm::axis(rotation); glRotatef(angle, axis.x, axis.y, axis.z); - glColor3f(laserColor.x, laserColor.y, laserColor.z); - geometryCache->renderLine(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, laserLength, 0.0f)); + geometryCache->renderLine(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, laserLength, 0.0f), laserColor); } glPopMatrix(); } diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index 32594a7225..f53975a4e8 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -345,11 +345,10 @@ void Head::renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosi glLineWidth(2.0); - // TODO: implement support for lines with gradient colors - // glColor4f(0.2f, 0.2f, 0.2f, 1.0f); --> to --> glColor4f(1.0f, 1.0f, 1.0f, 0.0f); - glColor4f(0.5f, 0.5f, 0.5f, 0.5f); - geometryCache->renderLine(leftEyePosition, lookatPosition, _leftEyeLookAtID); - geometryCache->renderLine(rightEyePosition, lookatPosition, _rightEyeLookAtID); + glm::vec4 startColor(0.2f, 0.2f, 0.2f, 1.0f); + glm::vec4 endColor(1.0f, 1.0f, 1.0f, 0.0f); + geometryCache->renderLine(leftEyePosition, lookatPosition, startColor, endColor, _leftEyeLookAtID); + geometryCache->renderLine(rightEyePosition, lookatPosition, startColor, endColor, _rightEyeLookAtID); DependencyManager::get()->end(); } diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 54cd6c0bfe..31fa648d17 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -396,14 +396,14 @@ void SkeletonModel::renderOrientationDirections(int jointIndex, glm::vec3 positi glm::vec3 pUp = position + orientation * IDENTITY_UP * size; glm::vec3 pFront = position + orientation * IDENTITY_FRONT * size; - glColor3f(1.0f, 0.0f, 0.0f); - geometryCache->renderLine(position, pRight, jointLineIDs._right); + glm::vec3 red(1.0f, 0.0f, 0.0f); + geometryCache->renderLine(position, pRight, red, jointLineIDs._right); - glColor3f(0.0f, 1.0f, 0.0f); - geometryCache->renderLine(position, pUp, jointLineIDs._up); + glm::vec3 green(0.0f, 1.0f, 0.0f); + geometryCache->renderLine(position, pUp, green, jointLineIDs._up); - glColor3f(0.0f, 0.0f, 1.0f); - geometryCache->renderLine(position, pFront, jointLineIDs._front); + glm::vec3 blue(0.0f, 0.0f, 1.0f); + geometryCache->renderLine(position, pFront, blue, jointLineIDs._front); } diff --git a/interface/src/ui/overlays/Line3DOverlay.cpp b/interface/src/ui/overlays/Line3DOverlay.cpp index 48a995b80b..ab537eea89 100644 --- a/interface/src/ui/overlays/Line3DOverlay.cpp +++ b/interface/src/ui/overlays/Line3DOverlay.cpp @@ -50,6 +50,7 @@ void Line3DOverlay::render(RenderArgs* args) { xColor color = getColor(); const float MAX_COLOR = 255.0f; glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); + glm::vec4 colorv4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); glm::vec3 position = getPosition(); glm::quat rotation = getRotation(); @@ -61,7 +62,7 @@ void Line3DOverlay::render(RenderArgs* args) { if (getIsDashedLine()) { DependencyManager::get()->renderDashedLine(_position, _end, _geometryCacheID); } else { - DependencyManager::get()->renderLine(_start, _end, _geometryCacheID); + DependencyManager::get()->renderLine(_start, _end, colorv4, _geometryCacheID); } glEnable(GL_LIGHTING); diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 553e460a5c..4d09ab0163 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -18,6 +18,9 @@ #include #include +#include +#include + #include #include "TextureCache.h" @@ -1397,18 +1400,30 @@ void GeometryCache::renderDashedLine(const glm::vec3& start, const glm::vec3& en details.buffer.release(); } -void GeometryCache::renderLine(const glm::vec3& p1, const glm::vec3& p2, int id) { - bool registeredLine = (id != UNKNOWN_ID); +void GeometryCache::renderLine(const glm::vec3& p1, const glm::vec3& p2, + const glm::vec4& color1, const glm::vec4& color2, int id) { + + bool registered = (id != UNKNOWN_ID); Vec3Pair key(p1, p2); - VerticesIndices& vbo = registeredLine ? _registeredLine3DVBOs[id] : _line3DVBOs[key]; + 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 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); + // if this is a registered quad, and we have buffers, then check to see if the geometry changed and rebuild if needed - if (registeredLine && vbo.first != 0) { + if (registered && details.isCreated) { Vec3Pair& lastKey = _lastRegisteredLine3D[id]; if (lastKey != key) { - glDeleteBuffers(1, &vbo.first); - glDeleteBuffers(1, &vbo.second); - vbo.first = vbo.second = 0; + details.clear(); + _lastRegisteredLine3D[id] = key; #ifdef WANT_DEBUG qDebug() << "renderLine() 3D ... RELEASING REGISTERED line"; #endif // def WANT_DEBUG @@ -1421,46 +1436,38 @@ void GeometryCache::renderLine(const glm::vec3& p1, const glm::vec3& p2, int id) } const int FLOATS_PER_VERTEX = 3; - const int NUM_BYTES_PER_VERTEX = FLOATS_PER_VERTEX * sizeof(GLfloat); const int vertices = 2; - const int indices = 2; - if (vbo.first == 0) { - _lastRegisteredLine3D[id] = key; + if (!details.isCreated) { - int vertexPoints = vertices * FLOATS_PER_VERTEX; - GLfloat* vertexData = new GLfloat[vertexPoints]; // only vertices, no normals because we're a 2D quad - GLfloat* vertex = vertexData; - static GLubyte cannonicalIndices[indices] = {0, 1}; - - int vertexPoint = 0; + details.isCreated = true; + details.vertices = vertices; + details.vertexSize = FLOATS_PER_VERTEX; - // p1 - vertex[vertexPoint++] = p1.x; - vertex[vertexPoint++] = p1.y; - vertex[vertexPoint++] = p1.z; + gpu::BufferPointer verticesBuffer(new gpu::Buffer()); + gpu::BufferPointer colorBuffer(new gpu::Buffer()); + gpu::Stream::FormatPointer streamFormat(new gpu::Stream::Format()); + gpu::BufferStreamPointer stream(new gpu::BufferStream()); - // p2 - vertex[vertexPoint++] = p2.x; - vertex[vertexPoint++] = p2.y; - vertex[vertexPoint++] = p2.z; - + 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::POS_XYZ), 0); + details.streamFormat->setAttribute(gpu::Stream::COLOR, 1, gpu::Element(gpu::VEC4, gpu::UINT8, 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); + + + float vertexBuffer[vertices * FLOATS_PER_VERTEX] = { p1.x, p1.y, p1.z, p2.x, p2.y, p2.z }; + + const int NUM_COLOR_SCALARS = 2; + int colors[NUM_COLOR_SCALARS] = { compactColor1, compactColor2 }; + + details.verticesBuffer->append(sizeof(vertexBuffer), (gpu::Buffer::Byte*) vertexBuffer); + details.colorBuffer->append(sizeof(colors), (gpu::Buffer::Byte*) colors); - glGenBuffers(1, &vbo.first); - glBindBuffer(GL_ARRAY_BUFFER, vbo.first); - glBufferData(GL_ARRAY_BUFFER, vertices * NUM_BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW); - delete[] vertexData; - - GLushort* indexData = new GLushort[indices]; - GLushort* index = indexData; - for (int i = 0; i < indices; i++) { - index[i] = cannonicalIndices[i]; - } - - glGenBuffers(1, &vbo.second); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * NUM_BYTES_PER_INDEX, indexData, GL_STATIC_DRAW); - delete[] indexData; - #ifdef WANT_DEBUG if (id == UNKNOWN_ID) { qDebug() << "new renderLine() 3D VBO made -- _line3DVBOs.size():" << _line3DVBOs.size(); @@ -1468,18 +1475,20 @@ void GeometryCache::renderLine(const glm::vec3& p1, const glm::vec3& p2, int id) qDebug() << "new registered renderLine() 3D VBO made -- _registeredLine3DVBOs.size():" << _registeredLine3DVBOs.size(); } #endif - - } else { - glBindBuffer(GL_ARRAY_BUFFER, vbo.first); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second); } - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(FLOATS_PER_VERTEX, GL_FLOAT, FLOATS_PER_VERTEX * sizeof(float), 0); - glDrawRangeElementsEXT(GL_LINES, 0, vertices - 1, indices, GL_UNSIGNED_SHORT, 0); + + gpu::Batch batch; + + // this is what it takes to render a quad + batch.setInputFormat(details.streamFormat); + batch.setInputStream(0, *details.stream); + batch.draw(gpu::LINES, 2, 0); + + gpu::GLBackend::renderBatch(batch); + glDisableClientState(GL_VERTEX_ARRAY); - + glDisableClientState(GL_COLOR_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } void GeometryCache::renderLine(const glm::vec2& p1, const glm::vec2& p2, int id) { diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index 17b23da945..96e3f4c398 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -111,7 +111,20 @@ public: const glm::vec2& texCoordBottomRight, const glm::vec2& texCoordTopRight, int id = UNKNOWN_ID); - void renderLine(const glm::vec3& p1, const glm::vec3& p2, int id = UNKNOWN_ID); + void renderLine(const glm::vec3& p1, const glm::vec3& p2, const glm::vec3& color, int id = UNKNOWN_ID) + { renderLine(p1, p2, color, color, id); } + + void renderLine(const glm::vec3& p1, const glm::vec3& p2, + const glm::vec3& color1, const glm::vec3& color2, int id = UNKNOWN_ID) + { renderLine(p1, p2, glm::vec4(color1, 1.0f), glm::vec4(color2, 1.0f), id); } + + void renderLine(const glm::vec3& p1, const glm::vec3& p2, + const glm::vec4& color, int id = UNKNOWN_ID) + { renderLine(p1, p2, color, color, id); } + + void renderLine(const glm::vec3& p1, const glm::vec3& p2, + const glm::vec4& color1, const glm::vec4& color2, int id = UNKNOWN_ID); + void renderDashedLine(const glm::vec3& start, const glm::vec3& end, int id = UNKNOWN_ID); void renderLine(const glm::vec2& p1, const glm::vec2& p2, int id = UNKNOWN_ID); @@ -128,13 +141,46 @@ protected: virtual QSharedPointer createResource(const QUrl& url, const QSharedPointer& fallback, bool delayLoad, const void* extra); - + private: GeometryCache(); virtual ~GeometryCache(); typedef QPair IntPair; typedef QPair VerticesIndices; + struct BufferDetails { + QOpenGLBuffer buffer; + int vertices; + int vertexSize; + }; + + class BatchItemDetails { + public: + gpu::BufferPointer verticesBuffer; + gpu::BufferPointer colorBuffer; + gpu::Stream::FormatPointer streamFormat; + gpu::BufferStreamPointer stream; + + int vertices; + int vertexSize; + bool isCreated; + + BatchItemDetails() : + verticesBuffer(NULL), + colorBuffer(NULL), + streamFormat(NULL), + stream(NULL), + vertices(0), + vertexSize(0), + isCreated(false) + { + } + + void clear() { + // TODO: add the proper de-allocation of the gpu items + isCreated = false; + } + }; QHash _hemisphereVBOs; QHash _sphereVBOs; @@ -160,27 +206,20 @@ private: QHash _registeredRectVBOs; QHash _lastRegisteredLine3D; - QHash _line3DVBOs; - QHash _registeredLine3DVBOs; + QHash _line3DVBOs; + QHash _registeredLine3DVBOs; QHash _lastRegisteredLine2D; QHash _line2DVBOs; QHash _registeredLine2DVBOs; - struct BufferDetails { - QOpenGLBuffer buffer; - int vertices; - int vertexSize; - }; - QHash _registeredVertices; QHash _lastRegisteredDashedLines; QHash _dashedLines; QHash _registeredDashedLines; - - + QHash _colors; QHash _gridBuffers; QHash _registeredAlternateGridBuffers;