diff --git a/interface/src/audio/AudioScope.cpp b/interface/src/audio/AudioScope.cpp index 79e52fb5f5..b2e6d35dcf 100644 --- a/interface/src/audio/AudioScope.cpp +++ b/interface/src/audio/AudioScope.cpp @@ -195,7 +195,7 @@ void AudioScope::renderLineStrip(int id, const glm::vec4& color, int x, int y, i geometryCache->updateVertices(id, points, color); - geometryCache->renderVertices(GL_LINE_STRIP, id); + geometryCache->renderVertices(gpu::LINE_STRIP, id); glColor4f(1, 1, 1, 1); } diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 690322201b..92f2b72352 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -574,7 +574,6 @@ void Avatar::renderBillboard() { glm::vec2 texCoordBottomRight(1.0f, 1.0f); DependencyManager::get()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); - glPopMatrix(); @@ -990,7 +989,7 @@ void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, // TODO: this is really inefficient constantly recreating these vertices buffers. It would be // better if the avatars cached these buffers for each of the joints they are rendering geometryCache->updateVertices(_jointConesID, points, color); - geometryCache->renderVertices(GL_TRIANGLES, _jointConesID); + geometryCache->renderVertices(gpu::TRIANGLES, _jointConesID); } } diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 5e179a341c..296ff6fee9 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -367,7 +367,7 @@ void SkeletonModel::renderJointConstraints(int jointIndex) { // TODO: this is really inefficient constantly recreating these vertices buffers. It would be // better if the skeleton model cached these buffers for each of the joints they are rendering geometryCache->updateVertices(_triangleFanID, points, color); - geometryCache->renderVertices(GL_TRIANGLE_FAN, _triangleFanID); + geometryCache->renderVertices(gpu::TRIANGLE_FAN, _triangleFanID); } glPopMatrix(); diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 8bf2755509..1a57a16bef 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -767,7 +767,7 @@ void ApplicationOverlay::renderMagnifier(glm::vec2 magPos, float sizeMult, bool glDisable(GL_TEXTURE_2D); glLineWidth(1.0f); //Outer Line - geometryCache->renderVertices(GL_LINE_STRIP, _magnifierBorder); + geometryCache->renderVertices(gpu::LINE_STRIP, _magnifierBorder); glEnable(GL_TEXTURE_2D); } glColor4f(1.0f, 1.0f, 1.0f, _alpha); @@ -970,7 +970,7 @@ void ApplicationOverlay::renderDomainConnectionStatusBorder() { glLineWidth(CONNECTION_STATUS_BORDER_LINE_WIDTH); - geometryCache->renderVertices(GL_LINE_STRIP, _domainStatusBorder); + geometryCache->renderVertices(gpu::LINE_STRIP, _domainStatusBorder); } } diff --git a/interface/src/ui/overlays/Circle3DOverlay.cpp b/interface/src/ui/overlays/Circle3DOverlay.cpp index 8244532d5a..f890999174 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.cpp +++ b/interface/src/ui/overlays/Circle3DOverlay.cpp @@ -164,7 +164,7 @@ void Circle3DOverlay::render(RenderArgs* args) { geometryCache->updateVertices(_quadVerticesID, points, color); } - geometryCache->renderVertices(GL_QUAD_STRIP, _quadVerticesID); + geometryCache->renderVertices(gpu::QUAD_STRIP, _quadVerticesID); } else { if (_lineVerticesID == GeometryCache::UNKNOWN_ID) { @@ -203,9 +203,9 @@ void Circle3DOverlay::render(RenderArgs* args) { } if (getIsDashedLine()) { - geometryCache->renderVertices(GL_LINES, _lineVerticesID); + geometryCache->renderVertices(gpu::LINES, _lineVerticesID); } else { - geometryCache->renderVertices(GL_LINE_STRIP, _lineVerticesID); + geometryCache->renderVertices(gpu::LINE_STRIP, _lineVerticesID); } } @@ -280,9 +280,9 @@ void Circle3DOverlay::render(RenderArgs* args) { geometryCache->updateVertices(_minorTicksVerticesID, minorPoints, minorColor); } - geometryCache->renderVertices(GL_LINES, _majorTicksVerticesID); + geometryCache->renderVertices(gpu::LINES, _majorTicksVerticesID); - geometryCache->renderVertices(GL_LINES, _minorTicksVerticesID); + geometryCache->renderVertices(gpu::LINES, _minorTicksVerticesID); } diff --git a/interface/src/ui/overlays/ImageOverlay.cpp b/interface/src/ui/overlays/ImageOverlay.cpp index 169a3eaa3d..416643a846 100644 --- a/interface/src/ui/overlays/ImageOverlay.cpp +++ b/interface/src/ui/overlays/ImageOverlay.cpp @@ -89,7 +89,7 @@ void ImageOverlay::render(RenderArgs* args) { float imageWidth = _textureImage.width(); float imageHeight = _textureImage.height(); - + QRect fromImage; if (_wantClipFromImage) { fromImage = _fromImage; @@ -114,7 +114,8 @@ void ImageOverlay::render(RenderArgs* args) { glm::vec2 texCoordTopLeft(x, 1.0f - y); glm::vec2 texCoordBottomRight(x + w, 1.0f - (y + h)); - if (_renderImage) { + // if for some reason our image is not over 0 width or height, don't attempt to render the image + if (_renderImage && imageWidth > 0 && imageHeight > 0) { DependencyManager::get()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, quadColor); } else { DependencyManager::get()->renderQuad(topLeft, bottomRight, quadColor); diff --git a/interface/src/ui/overlays/Rectangle3DOverlay.cpp b/interface/src/ui/overlays/Rectangle3DOverlay.cpp index 45873380c4..0c81e932a3 100644 --- a/interface/src/ui/overlays/Rectangle3DOverlay.cpp +++ b/interface/src/ui/overlays/Rectangle3DOverlay.cpp @@ -100,7 +100,7 @@ void Rectangle3DOverlay::render(RenderArgs* args) { _previousHalfDimensions = halfDimensions; } - geometryCache->renderVertices(GL_LINE_STRIP, _geometryCacheID); + geometryCache->renderVertices(gpu::LINE_STRIP, _geometryCacheID); } } diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index c3a87c8f19..f73ab66d14 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -45,7 +45,9 @@ enum Primitive { LINE_STRIP, TRIANGLES, TRIANGLE_STRIP, + TRIANGLE_FAN, QUADS, + QUAD_STRIP, NUM_PRIMITIVES, }; diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index f5f998d0d9..bd369c0806 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -93,7 +93,9 @@ static const GLenum _primitiveToGLmode[NUM_PRIMITIVES] = { GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP, + GL_TRIANGLE_FAN, GL_QUADS, + GL_QUAD_STRIP, }; static const GLenum _elementTypeToGLType[NUM_TYPES]= { diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 75fb2171f7..8d0b7f276a 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -607,81 +607,149 @@ void GeometryCache::renderGrid(int x, int y, int width, int height, int rows, in } void GeometryCache::updateVertices(int id, const QVector& points, const glm::vec4& color) { - BufferDetails& details = _registeredVertices[id]; + qDebug() << "GeometryCache::updateVertices(id=" << id <<")..."; + BatchItemDetails& details = _registeredVertices[id]; - if (details.buffer.isCreated()) { - details.buffer.destroy(); + if (details.isCreated) { + details.clear(); #ifdef WANT_DEBUG qDebug() << "updateVertices()... RELEASING REGISTERED"; #endif // def WANT_DEBUG } const int FLOATS_PER_VERTEX = 2; + details.isCreated = true; details.vertices = points.size(); details.vertexSize = FLOATS_PER_VERTEX; + 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()); + + 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); + + details.vertices = points.size(); + 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); + GLfloat* vertexData = new GLfloat[details.vertices * FLOATS_PER_VERTEX]; GLfloat* vertex = vertexData; + int* colorData = new int[details.vertices]; + int* colorDataAt = colorData; + foreach (const glm::vec2& point, points) { *(vertex++) = point.x; *(vertex++) = point.y; + + *(colorDataAt++) = compactColor; } - details.buffer.create(); - details.buffer.setUsagePattern(QOpenGLBuffer::StaticDraw); - details.buffer.bind(); - details.buffer.allocate(vertexData, details.vertices * FLOATS_PER_VERTEX * sizeof(GLfloat)); - delete[] vertexData; - - #ifdef WANT_DEBUG - qDebug() << "new registered vertices buffer made -- _registeredVertices.size():" << _registeredVertices.size(); - #endif -} - -void GeometryCache::updateVertices(int id, const QVector& points, const glm::vec4& color) { - BufferDetails& details = _registeredVertices[id]; - - if (details.buffer.isCreated()) { - details.buffer.destroy(); - #ifdef WANT_DEBUG - qDebug() << "updateVertices()... RELEASING REGISTERED"; - #endif // def WANT_DEBUG - } - - const int FLOATS_PER_VERTEX = 3; - details.vertices = points.size(); - details.vertexSize = FLOATS_PER_VERTEX; - - GLfloat* vertexData = new GLfloat[details.vertices * FLOATS_PER_VERTEX]; - GLfloat* vertex = vertexData; - - foreach (const glm::vec3& point, points) { - *(vertex++) = point.x; - *(vertex++) = point.y; - *(vertex++) = point.z; - } - - details.buffer.create(); - details.buffer.setUsagePattern(QOpenGLBuffer::StaticDraw); - details.buffer.bind(); - details.buffer.allocate(vertexData, details.vertices * FLOATS_PER_VERTEX * sizeof(GLfloat)); + details.verticesBuffer->append(FLOATS_PER_VERTEX * details.vertices, (gpu::Buffer::Byte*) vertexData); + details.colorBuffer->append(sizeof(int) * details.vertices, (gpu::Buffer::Byte*) colorData); delete[] vertexData; + delete[] colorData; #ifdef WANT_DEBUG qDebug() << "new registered linestrip buffer made -- _registeredVertices.size():" << _registeredVertices.size(); #endif } -void GeometryCache::renderVertices(GLenum mode, int id) { - BufferDetails& details = _registeredVertices[id]; - if (details.buffer.isCreated()) { - details.buffer.bind(); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(details.vertexSize, GL_FLOAT, 0, 0); - glDrawArrays(mode, 0, details.vertices); +void GeometryCache::updateVertices(int id, const QVector& points, const glm::vec4& color) { + qDebug() << "GeometryCache::updateVertices(id=" << id <<")..."; + BatchItemDetails& details = _registeredVertices[id]; + + if (details.isCreated) { + details.clear(); + #ifdef WANT_DEBUG + qDebug() << "updateVertices()... RELEASING REGISTERED"; + #endif // def WANT_DEBUG + } + + const int FLOATS_PER_VERTEX = 3; + details.isCreated = true; + details.vertices = points.size(); + details.vertexSize = FLOATS_PER_VERTEX; + + 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()); + + 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); + + details.vertices = points.size(); + 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); + + GLfloat* vertexData = new GLfloat[details.vertices * FLOATS_PER_VERTEX]; + GLfloat* vertex = vertexData; + + int* colorData = new int[details.vertices]; + int* colorDataAt = colorData; + + foreach (const glm::vec3& point, points) { + *(vertex++) = point.x; + *(vertex++) = point.y; + *(vertex++) = point.z; + + *(colorDataAt++) = compactColor; + } + + details.verticesBuffer->append(FLOATS_PER_VERTEX * details.vertices, (gpu::Buffer::Byte*) vertexData); + details.colorBuffer->append(sizeof(int) * details.vertices, (gpu::Buffer::Byte*) colorData); + delete[] vertexData; + delete[] colorData; + + #ifdef WANT_DEBUG + qDebug() << "new registered linestrip buffer made -- _registeredVertices.size():" << _registeredVertices.size(); + #endif +} + +void GeometryCache::renderVertices(gpu::Primitive primitiveType, int id) { + qDebug() << "GeometryCache::renderVertices(id=" << id <<")..."; + + BatchItemDetails& details = _registeredVertices[id]; + if (details.isCreated) { + gpu::Batch batch; + + batch.setInputFormat(details.streamFormat); + batch.setInputStream(0, *details.stream); + batch.draw(primitiveType, details.vertices, 0); + + gpu::GLBackend::renderBatch(batch); + glDisableClientState(GL_VERTEX_ARRAY); - details.buffer.release(); + glDisableClientState(GL_COLOR_ARRAY); + + glBindBuffer(GL_ARRAY_BUFFER, 0); } } @@ -897,6 +965,7 @@ void GeometryCache::renderWireCube(float size, const glm::vec4& color) { } void GeometryCache::renderBevelCornersRect(int x, int y, int width, int height, int bevelDistance, const glm::vec4& color, int id) { + qDebug() << "GeometryCache::renderBevelCornersRect(id=" << id <<")..."; bool registered = (id != UNKNOWN_ID); Vec3Pair key(glm::vec3(x, y, 0.0f), glm::vec3(width, height, bevelDistance)); BatchItemDetails& details = registered ? _registeredBevelRects[id] : _bevelRects[key]; @@ -1004,6 +1073,7 @@ void GeometryCache::renderBevelCornersRect(int x, int y, int width, int height, } void GeometryCache::renderQuad(const glm::vec2& minCorner, const glm::vec2& maxCorner, const glm::vec4& color, int id) { + qDebug() << "GeometryCache::renderQuad(vec2,id=" << id <<")..."; bool registered = (id != UNKNOWN_ID); Vec2Pair key(minCorner, maxCorner); BatchItemDetails& details = registered ? _registeredQuad2D[id] : _quad2D[key]; @@ -1087,6 +1157,7 @@ void GeometryCache::renderQuad(const glm::vec2& minCorner, const glm::vec2& maxC const glm::vec2& texCoordMinCorner, const glm::vec2& texCoordMaxCorner, const glm::vec4& color, int id) { + qDebug() << "GeometryCache::renderQuad(vec2/texture,id=" << id <<")..."; bool registered = (id != UNKNOWN_ID); Vec2PairPair key(Vec2Pair(minCorner, maxCorner), Vec2Pair(texCoordMinCorner, texCoordMaxCorner)); BatchItemDetails& details = registered ? _registeredQuad2DTextures[id] : _quad2DTextures[key]; @@ -1177,6 +1248,7 @@ void GeometryCache::renderQuad(const glm::vec2& minCorner, const glm::vec2& maxC } void GeometryCache::renderQuad(const glm::vec3& minCorner, const glm::vec3& maxCorner, const glm::vec4& color, int id) { + qDebug() << "GeometryCache::renderQuad(vec3,id=" << id <<")..."; bool registered = (id != UNKNOWN_ID); Vec3Pair key(minCorner, maxCorner); BatchItemDetails& details = registered ? _registeredQuad3D[id] : _quad3D[key]; @@ -1464,6 +1536,7 @@ GeometryCache::BatchItemDetails::BatchItemDetails() : isCreated(false) { population++; + qDebug() << "BatchItemDetails()... population:" << population << "**********************************"; } GeometryCache::BatchItemDetails::BatchItemDetails(const GeometryCache::BatchItemDetails& other) : @@ -1476,12 +1549,13 @@ GeometryCache::BatchItemDetails::BatchItemDetails(const GeometryCache::BatchItem isCreated(other.isCreated) { population++; + qDebug() << "BatchItemDetails()... population:" << population << "**********************************"; } GeometryCache::BatchItemDetails::~BatchItemDetails() { population--; clear(); - //qDebug() << "~BatchItemDetails()... population:" << population << "**********************************"; + qDebug() << "~BatchItemDetails()... population:" << population << "**********************************"; } void GeometryCache::BatchItemDetails::clear() { @@ -1495,6 +1569,7 @@ void GeometryCache::BatchItemDetails::clear() { void GeometryCache::renderLine(const glm::vec3& p1, const glm::vec3& p2, const glm::vec4& color1, const glm::vec4& color2, int id) { + qDebug() << "GeometryCache::renderLine(vec3)..."; bool registered = (id != UNKNOWN_ID); Vec3Pair key(p1, p2); @@ -1587,6 +1662,7 @@ void GeometryCache::renderLine(const glm::vec3& p1, const glm::vec3& p2, void GeometryCache::renderLine(const glm::vec2& p1, const glm::vec2& p2, const glm::vec4& color1, const glm::vec4& color2, int id) { + qDebug() << "GeometryCache::renderLine(vec2)..."; bool registered = (id != UNKNOWN_ID); Vec2Pair key(p1, p2); diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index 1a9230a23a..3aa18efb7e 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -25,7 +25,9 @@ #include -#include "gpu/Stream.h" +#include +#include + class NetworkGeometry; class NetworkMesh; @@ -153,7 +155,7 @@ public: void updateVertices(int id, const QVector& points, const glm::vec4& color); void updateVertices(int id, const QVector& points, const glm::vec4& color); - void renderVertices(GLenum mode, int id); + void renderVertices(gpu::Primitive primitiveType, int id); /// Loads geometry from the specified URL. /// \param fallback a fallback URL to load if the desired one is unavailable @@ -244,7 +246,7 @@ private: QHash _line2DVBOs; QHash _registeredLine2DVBOs; - QHash _registeredVertices; + QHash _registeredVertices; QHash _lastRegisteredDashedLines; QHash _dashedLines; diff --git a/libraries/render-utils/src/RenderUtil.cpp b/libraries/render-utils/src/RenderUtil.cpp index c27c56161a..7744817625 100644 --- a/libraries/render-utils/src/RenderUtil.cpp +++ b/libraries/render-utils/src/RenderUtil.cpp @@ -22,5 +22,6 @@ void renderFullscreenQuad(float sMin, float sMax, float tMin, float tMax) { glm::vec2 bottomRight(1.0f, 1.0f); glm::vec2 texCoordTopLeft(sMin, tMin); glm::vec2 texCoordBottomRight(sMax, tMax); + DependencyManager::get()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); }