diff --git a/interface/resources/shaders/point_size.vert b/interface/resources/shaders/point_size.vert new file mode 100644 index 0000000000..98da0b85d6 --- /dev/null +++ b/interface/resources/shaders/point_size.vert @@ -0,0 +1,32 @@ +#version 120 + +attribute float voxelSizeIn; +varying float voxelSize; +uniform float viewportWidth; +uniform float viewportHeight; + +void main(void) { + gl_FrontColor = gl_Color; + vec4 cornerOriginal = gl_Vertex; + vec4 corner = gl_ModelViewProjectionMatrix * gl_Vertex; + + vec4 farCornerVertex = gl_Vertex; + farCornerVertex[0] += voxelSizeIn; + farCornerVertex[1] += voxelSizeIn; + farCornerVertex[2] += voxelSizeIn; + vec4 farCorner = gl_ModelViewProjectionMatrix * farCornerVertex; + + float voxelScreenWidth = abs((farCorner.x / farCorner.w) - (corner.x / corner.w)) * viewportWidth / 2.0; + float voxelScreenHeight = abs((farCorner.y / farCorner.w) - (corner.y / corner.w)) * viewportHeight / 2.0; + float voxelScreenLength = sqrt(voxelScreenHeight * voxelScreenHeight + voxelScreenWidth * voxelScreenWidth); + + vec4 centerVertex = gl_Vertex; + float halfSizeIn = voxelSizeIn / 2; + centerVertex[0] += halfSizeIn; + centerVertex[1] += halfSizeIn; + centerVertex[2] += halfSizeIn; + vec4 center = gl_ModelViewProjectionMatrix * centerVertex; + + gl_Position = center; + gl_PointSize = voxelScreenLength; +} \ No newline at end of file diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d1d48a15e2..82fccf7d6d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1665,6 +1665,7 @@ void Application::init() { _glowEffect.init(); _ambientOcclusionEffect.init(); _voxelShader.init(); + _pointShader.init(); _handControl.setScreenDimensions(_glWidget->width(), _glWidget->height()); diff --git a/interface/src/Application.h b/interface/src/Application.h index f888442dbd..226756ab0f 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -55,12 +55,12 @@ #include "renderer/GeometryCache.h" #include "renderer/GlowEffect.h" #include "renderer/VoxelShader.h" +#include "renderer/PointShader.h" #include "renderer/TextureCache.h" #include "ui/BandwidthDialog.h" #include "ui/ChatEntry.h" #include "ui/VoxelStatsDialog.h" #include "ui/RearMirrorTools.h" -#include "ui/LodToolsDialog.h" class QAction; class QActionGroup; @@ -162,6 +162,9 @@ public: virtual void domainChanged(QString domain); VoxelShader& getVoxelShader() { return _voxelShader; } + PointShader& getPointShader() { return _pointShader; } + + glm::vec2 getViewportDimensions() const{ return glm::vec2(_glWidget->width(),_glWidget->height()); } public slots: void sendAvatarFaceVideoMessage(int frameCount, const QByteArray& data); @@ -383,6 +386,7 @@ private: GlowEffect _glowEffect; AmbientOcclusionEffect _ambientOcclusionEffect; VoxelShader _voxelShader; + PointShader _pointShader; #ifndef _WIN32 Audio _audio; diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index a1f83007fd..ac207e8812 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -29,6 +29,7 @@ #include "Menu.h" #include "Util.h" #include "InfoView.h" +#include "ui/LodToolsDialog.h" Menu* Menu::_instance = NULL; diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 9e2c6ec63e..5c836eb3e2 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -1257,13 +1257,28 @@ void VoxelSystem::render(bool texture) { if (!_voxelsAsPoints) { Application::getInstance()->getVoxelShader().begin(); - attributeLocation = Application::getInstance()->getVoxelShader().attributeLocation("voxelSizeIn"); glEnableVertexAttribArray(attributeLocation); glVertexAttribPointer(attributeLocation, 1, GL_FLOAT, false, sizeof(VoxelShaderVBOData), BUFFER_OFFSET(3*sizeof(float))); } else { - const float POINT_SIZE = 4.0; - glPointSize(POINT_SIZE); + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); + + glm::vec2 viewDimensions = Application::getInstance()->getViewportDimensions(); + float viewportWidth = viewDimensions.x; + float viewportHeight = viewDimensions.y; + + Application::getInstance()->getPointShader().begin(); + + int uniformLocation = Application::getInstance()->getPointShader().uniformLocation("viewportWidth"); + Application::getInstance()->getPointShader().setUniformValue(uniformLocation, viewportWidth); + + uniformLocation = Application::getInstance()->getPointShader().uniformLocation("viewportHeight"); + Application::getInstance()->getPointShader().setUniformValue(uniformLocation, viewportHeight); + + attributeLocation = Application::getInstance()->getVoxelShader().attributeLocation("voxelSizeIn"); + //printf("attributeLocation=%d\n", attributeLocation); + glEnableVertexAttribArray(attributeLocation); + glVertexAttribPointer(attributeLocation, 1, GL_FLOAT, false, sizeof(VoxelShaderVBOData), BUFFER_OFFSET(3*sizeof(float))); } @@ -1287,6 +1302,10 @@ void VoxelSystem::render(bool texture) { if (!_voxelsAsPoints) { Application::getInstance()->getVoxelShader().end(); glDisableVertexAttribArray(attributeLocation); + } else { + Application::getInstance()->getPointShader().end(); + glDisableVertexAttribArray(attributeLocation); + glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); } } else { PerformanceWarning warn(showWarnings, "render().. TRIANGLES..."); diff --git a/interface/src/renderer/PointShader.cpp b/interface/src/renderer/PointShader.cpp new file mode 100644 index 0000000000..8ebccc8d08 --- /dev/null +++ b/interface/src/renderer/PointShader.cpp @@ -0,0 +1,73 @@ +// +// PointShader.cpp +// interface +// +// Created by Brad Hefta-Gaub on 9/22/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. + +// include this before QOpenGLFramebufferObject, which includes an earlier version of OpenGL +#include "InterfaceConfig.h" + +#include + +#include "Application.h" +#include "PointShader.h" +#include "ProgramObject.h" +#include "RenderUtil.h" + +PointShader::PointShader() + : _initialized(false) +{ + _program = NULL; +} + +PointShader::~PointShader() { + if (_initialized) { + delete _program; + } +} + +ProgramObject* PointShader::createPointShaderProgram(const QString& name) { + ProgramObject* program = new ProgramObject(); + program->addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/" + name + ".vert" ); + program->link(); + return program; +} + +void PointShader::init() { + if (_initialized) { + qDebug("[ERROR] PointShader is already initialized.\n"); + return; + } + switchToResourcesParentIfRequired(); + _program = createPointShaderProgram("point_size"); + _initialized = true; +} + +void PointShader::begin() { + _program->bind(); +} + +void PointShader::end() { + _program->release(); +} + +int PointShader::attributeLocation(const char * name) const { + if (_program) { + return _program->attributeLocation(name); + } else { + return -1; + } +} + +int PointShader::uniformLocation(const char * name) const { + if (_program) { + return _program->uniformLocation(name); + } else { + return -1; + } +} + +void PointShader::setUniformValue(int attributeLocation, float value) { + _program->setUniformValue(attributeLocation, value); +} diff --git a/interface/src/renderer/PointShader.h b/interface/src/renderer/PointShader.h new file mode 100644 index 0000000000..f5ef54af5e --- /dev/null +++ b/interface/src/renderer/PointShader.h @@ -0,0 +1,48 @@ +// +// PointShader.h +// interface +// +// Created by Brad Hefta-Gaub on 9/23/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#ifndef __interface__PointShader__ +#define __interface__PointShader__ + +#include + +class ProgramObject; + +/// A generic full screen glow effect. +class PointShader : public QObject { + Q_OBJECT + +public: + PointShader(); + ~PointShader(); + + void init(); + + /// Starts using the voxel geometry shader effect. + void begin(); + + /// Stops using the voxel geometry shader effect. + void end(); + + /// Gets access to attributes from the shader program + int attributeLocation(const char * name) const; + int uniformLocation(const char * name) const; + void setUniformValue(int attributeLocation, float value); + + static ProgramObject* createPointShaderProgram(const QString& name); + +public slots: + +private: + + bool _initialized; + + ProgramObject* _program; +}; + +#endif /* defined(__interface__PointShader__) */