diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 2511fb4480..a43bda34fa 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -1702,14 +1702,7 @@ void Audio::renderScope(int width, int height) { void Audio::renderBackground(const float* color, int x, int y, int width, int height) { glColor4fv(color); - glBegin(GL_QUADS); - - glVertex2i(x, y); - glVertex2i(x + width, y); - glVertex2i(x + width, y + height); - glVertex2i(x , y + height); - - glEnd(); + DependencyManager::get()->renderQuad(x, y, width, height); glColor4f(1, 1, 1, 1); } diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index d795964c5c..45a7dabb40 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -130,38 +130,10 @@ void renderCollisionOverlay(int width, int height, float magnitude, float red, f const float MIN_VISIBLE_COLLISION = 0.01f; if (magnitude > MIN_VISIBLE_COLLISION) { glColor4f(red, blue, green, magnitude); - glBegin(GL_QUADS); - glVertex2f(0, 0); - glVertex2d(width, 0); - glVertex2d(width, height); - glVertex2d(0, height); - glEnd(); + DependencyManager::get()->renderQuad(0, 0, width, height); } } - - -void renderCircle(glm::vec3 position, float radius, glm::vec3 surfaceNormal, int numSides) { - glm::vec3 perp1 = glm::vec3(surfaceNormal.y, surfaceNormal.z, surfaceNormal.x); - glm::vec3 perp2 = glm::vec3(surfaceNormal.z, surfaceNormal.x, surfaceNormal.y); - - glBegin(GL_LINE_STRIP); - - for (int i=0; irenderStats(WHITE_TEXT, glCanvas->width(), glCanvas->height()); - glBegin(GL_QUADS); if (isClipping) { glColor3f(1, 0, 0); } else { @@ -846,10 +845,7 @@ void ApplicationOverlay::renderAudioMeter() { glColor3f(0, 0, 0); // Draw audio meter background Quad - glVertex2i(AUDIO_METER_X, audioMeterY); - glVertex2i(AUDIO_METER_X + AUDIO_METER_WIDTH, audioMeterY); - glVertex2i(AUDIO_METER_X + AUDIO_METER_WIDTH, audioMeterY + AUDIO_METER_HEIGHT); - glVertex2i(AUDIO_METER_X, audioMeterY + AUDIO_METER_HEIGHT); + DependencyManager::get()->renderQuad(AUDIO_METER_X, audioMeterY, AUDIO_METER_WIDTH, AUDIO_METER_HEIGHT); if (audioLevel > AUDIO_RED_START) { if (!isClipping) { @@ -858,12 +854,16 @@ void ApplicationOverlay::renderAudioMeter() { glColor3f(1, 1, 1); } // Draw Red Quad - glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_RED_START, audioMeterY + AUDIO_METER_INSET); - glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_INSET); - glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET); - glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_RED_START, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET); + 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); + audioLevel = AUDIO_RED_START; } + + //glBegin(GL_QUADS); + if (audioLevel > AUDIO_GREEN_START) { if (!isClipping) { glColor3fv(AUDIO_METER_GREEN); @@ -871,10 +871,11 @@ void ApplicationOverlay::renderAudioMeter() { glColor3f(1, 1, 1); } // Draw Green Quad - glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_GREEN_START, audioMeterY + AUDIO_METER_INSET); - glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_INSET); - glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET); - glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_GREEN_START, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET); + 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); + audioLevel = AUDIO_GREEN_START; } // Draw Blue Quad @@ -884,11 +885,9 @@ void ApplicationOverlay::renderAudioMeter() { glColor3f(1, 1, 1); } // Draw Blue (low level) quad - glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET, audioMeterY + AUDIO_METER_INSET); - glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_INSET); - glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET); - glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET); - glEnd(); + DependencyManager::get()->renderQuad(AUDIO_METER_X + AUDIO_METER_INSET, + audioMeterY + AUDIO_METER_INSET, + audioLevel, AUDIO_METER_HEIGHT - AUDIO_METER_INSET); } void ApplicationOverlay::renderStatsAndLogs() { diff --git a/interface/src/ui/BandwidthMeter.cpp b/interface/src/ui/BandwidthMeter.cpp index a0a8129229..d28d85428d 100644 --- a/interface/src/ui/BandwidthMeter.cpp +++ b/interface/src/ui/BandwidthMeter.cpp @@ -11,6 +11,9 @@ #include +#include +#include + #include "BandwidthMeter.h" #include "InterfaceConfig.h" @@ -92,13 +95,7 @@ void BandwidthMeter::setColorRGBA(unsigned c) { } void BandwidthMeter::renderBox(int x, int y, int w, int h) { - - glBegin(GL_QUADS); - glVertex2i(x, y); - glVertex2i(x + w, y); - glVertex2i(x + w, y + h); - glVertex2i(x, y + h); - glEnd(); + DependencyManager::get()->renderQuad(x, y, w, h); } void BandwidthMeter::renderVerticalLine(int x, int y, int h) { diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index ab3927a3ab..eced2d87fd 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -154,16 +154,13 @@ void Stats::resetWidth(int width, int horizontalOffset) { // translucent background box that makes stats more readable void Stats::drawBackground(unsigned int rgba, int x, int y, int width, int height) { - glBegin(GL_QUADS); glColor4f(((rgba >> 24) & 0xff) / 255.0f, ((rgba >> 16) & 0xff) / 255.0f, ((rgba >> 8) & 0xff) / 255.0f, (rgba & 0xff) / 255.0f); - glVertex3f(x, y, 0); - glVertex3f(x + width, y, 0); - glVertex3f(x + width, y + height, 0); - glVertex3f(x , y + height, 0); - glEnd(); + + DependencyManager::get()->renderQuad(x, y, width, height); + glColor4f(1, 1, 1, 1); } diff --git a/interface/src/ui/overlays/TextOverlay.cpp b/interface/src/ui/overlays/TextOverlay.cpp index 03a5c3d846..ca83e1c595 100644 --- a/interface/src/ui/overlays/TextOverlay.cpp +++ b/interface/src/ui/overlays/TextOverlay.cpp @@ -12,6 +12,9 @@ #include "InterfaceConfig.h" #include + +#include +#include #include #include @@ -75,12 +78,9 @@ void TextOverlay::render(RenderArgs* args) { int top = _bounds.top(); int bottom = _bounds.bottom() + 1; - glBegin(GL_QUADS); - glVertex2f(left, top); - glVertex2f(right, top); - glVertex2f(right, bottom); - glVertex2f(left, bottom); - glEnd(); + glm::vec2 topLeft(left, top); + glm::vec2 bottomRight(right, bottom); + DependencyManager::get()->renderQuad(topLeft, bottomRight); // Same font properties as textSize() TextRenderer* textRenderer = TextRenderer::getInstance(SANS_FONT_FAMILY, _fontSize, DEFAULT_FONT_WEIGHT); diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 2837568ef5..65069b773f 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -661,6 +661,73 @@ void GeometryCache::renderWireCube(float size) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } +void GeometryCache::renderQuad(const glm::vec2& topLeft, const glm::vec2& bottomRight) { + Vec2Pair key(topLeft, bottomRight); + VerticesIndices& vbo = _quad2DVBOs[key]; + const int FLOATS_PER_VERTEX = 2; + const int vertices = 4; + const int indices = 4; + if (vbo.first == 0) { + int vertexPoints = vertices * FLOATS_PER_VERTEX; + GLfloat* vertexData = new GLfloat[vertexPoints]; // only vertices, no normals because we're a 2D quad + GLfloat* vertex = vertexData; + // index array of vertex array for glDrawRangeElement() as a GL_LINES for each edge + static GLubyte cannonicalIndices[indices] = { 0, 1, 2, 3 }; + + //glBegin(GL_QUADS); + // glVertex2f(left, top); + // glVertex2f(right, top); + // glVertex2f(right, bottom); + // glVertex2f(left, bottom); + //glEnd(); + + vertex[0] = topLeft.x; + vertex[1] = topLeft.y; + vertex[2] = bottomRight.x; + vertex[3] = topLeft.y; + vertex[4] = bottomRight.x; + vertex[5] = bottomRight.y; + vertex[6] = topLeft.x; + vertex[7] = bottomRight.y; + + 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; + + qDebug() << "new quad VBO made -- _quad2DVBOs.size():" << _quad2DVBOs.size(); + + } 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_QUADS, 0, vertices - 1, indices, GL_UNSIGNED_SHORT, 0); + glDisableClientState(GL_VERTEX_ARRAY); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +} + + +/* +void GeometryCache::renderQuad(cont glm::vec2& topLeft, cont glm::vec2& bottomRight, + cont glm::vec2& texCoordTopLeft, cont glm::vec2& texCoordBottomRight) { +} +*/ + QSharedPointer GeometryCache::getGeometry(const QUrl& url, const QUrl& fallback, bool delayLoad) { return getResource(url, fallback, delayLoad).staticCast(); diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index 514ee03c79..1c3f2114d6 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -31,6 +31,29 @@ class NetworkGeometry; class NetworkMesh; class NetworkTexture; + +typedef QPair Vec2Pair; +typedef QPair Vec2PairPair; + +inline uint qHash(const glm::vec2& v, uint seed) { + // multiply by prime numbers greater than the possible size + return qHash(v.x + 5009 * v.y, seed); +} + +inline uint qHash(const Vec2Pair& v, uint seed) { + // multiply by prime numbers greater than the possible size + return qHash(v.first.x + 5009 * v.first.y + 5011 * v.second.x + 5021 * v.second.y, seed); +} + +inline uint qHash(const Vec2PairPair& v, uint seed) { + // multiply by prime numbers greater than the possible size + return qHash(v.first.first.x + 5009 * v.first.first.y + + 5011 * v.first.second.x + 5021 * v.first.second.y + + 5023 * v.second.first.x + 5039 * v.second.first.y + + 5051 * v.second.second.x + 5059 * v.second.second.y, seed); +} + + /// Stores cached geometry. class GeometryCache : public ResourceCache { Q_OBJECT @@ -46,6 +69,16 @@ public: void renderSolidCube(float size); void renderWireCube(float size); + + 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(const glm::vec2& topLeft, const glm::vec2& bottomRight, + const glm::vec2& texCoordTopLeft, const glm::vec2& texCoordBottomRight); + + /// Loads geometry from the specified URL. /// \param fallback a fallback URL to load if the desired one is unavailable /// \param delayLoad if true, don't load the geometry immediately; wait until load is first requested @@ -70,6 +103,9 @@ private: QHash _coneVBOs; QHash _wireCubeVBOs; QHash _solidCubeVBOs; + QHash _quad2DVBOs; + //QHash _quad2DTextureVBOs; + QHash _gridBuffers; QHash > _networkGeometry; diff --git a/libraries/render-utils/src/TextRenderer.cpp b/libraries/render-utils/src/TextRenderer.cpp index 34098c6862..2c677a330a 100644 --- a/libraries/render-utils/src/TextRenderer.cpp +++ b/libraries/render-utils/src/TextRenderer.cpp @@ -81,9 +81,6 @@ int TextRenderer::draw(int x, int y, const char* str, float alpha) { ((int(currentColor[2] * 255.0f) & 0xFF) << 16) | ((int(currentColor[3] * 255.0f) & 0xFF) << 24); -// TODO: Remove that code once we test for performance improvments - //glEnable(GL_TEXTURE_2D); - int maxHeight = 0; for (const char* ch = str; *ch != 0; ch++) { const Glyph& glyph = getGlyph(*ch); @@ -111,20 +108,6 @@ int TextRenderer::draw(int x, int y, const char* str, float alpha) { float bt = glyph.location().y() * scale; float tt = (glyph.location().y() + glyph.bounds().height()) * scale; -// TODO: Remove that code once we test for performance improvments -/* - glBegin(GL_QUADS); - glTexCoord2f(ls, bt); - glVertex2f(left, bottom); - glTexCoord2f(rs, bt); - glVertex2f(right, bottom); - glTexCoord2f(rs, tt); - glVertex2f(right, top); - glTexCoord2f(ls, tt); - glVertex2f(left, top); - glEnd(); -*/ - const int NUM_COORDS_SCALARS_PER_GLYPH = 16; float vertexBuffer[NUM_COORDS_SCALARS_PER_GLYPH] = { leftBottom.x, leftBottom.y, ls, bt, rightTop.x, leftBottom.y, rs, bt, @@ -152,10 +135,6 @@ int TextRenderer::draw(int x, int y, const char* str, float alpha) { drawBatch(); clearBatch(); -// TODO: Remove that code once we test for performance improvments - // glBindTexture(GL_TEXTURE_2D, 0); - // glDisable(GL_TEXTURE_2D); - return maxHeight; }