From be137534b5a76a816684d6e7943dda71febec2dc Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 30 Dec 2014 12:38:16 -0800 Subject: [PATCH] first cut at registered quads to reduce copies of constantly changing quads --- interface/src/ui/ApplicationOverlay.cpp | 50 +++++++-- interface/src/ui/ApplicationOverlay.h | 9 +- libraries/render-utils/src/GeometryCache.cpp | 105 ++++++++++++++++--- libraries/render-utils/src/GeometryCache.h | 20 ++-- 4 files changed, 149 insertions(+), 35 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 6c68e0add1..120c5b3043 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -105,7 +105,7 @@ bool raySphereIntersect(const glm::vec3 &dir, const glm::vec3 &origin, float r, } } -void renderReticle(glm::quat orientation, float alpha) { +void ApplicationOverlay::renderReticle(glm::quat orientation, float alpha) { glPushMatrix(); { glm::vec3 axis = glm::axis(orientation); glRotatef(glm::degrees(glm::angle(orientation)), axis.x, axis.y, axis.z); @@ -114,9 +114,12 @@ void renderReticle(glm::quat orientation, float alpha) { glm::vec3 bottomLeft = getPoint(reticleSize / 2.0f, reticleSize / 2.0f); glm::vec3 bottomRight = getPoint(-reticleSize / 2.0f, reticleSize / 2.0f); glColor4f(RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], alpha); + if (_reticleQuad == GeometryCache::UNKNOWN_QUAD_ID) { + _reticleQuad = DependencyManager::get()->allocateQuad(); + } DependencyManager::get()->renderQuad(topLeft, bottomLeft, bottomRight, topRight, glm::vec2(0.0f, 0.0f), glm::vec2(1.0f, 0.0f), - glm::vec2(1.0f, 1.0f), glm::vec2(0.0f, 1.0f)); + glm::vec2(1.0f, 1.0f), glm::vec2(0.0f, 1.0f), _reticleQuad); } glPopMatrix(); } @@ -126,8 +129,13 @@ ApplicationOverlay::ApplicationOverlay() : _lastMouseMove(0), _alpha(1.0f), _oculusUIRadius(1.0f), - _crosshairTexture(0) { - + _crosshairTexture(0), + _reticleQuad(GeometryCache::UNKNOWN_QUAD_ID), + _magnifierQuad(GeometryCache::UNKNOWN_QUAD_ID), + _audioRedQuad(GeometryCache::UNKNOWN_QUAD_ID), + _audioGreenQuad(GeometryCache::UNKNOWN_QUAD_ID), + _audioBlueQuad(GeometryCache::UNKNOWN_QUAD_ID) +{ memset(_reticleActive, 0, sizeof(_reticleActive)); memset(_magActive, 0, sizeof(_reticleActive)); memset(_magSizeMult, 0, sizeof(_magSizeMult)); @@ -389,12 +397,17 @@ void ApplicationOverlay::displayOverlayTexture3DTV(Camera& whichCamera, float as glColor3f(RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2]); + if (_reticleQuad == GeometryCache::UNKNOWN_QUAD_ID) { + _reticleQuad = DependencyManager::get()->allocateQuad(); + } + DependencyManager::get()->renderQuad(glm::vec3(x + mouseX, y + mouseY, -distance), glm::vec3(x + mouseX + reticleSize, y + mouseY, -distance), glm::vec3(x + mouseX + reticleSize, y + mouseY - reticleSize, -distance), glm::vec3(x + mouseX, y + mouseY - reticleSize, -distance), glm::vec2(0.0f, 0.0f), glm::vec2(1.0f, 0.0f), - glm::vec2(1.0f, 1.0f), glm::vec2(0.0f, 1.0f)); + glm::vec2(1.0f, 1.0f), glm::vec2(0.0f, 1.0f), + _reticleQuad); glEnable(GL_DEPTH_TEST); @@ -696,7 +709,7 @@ void ApplicationOverlay::renderPointersOculus(const glm::vec3& eyePos) { } //Renders a small magnification of the currently bound texture at the coordinates -void ApplicationOverlay::renderMagnifier(glm::vec2 magPos, float sizeMult, bool showBorder) const { +void ApplicationOverlay::renderMagnifier(glm::vec2 magPos, float sizeMult, bool showBorder) { GLCanvas::SharedPointer glCanvas = DependencyManager::get(); const int widgetWidth = glCanvas->width(); @@ -742,11 +755,16 @@ void ApplicationOverlay::renderMagnifier(glm::vec2 magPos, float sizeMult, bool } glColor4f(1.0f, 1.0f, 1.0f, _alpha); + if (_magnifierQuad == GeometryCache::UNKNOWN_QUAD_ID) { + _magnifierQuad = DependencyManager::get()->allocateQuad(); + } + DependencyManager::get()->renderQuad(bottomLeft, bottomRight, topRight, topLeft, glm::vec2(magnifyULeft, magnifyVBottom), glm::vec2(magnifyURight, magnifyVBottom), glm::vec2(magnifyURight, magnifyVTop), - glm::vec2(magnifyULeft, magnifyVTop)); + glm::vec2(magnifyULeft, magnifyVTop), + _magnifierQuad); } glPopMatrix(); } @@ -845,10 +863,14 @@ void ApplicationOverlay::renderAudioMeter() { glColor3f(1, 1, 1); } // Draw Red Quad + if (_audioRedQuad == GeometryCache::UNKNOWN_QUAD_ID) { + _audioRedQuad = DependencyManager::get()->allocateQuad(); + } DependencyManager::get()->renderQuad(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_RED_START, audioMeterY + AUDIO_METER_INSET, audioLevel - AUDIO_RED_START, - AUDIO_METER_HEIGHT - AUDIO_METER_INSET); + AUDIO_METER_HEIGHT - AUDIO_METER_INSET, + _audioRedQuad); audioLevel = AUDIO_RED_START; } @@ -860,10 +882,14 @@ void ApplicationOverlay::renderAudioMeter() { glColor3f(1, 1, 1); } // Draw Green Quad + if (_audioGreenQuad == GeometryCache::UNKNOWN_QUAD_ID) { + _audioGreenQuad = DependencyManager::get()->allocateQuad(); + } DependencyManager::get()->renderQuad(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_GREEN_START, audioMeterY + AUDIO_METER_INSET, audioLevel - AUDIO_GREEN_START, - AUDIO_METER_HEIGHT - AUDIO_METER_INSET); + AUDIO_METER_HEIGHT - AUDIO_METER_INSET, + _audioGreenQuad); audioLevel = AUDIO_GREEN_START; } @@ -874,9 +900,13 @@ void ApplicationOverlay::renderAudioMeter() { glColor3f(1, 1, 1); } // Draw Blue (low level) quad + if (_audioBlueQuad == GeometryCache::UNKNOWN_QUAD_ID) { + _audioBlueQuad = DependencyManager::get()->allocateQuad(); + } DependencyManager::get()->renderQuad(AUDIO_METER_X + AUDIO_METER_INSET, audioMeterY + AUDIO_METER_INSET, - audioLevel, AUDIO_METER_HEIGHT - AUDIO_METER_INSET); + audioLevel, AUDIO_METER_HEIGHT - AUDIO_METER_INSET, + _audioBlueQuad); } void ApplicationOverlay::renderStatsAndLogs() { diff --git a/interface/src/ui/ApplicationOverlay.h b/interface/src/ui/ApplicationOverlay.h index 269adef4f3..20d38c879c 100644 --- a/interface/src/ui/ApplicationOverlay.h +++ b/interface/src/ui/ApplicationOverlay.h @@ -79,8 +79,9 @@ private: VerticesIndices _vbo; }; + void renderReticle(glm::quat orientation, float alpha); void renderPointers();; - void renderMagnifier(glm::vec2 magPos, float sizeMult, bool showBorder) const; + void renderMagnifier(glm::vec2 magPos, float sizeMult, bool showBorder); void renderControllerPointers(); void renderPointersOculus(const glm::vec3& eyePos); @@ -106,6 +107,12 @@ private: float _trailingAudioLoudness; GLuint _crosshairTexture; + + int _reticleQuad; + int _magnifierQuad; + int _audioRedQuad; + int _audioGreenQuad; + int _audioBlueQuad; }; #endif // hifi_ApplicationOverlay_h diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index a1cadf2c20..2eb54331c8 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -23,7 +23,13 @@ #include "TextureCache.h" #include "GeometryCache.h" -GeometryCache::GeometryCache() { +//#define WANT_DEBUG + +const int GeometryCache::UNKNOWN_QUAD_ID = -1; + +GeometryCache::GeometryCache() : + _nextQuadID(0) +{ } GeometryCache::~GeometryCache() { @@ -661,9 +667,23 @@ void GeometryCache::renderWireCube(float size) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } -void GeometryCache::renderQuad(const glm::vec2& topLeft, const glm::vec2& bottomRight) { +void GeometryCache::renderQuad(const glm::vec2& topLeft, const glm::vec2& bottomRight, int quadID) { + + bool registeredQuad = (quadID != UNKNOWN_QUAD_ID); Vec2Pair key(topLeft, bottomRight); - VerticesIndices& vbo = _quad2DVBOs[key]; + VerticesIndices& vbo = registeredQuad ? _registeredQuadVBOs[quadID] : _quad2DVBOs[key]; + + // if this is a registered quad, and we have buffers, then clear them and rebuild + // TODO: would be nice to only rebuild if the geometry changed from last time. + if (registeredQuad && vbo.first != 0) { + glDeleteBuffers(1, &vbo.first); + glDeleteBuffers(1, &vbo.second); + vbo.first = vbo.second = 0; + #ifdef WANT_DEBUG + qDebug() << "renderQuad() vec2... RELEASING REGISTERED QUAD"; + #endif // def WANT_DEBUG + } + const int FLOATS_PER_VERTEX = 2; const int NUM_BYTES_PER_VERTEX = FLOATS_PER_VERTEX * sizeof(GLfloat); const int vertices = 4; @@ -700,7 +720,11 @@ void GeometryCache::renderQuad(const glm::vec2& topLeft, const glm::vec2& bottom delete[] indexData; #ifdef WANT_DEBUG - qDebug() << "new quad VBO made -- _quad2DVBOs.size():" << _quad2DVBOs.size(); + if (quadID == UNKNOWN_QUAD_ID) { + qDebug() << "new quad VBO made -- _quad2DVBOs.size():" << _quad2DVBOs.size(); + } else { + qDebug() << "new registered quad VBO made -- _registeredQuadVBOs.size():" << _registeredQuadVBOs.size(); + } #endif } else { @@ -718,10 +742,23 @@ void GeometryCache::renderQuad(const glm::vec2& topLeft, const glm::vec2& bottom void GeometryCache::renderQuad(const glm::vec2& topLeft, const glm::vec2& bottomRight, - const glm::vec2& texCoordTopLeft, const glm::vec2& texCoordBottomRight) { + const glm::vec2& texCoordTopLeft, const glm::vec2& texCoordBottomRight, int quadID) { + + bool registeredQuad = (quadID != UNKNOWN_QUAD_ID); Vec2PairPair key(Vec2Pair(topLeft, bottomRight), Vec2Pair(texCoordTopLeft, texCoordBottomRight)); + VerticesIndices& vbo = registeredQuad ? _registeredQuadVBOs[quadID] : _quad2DTextureVBOs[key]; - VerticesIndices& vbo = _quad2DTextureVBOs[key]; + // if this is a registered quad, and we have buffers, then clear them and rebuild + // TODO: would be nice to only rebuild if the geometry changed from last time. + if (registeredQuad && vbo.first != 0) { + glDeleteBuffers(1, &vbo.first); + glDeleteBuffers(1, &vbo.second); + vbo.first = vbo.second = 0; + #ifdef WANT_DEBUG + qDebug() << "renderQuad() vec2 + texture... RELEASING REGISTERED QUAD"; + #endif // def WANT_DEBUG + } + const int FLOATS_PER_VERTEX = 2 * 2; // text coords & vertices const int NUM_BYTES_PER_VERTEX = FLOATS_PER_VERTEX * sizeof(GLfloat); const int vertices = 4; @@ -770,7 +807,11 @@ void GeometryCache::renderQuad(const glm::vec2& topLeft, const glm::vec2& bottom delete[] indexData; #ifdef WANT_DEBUG - qDebug() << "new quad + texture VBO made -- _quad2DTextureVBOs.size():" << _quad2DTextureVBOs.size(); + if (quadID == UNKNOWN_QUAD_ID) { + qDebug() << "new quad + texture VBO made -- _quad2DTextureVBOs.size():" << _quad2DTextureVBOs.size(); + } else { + qDebug() << "new registered quad VBO made -- _registeredQuadVBOs.size():" << _registeredQuadVBOs.size(); + } #endif } else { glBindBuffer(GL_ARRAY_BUFFER, vbo.first); @@ -791,9 +832,23 @@ void GeometryCache::renderQuad(const glm::vec2& topLeft, const glm::vec2& bottom glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } -void GeometryCache::renderQuad(const glm::vec3& topLeft, const glm::vec3& bottomRight) { +void GeometryCache::renderQuad(const glm::vec3& topLeft, const glm::vec3& bottomRight, int quadID) { + + bool registeredQuad = (quadID != UNKNOWN_QUAD_ID); Vec3Pair key(topLeft, bottomRight); - VerticesIndices& vbo = _quad3DVBOs[key]; + VerticesIndices& vbo = registeredQuad ? _registeredQuadVBOs[quadID] : _quad3DVBOs[key]; + + // if this is a registered quad, and we have buffers, then clear them and rebuild + // TODO: would be nice to only rebuild if the geometry changed from last time. + if (registeredQuad && vbo.first != 0) { + glDeleteBuffers(1, &vbo.first); + glDeleteBuffers(1, &vbo.second); + vbo.first = vbo.second = 0; + #ifdef WANT_DEBUG + qDebug() << "renderQuad() vec3... RELEASING REGISTERED QUAD"; + #endif // def WANT_DEBUG + } + const int FLOATS_PER_VERTEX = 3; const int NUM_BYTES_PER_VERTEX = FLOATS_PER_VERTEX * sizeof(GLfloat); const int vertices = 4; @@ -838,7 +893,11 @@ void GeometryCache::renderQuad(const glm::vec3& topLeft, const glm::vec3& bottom delete[] indexData; #ifdef WANT_DEBUG - qDebug() << "new quad VBO made -- _quad3DVBOs.size():" << _quad3DVBOs.size(); + if (quadID == UNKNOWN_QUAD_ID) { + qDebug() << "new quad VBO made -- _quad3DVBOs.size():" << _quad3DVBOs.size(); + } else { + qDebug() << "new registered quad VBO made -- _registeredQuadVBOs.size():" << _registeredQuadVBOs.size(); + } #endif } else { @@ -858,7 +917,7 @@ void GeometryCache::renderQuad(const glm::vec3& topLeft, const glm::vec3& bottom void GeometryCache::renderQuad(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::vec2& texCoordBottomRight, const glm::vec2& texCoordTopRight, int quadID) { #ifdef WANT_DEBUG qDebug() << "renderQuad() vec3 + texture VBO..."; @@ -869,10 +928,22 @@ void GeometryCache::renderQuad(const glm::vec3& topLeft, const glm::vec3& bottom qDebug() << " texCoordTopLeft:" << texCoordTopLeft; qDebug() << " texCoordBottomRight:" << texCoordBottomRight; #endif //def WANT_DEBUG - - Vec3PairVec2Pair key(Vec3Pair(topLeft, bottomRight), Vec2Pair(texCoordTopLeft, texCoordBottomRight)); - VerticesIndices& vbo = _quad3DTextureVBOs[key]; + bool registeredQuad = (quadID != UNKNOWN_QUAD_ID); + Vec3PairVec2Pair key(Vec3Pair(topLeft, bottomRight), Vec2Pair(texCoordTopLeft, texCoordBottomRight)); + VerticesIndices& vbo = registeredQuad ? _registeredQuadVBOs[quadID] : _quad3DTextureVBOs[key]; + + // if this is a registered quad, and we have buffers, then clear them and rebuild + // TODO: would be nice to only rebuild if the geometry changed from last time. + if (registeredQuad && vbo.first != 0) { + glDeleteBuffers(1, &vbo.first); + glDeleteBuffers(1, &vbo.second); + vbo.first = vbo.second = 0; + #ifdef WANT_DEBUG + qDebug() << "renderQuad() vec3 + texture VBO... RELEASING REGISTERED QUAD"; + #endif // def WANT_DEBUG + } + const int FLOATS_PER_VERTEX = 5; // text coords & vertices const int NUM_BYTES_PER_VERTEX = FLOATS_PER_VERTEX * sizeof(GLfloat); const int vertices = 4; @@ -925,7 +996,11 @@ void GeometryCache::renderQuad(const glm::vec3& topLeft, const glm::vec3& bottom delete[] indexData; #ifdef WANT_DEBUG - qDebug() << " _quad3DTextureVBOs.size():" << _quad3DTextureVBOs.size(); + if (quadID == UNKNOWN_QUAD_ID) { + qDebug() << " _quad3DTextureVBOs.size():" << _quad3DTextureVBOs.size(); + } else { + qDebug() << "new registered quad VBO made -- _registeredQuadVBOs.size():" << _registeredQuadVBOs.size(); + } #endif } else { glBindBuffer(GL_ARRAY_BUFFER, vbo.first); diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index 9a76973f77..5736cea116 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -90,23 +90,23 @@ public: void renderSolidCube(float size); void renderWireCube(float size); + int allocateQuad() { return _nextQuadID++; } + static const int UNKNOWN_QUAD_ID; - void renderQuad(int x, int y, int width, int height) { renderQuad(glm::vec2(x,y), glm::vec2(x + width, y + height)); } - void renderQuad(const glm::vec2& topLeft, const glm::vec2& bottomRight); + void renderQuad(int x, int y, int width, int height, int quadID = UNKNOWN_QUAD_ID) + { renderQuad(glm::vec2(x,y), glm::vec2(x + width, y + height), quadID); } + + void renderQuad(const glm::vec2& topLeft, const glm::vec2& bottomRight, int quadID = UNKNOWN_QUAD_ID); void renderQuad(const glm::vec2& topLeft, const glm::vec2& bottomRight, - const glm::vec2& texCoordTopLeft, const glm::vec2& texCoordBottomRight); + const glm::vec2& texCoordTopLeft, const glm::vec2& texCoordBottomRight, int quadID = UNKNOWN_QUAD_ID); - - void renderQuad(const glm::vec3& topLeft, const glm::vec3& bottomRight); - - //void renderQuad(const glm::vec3& topLeft, const glm::vec3& bottomRight, - // const glm::vec2& texCoordTopLeft, const glm::vec2& texCoordBottomRight); + void renderQuad(const glm::vec3& topLeft, const glm::vec3& bottomRight, int quadID = UNKNOWN_QUAD_ID); void renderQuad(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::vec2& texCoordBottomRight, const glm::vec2& texCoordTopRight, int quadID = UNKNOWN_QUAD_ID); /// Loads geometry from the specified URL. /// \param fallback a fallback URL to load if the desired one is unavailable @@ -136,6 +136,8 @@ private: QHash _quad2DTextureVBOs; QHash _quad3DVBOs; QHash _quad3DTextureVBOs; + QHash _registeredQuadVBOs; + int _nextQuadID; QHash _gridBuffers;