From 398075e45aa32775988e671857f012b518fa08da Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 16 Jul 2015 16:26:28 -0700 Subject: [PATCH] hacking on more naked GL --- interface/src/Application.cpp | 5 + interface/src/Application.h | 3 - interface/src/audio/AudioScope.cpp | 4 +- interface/src/audio/AudioScope.h | 1 + interface/src/ui/ApplicationCompositor.cpp | 31 ++-- interface/src/ui/ApplicationOverlay.cpp | 180 +++++++++++++------ interface/src/ui/ApplicationOverlay.h | 9 +- interface/src/ui/overlays/Overlays.cpp | 17 +- libraries/render-utils/src/GeometryCache.cpp | 2 + 9 files changed, 185 insertions(+), 67 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 056490806a..71eabd2d6d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -895,6 +895,11 @@ void Application::paintGL() { { PerformanceTimer perfTimer("renderOverlay"); + + // NOTE: the ApplicationOverlay class assumes it's viewport is setup to be the device size + // There is no batch associated with this renderArgs + QSize size = qApp->getDeviceSize(); + renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height()); _applicationOverlay.renderOverlay(&renderArgs); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 44ead54563..d2a55fbf70 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -359,9 +359,6 @@ signals: /// Fired when we're rendering in-world interface elements; allows external parties to hook in. void renderingInWorldInterface(); - /// Fired when we're rendering the overlay. - void renderingOverlay(); - /// Fired when the import window is closed void importDone(); diff --git a/interface/src/audio/AudioScope.cpp b/interface/src/audio/AudioScope.cpp index 4b4e86e7f4..d9ceb82eef 100644 --- a/interface/src/audio/AudioScope.cpp +++ b/interface/src/audio/AudioScope.cpp @@ -38,6 +38,7 @@ AudioScope::AudioScope() : _scopeOutputLeft(NULL), _scopeOutputRight(NULL), _scopeLastFrame(), + _audioScopeBackground(DependencyManager::get()->allocateID()), _audioScopeGrid(DependencyManager::get()->allocateID()), _inputID(DependencyManager::get()->allocateID()), _outputLeftID(DependencyManager::get()->allocateID()), @@ -135,7 +136,8 @@ void AudioScope::render(RenderArgs* renderArgs, int width, int height) { batch.setProjectionTransform(legacyProjection); batch.setModelTransform(Transform()); batch.setViewTransform(Transform()); - geometryCache->renderQuad(batch, x, y, w, h, backgroundColor); + batch._glLineWidth(1.0f); // default + geometryCache->renderQuad(batch, x, y, w, h, backgroundColor, _audioScopeBackground); geometryCache->renderGrid(batch, x, y, w, h, gridRows, gridCols, gridColor, _audioScopeGrid); renderLineStrip(batch, _inputID, inputColor, x, y, _samplesPerScope, _scopeInputOffset, _scopeInput); renderLineStrip(batch, _outputLeftID, outputLeftColor, x, y, _samplesPerScope, _scopeOutputOffset, _scopeOutputLeft); diff --git a/interface/src/audio/AudioScope.h b/interface/src/audio/AudioScope.h index 4ff4b55c29..0b716d7666 100644 --- a/interface/src/audio/AudioScope.h +++ b/interface/src/audio/AudioScope.h @@ -69,6 +69,7 @@ private: QByteArray* _scopeOutputRight; QByteArray _scopeLastFrame; + int _audioScopeBackground; int _audioScopeGrid; int _inputID; int _outputLeftID; diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index 4623109cdd..56735111c1 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -189,8 +189,9 @@ void ApplicationCompositor::displayOverlayTexture(RenderArgs* renderArgs) { return; } - GLuint texture = qApp->getApplicationOverlay().getOverlayTexture(); - if (!texture) { + //GLuint texture = 0; // FIXME -- qApp->getApplicationOverlay().getOverlayTexture(); + gpu::FramebufferPointer overlayFramebuffer = qApp->getApplicationOverlay().getOverlayFramebuffer(); + if (!overlayFramebuffer) { return; } @@ -209,9 +210,12 @@ void ApplicationCompositor::displayOverlayTexture(RenderArgs* renderArgs) { batch.setModelTransform(Transform()); batch.setViewTransform(Transform()); batch.setProjectionTransform(mat4()); - batch._glBindTexture(GL_TEXTURE_2D, texture); - batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + //batch._glBindTexture(GL_TEXTURE_2D, texture); + //batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + //batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + batch.setResourceTexture(0, overlayFramebuffer->getRenderBuffer(0)); + geometryCache->renderUnitQuad(batch, vec4(vec3(1), _alpha)); // Doesn't actually render @@ -258,8 +262,12 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int return; } - GLuint texture = qApp->getApplicationOverlay().getOverlayTexture(); - if (!texture) { + //GLuint texture = 0; // FIXME -- qApp->getApplicationOverlay().getOverlayTexture(); + //if (!texture) { + // return; + //} + gpu::FramebufferPointer overlayFramebuffer = qApp->getApplicationOverlay().getOverlayFramebuffer(); + if (!overlayFramebuffer) { return; } @@ -275,9 +283,12 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int geometryCache->useSimpleDrawPipeline(batch); batch._glDisable(GL_DEPTH_TEST); batch._glDisable(GL_CULL_FACE); - batch._glBindTexture(GL_TEXTURE_2D, texture); - batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + //batch._glBindTexture(GL_TEXTURE_2D, texture); + //batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + //batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + batch.setResourceTexture(0, overlayFramebuffer->getRenderBuffer(0)); + batch.setViewTransform(Transform()); batch.setProjectionTransform(qApp->getEyeProjection(eye)); diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 63dcba9d5d..f89867c70d 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -40,12 +40,6 @@ const float CONNECTION_STATUS_BORDER_LINE_WIDTH = 4.0f; static const float ORTHO_NEAR_CLIP = -10000; static const float ORTHO_FAR_CLIP = 10000; -// TODO move somewhere useful -static void fboViewport(QOpenGLFramebufferObject* fbo) { - auto size = fbo->size(); - glViewport(0, 0, size.width(), size.height()); -} - ApplicationOverlay::ApplicationOverlay() { auto geometryCache = DependencyManager::get(); @@ -84,16 +78,41 @@ void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) { buildFramebufferObject(); // Execute the batch into our framebuffer - _overlayFramebuffer->bind(); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - fboViewport(_overlayFramebuffer); + + gpu::Batch batch; + + // 1) bind the framebuffer + //_overlayFramebuffer->bind(); + batch.setFramebuffer(_overlayFramebuffer); + + // 2) clear it... + //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glm::vec4 color { 0.0f, 0.0f, 0.0f, 0.0f }; + float depth = 1.0f; + int stencil = 0; + //batch.clearFramebuffer(gpu::Framebuffer::BUFFER_COLORS | gpu::Framebuffer::BUFFER_DEPTH, color, depth, stencil); + batch.clearColorFramebuffer(_overlayFramebuffer->getBufferMask(), glm::vec4(0.0f, 0.0f, 0.0f, 0.0f)); + + int width = _overlayFramebuffer ? _overlayFramebuffer->getWidth() : 0; + int height = _overlayFramebuffer ? _overlayFramebuffer->getHeight() : 0; + + glViewport(0, 0, width, height); + + qDebug() << "ApplicationOverlay::renderOverlay()... "; + qDebug() << " renderArgs->batch:" << (void*)renderArgs->_batch; + qDebug() << " renderArgs->_viewport:" << renderArgs->_viewport.z << "," << renderArgs->_viewport.w; + qDebug() << " getDeviceSize:" << qApp->getDeviceSize(); + qDebug() << " getCanvasSize:" << qApp->getCanvasSize(); + qDebug() << " _overlayFramebuffer size:" << width << "," << height; // Now render the overlay components together into a single texture - renderOverlays(renderArgs); - renderStatsAndLogs(renderArgs); - renderDomainConnectionStatusBorder(renderArgs); - renderQmlUi(renderArgs); - _overlayFramebuffer->release(); + renderOverlays(renderArgs); // renders Scripts Overlay and AudioScope + renderStatsAndLogs(renderArgs); // currently renders nothing + renderDomainConnectionStatusBorder(renderArgs); // renders the connected domain line + renderQmlUi(renderArgs); // renders a unit quad with the QML UI texture + + //_overlayFramebuffer->release(); // now we're done for later composition + batch.setFramebuffer(nullptr); CHECK_GL_ERROR(); } @@ -102,11 +121,15 @@ void ApplicationOverlay::renderQmlUi(RenderArgs* renderArgs) { if (_uiTexture) { gpu::Batch batch; auto geometryCache = DependencyManager::get(); + geometryCache->useSimpleDrawPipeline(batch); batch.setProjectionTransform(mat4()); - batch.setModelTransform(mat4()); + batch.setModelTransform(Transform()); + batch.setViewTransform(Transform()); batch._glBindTexture(GL_TEXTURE_2D, _uiTexture); + geometryCache->renderUnitQuad(batch, glm::vec4(1)); + renderArgs->_context->syncCache(); renderArgs->_context->render(batch); } @@ -114,31 +137,34 @@ void ApplicationOverlay::renderQmlUi(RenderArgs* renderArgs) { void ApplicationOverlay::renderOverlays(RenderArgs* renderArgs) { PROFILE_RANGE(__FUNCTION__); - glm::vec2 size = qApp->getCanvasSize(); - mat4 legacyProjection = glm::ortho(0, size.x, size.y, 0, ORTHO_NEAR_CLIP, ORTHO_FAR_CLIP); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadMatrixf(glm::value_ptr(legacyProjection)); - glMatrixMode(GL_MODELVIEW); - - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glUseProgram(0); - - // give external parties a change to hook in - emit qApp->renderingOverlay(); - qApp->getOverlays().renderHUD(renderArgs); - - DependencyManager::get()->render(renderArgs, _overlayFramebuffer->size().width(), _overlayFramebuffer->size().height()); - - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - - fboViewport(_overlayFramebuffer); + gpu::Batch batch; + auto geometryCache = DependencyManager::get(); + geometryCache->useSimpleDrawPipeline(batch); + auto textureCache = DependencyManager::get(); + batch.setResourceTexture(0, textureCache->getWhiteTexture()); + int width = renderArgs->_viewport.z; + int height = renderArgs->_viewport.w; + mat4 legacyProjection = glm::ortho(0, width, height, 0, -1000, 1000); + batch.setProjectionTransform(legacyProjection); + batch.setModelTransform(Transform()); + batch.setViewTransform(Transform()); + batch._glLineWidth(1.0f); // default + + { + // Render all of the Script based "HUD" aka 2D overlays. + // note: we call them HUD, as opposed to 2D, only because there are some cases of 3D HUD overlays, like the + // cameral controls for the edit.js + qApp->getOverlays().renderHUD(renderArgs); + + // Render the audio scope + int width = _overlayFramebuffer ? _overlayFramebuffer->getWidth() : 0; + int height = _overlayFramebuffer ? _overlayFramebuffer->getHeight() : 0; + DependencyManager::get()->render(renderArgs, width, height); + } + + renderArgs->_context->syncCache(); + renderArgs->_context->render(batch); } void ApplicationOverlay::renderRearViewToFbo(RenderArgs* renderArgs) { @@ -202,32 +228,86 @@ void ApplicationOverlay::renderDomainConnectionStatusBorder(RenderArgs* renderAr } } -GLuint ApplicationOverlay::getOverlayTexture() { - if (!_overlayFramebuffer) { - return 0; - } - return _overlayFramebuffer->texture(); -} - void ApplicationOverlay::buildFramebufferObject() { PROFILE_RANGE(__FUNCTION__); - QSize fboSize = qApp->getDeviceSize(); - if (_overlayFramebuffer && fboSize == _overlayFramebuffer->size()) { + + QSize desiredSize = qApp->getDeviceSize(); + int currentWidth = _overlayFramebuffer ? _overlayFramebuffer->getWidth() : 0; + int currentHeight = _overlayFramebuffer ? _overlayFramebuffer->getHeight() : 0; + QSize frameBufferCurrentSize(currentWidth, currentHeight); + + if (_overlayFramebuffer && desiredSize == frameBufferCurrentSize) { // Already built return; } if (_overlayFramebuffer) { - delete _overlayFramebuffer; + _overlayFramebuffer.reset(); + _overlayDepthTexture.reset(); + _overlayColorTexture.reset(); } + + _overlayFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); + + auto colorFormat = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); + auto width = desiredSize.width(); + auto height = desiredSize.height(); + + auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT); + _overlayColorTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler)); + _overlayFramebuffer->setRenderBuffer(0, _overlayColorTexture); + + + auto depthFormat = gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH); + _overlayDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, width, height, defaultSampler)); + + _overlayFramebuffer->setDepthStencilBuffer(_overlayDepthTexture, depthFormat); + + + /* + // This code essentially created a frame buffer, then sets a bunch of the parameters for that texture. _overlayFramebuffer = new QOpenGLFramebufferObject(fboSize, QOpenGLFramebufferObject::Depth); + + GLfloat borderColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + + gpu::Batch batch; + batch._glBindTexture(GL_TEXTURE_2D, getOverlayTexture()); + batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + batch._glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); + batch._glBindTexture(GL_TEXTURE_2D, 0); + */ + + /* glBindTexture(GL_TEXTURE_2D, getOverlayTexture()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - GLfloat borderColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); glBindTexture(GL_TEXTURE_2D, 0); + */ + + + + /**** Example code... + batch._glBindTexture(GL_TEXTURE_2D, texture); + batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + + // this stuff is what would actually render from the texture + + geometryCache->useSimpleDrawPipeline(batch); + batch.setViewportTransform(glm::ivec4(0, 0, deviceSize.width(), deviceSize.height())); + batch.setModelTransform(Transform()); + batch.setViewTransform(Transform()); + batch.setProjectionTransform(mat4()); + batch._glBindTexture(GL_TEXTURE_2D, texture); + geometryCache->renderUnitQuad(batch, vec4(vec3(1), _alpha)); + ****/ + } diff --git a/interface/src/ui/ApplicationOverlay.h b/interface/src/ui/ApplicationOverlay.h index 2f434ed7e1..0bbe4e3f77 100644 --- a/interface/src/ui/ApplicationOverlay.h +++ b/interface/src/ui/ApplicationOverlay.h @@ -25,7 +25,8 @@ public: ~ApplicationOverlay(); void renderOverlay(RenderArgs* renderArgs); - GLuint getOverlayTexture(); + + gpu::FramebufferPointer getOverlayFramebuffer() const { return _overlayFramebuffer; } private: void renderStatsAndLogs(RenderArgs* renderArgs); @@ -44,7 +45,11 @@ private: int _magnifierBorder; ivec2 _previousBorderSize{ -1 }; - QOpenGLFramebufferObject* _overlayFramebuffer{ nullptr }; + + gpu::TexturePointer _overlayDepthTexture; + gpu::TexturePointer _overlayColorTexture; + gpu::FramebufferPointer _overlayFramebuffer; + }; #endif // hifi_ApplicationOverlay_h diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index e4401b32ef..8a1aa1014e 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -100,9 +100,24 @@ void Overlays::renderHUD(RenderArgs* renderArgs) { QReadLocker lock(&_lock); gpu::Batch batch; renderArgs->_batch = &batch; - + + auto geometryCache = DependencyManager::get(); + auto textureCache = DependencyManager::get(); + int width = renderArgs->_viewport.z; + int height = renderArgs->_viewport.w; + mat4 legacyProjection = glm::ortho(0, width, height, 0, -1000, 1000); + foreach(Overlay::Pointer thisOverlay, _overlaysHUD) { + + // Reset all batch pipeline settings between overlay + geometryCache->useSimpleDrawPipeline(batch); + batch.setResourceTexture(0, textureCache->getWhiteTexture()); + batch.setProjectionTransform(legacyProjection); + batch.setModelTransform(Transform()); + batch.setViewTransform(Transform()); + batch._glLineWidth(1.0f); // default + thisOverlay->render(renderArgs); } diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 2bf41bc9b3..7cb882acc1 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -433,6 +433,8 @@ void GeometryCache::renderGrid(gpu::Batch& batch, int x, int y, int width, int h } // Draw vertical grid lines for (int i = cols + 1; --i >= 0; ) { + //glVertex2i(tx, y); + //glVertex2i(tx, y + height); *(vertex++) = tx; *(vertex++) = y;