From 3d4341cee4f516da745a5e63e3c761c8b4cc4c6a Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 23 Sep 2013 15:18:45 -0700 Subject: [PATCH 01/11] hacking on voxel geometry shader --- .../resources/shaders/duplicate_geometry.geom | 46 ++++++ interface/resources/shaders/passthrough.geom | 150 ++++++++++++++++++ interface/resources/shaders/passthrough.vert | 6 + interface/src/Application.cpp | 4 + interface/src/Application.h | 2 + interface/src/renderer/TestGeometry.cpp | 65 ++++++++ interface/src/renderer/TestGeometry.h | 44 +++++ libraries/voxels/src/VoxelConstants.h | 6 +- 8 files changed, 320 insertions(+), 3 deletions(-) create mode 100644 interface/resources/shaders/duplicate_geometry.geom create mode 100644 interface/resources/shaders/passthrough.geom create mode 100644 interface/resources/shaders/passthrough.vert create mode 100644 interface/src/renderer/TestGeometry.cpp create mode 100644 interface/src/renderer/TestGeometry.h diff --git a/interface/resources/shaders/duplicate_geometry.geom b/interface/resources/shaders/duplicate_geometry.geom new file mode 100644 index 0000000000..2ab92fc4e3 --- /dev/null +++ b/interface/resources/shaders/duplicate_geometry.geom @@ -0,0 +1,46 @@ +#version 420 + +layout(triangles) in; +layout (triangle_strip, max_vertices=6) out; + +layout (std140) uniform Matrices { + mat4 projModelViewMatrix; + mat3 normalMatrix; +}; + +in VertexData { + vec2 texCoord; + vec3 normal; +} VertexIn[]; + +out VertexData { + vec2 texCoord; + vec3 normal; +} VertexOut; + +void main() +{ + for(int i = 0; i < gl_in.length(); i++) + { + // copy attributes + gl_Position = projModelViewMatrix * gl_in[i].gl_Position; + VertexOut.normal = normalize(normalMatrix * VertexIn[i].normal); + VertexOut.texCoord = VertexIn[i].texCoord; + + // done with the vertex + EmitVertex(); + } + EndPrimitive(); + + for(int i = 0; i < gl_in.length(); i++) + { + // copy attributes and displace copy + gl_Position = projModelViewMatrix * (gl_in[i].gl_Position + vec4(20.0, 0.0, 0.0, 0.0)); + VertexOut.normal = normalize(normalMatrix * VertexIn[i].normal); + VertexOut.texCoord = VertexIn[i].texCoord; + + // done with the vertex + EmitVertex(); + } + EndPrimitive(); +} diff --git a/interface/resources/shaders/passthrough.geom b/interface/resources/shaders/passthrough.geom new file mode 100644 index 0000000000..1ce193cda9 --- /dev/null +++ b/interface/resources/shaders/passthrough.geom @@ -0,0 +1,150 @@ +#version 120 +#extension GL_ARB_geometry_shader4 : enable + +// use GL_POINTS +// have point be the corner of voxel +// have a second dataset (? similar to how voxel avatars pass in bones??) +// which is the voxel size? +// +// In vertex shader DON'T transform.. therefor passing the world coordinate xyz to geometric shader +// In geometric shader calculate xyz for triangles the same way we currently do triangles outside of OpenGL +// do transform on these triangles +// gl_Position = gl_ModelViewProjectionMatrix * cube_coord; +// +// output GL_TRIANGLE_STRIP +// +// NOTE: updateNodeInArrays() does the covert from voxel corner to 12 triangles or 36 points or 36*3 floats +// but since it operates on the array of floats, it is kinda weird and hard to follow. The %3 is for the +// xyz.. and identityVertices[j] term in the math is actually a string of floats but they should be thought +// of as triplets of x,y,z +// +// do we need to add the light to these colors?? +// + +//GEOMETRY SHADER +/////////////////////// +void main() +{ + //increment variable + int i; + vec4 vertex; + vec4 color,red,green,blue; + + green = vec4(0,1.0,0,1.0); + red = vec4(1.0,0,0,1.0); + blue = vec4(0,0,1.0,1.0); + + ///////////////////////////////////////////////////////////// + //This example has two parts + // step a) draw the primitive pushed down the pipeline + // there are gl_VerticesIn # of vertices + // put the vertex value into gl_Position + // use EmitVertex => 'create' a new vertex + // use EndPrimitive to signal that you are done creating a primitive! + // step b) create a new piece of geometry + // I just do the same loop, but I negate the vertex.z + // result => the primitive is now mirrored. + //Pass-thru! + for(i = 0; i < gl_VerticesIn; i++) { + color = gl_FrontColorIn[i]; + gl_FrontColor = color; // + gl_Position = gl_ModelViewProjectionMatrix * gl_PositionIn[i]; + EmitVertex(); + } + EndPrimitive(); + + for(i = 0; i < gl_VerticesIn; i++) { + gl_FrontColor = red; // + vertex = gl_PositionIn[i]; + vertex.y += 0.05f; + gl_Position = gl_ModelViewProjectionMatrix * vertex; + EmitVertex(); + } + EndPrimitive(); + + for(i = 0; i < gl_VerticesIn; i++) { + gl_FrontColor = green; // + vertex = gl_PositionIn[i]; + vertex.x += 0.05f; + gl_Position = gl_ModelViewProjectionMatrix * vertex; + EmitVertex(); + } + EndPrimitive(); + + for(i = 0; i < gl_VerticesIn; i++) { + gl_FrontColor = blue; // + vertex = gl_PositionIn[i]; + vertex.z += 0.05f; + gl_Position = gl_ModelViewProjectionMatrix * vertex; + EmitVertex(); + } + EndPrimitive(); + +/** + + for(i = 0; i < gl_VerticesIn; i++) { + green = vec4(0,1.0,0,1.0); + red = vec4(1.0,0,0,1.0); + //gl_FrontColor = gl_FrontColorIn[i]; + gl_FrontColor = red; + + // v -> v+x -> v+x+y + vertex = gl_PositionIn[i]; + gl_Position = vertex; + EmitVertex(); + vertex.x += 0.1f; + gl_Position = vertex; + EmitVertex(); + vertex.y += 0.1f; + gl_Position = vertex; + EmitVertex(); + EndPrimitive(); + + // v+x+y -> v+y -> v + vertex = gl_PositionIn[i]; + vertex.x += 0.1f; + vertex.y += 0.1f; + gl_Position = vertex; + EmitVertex(); + vertex.x -= 0.1f; + gl_Position = vertex; + EmitVertex(); + vertex.y -= 0.1f; + gl_Position = vertex; + EmitVertex(); + EndPrimitive(); + // v+z -> v+z+x -> v+z+x+y + gl_FrontColor = green; + vertex = gl_PositionIn[i]; + vertex.z -= 0.1f; + gl_Position = vertex; + EmitVertex(); + + vertex.x += 0.1f; + gl_Position = vertex; + EmitVertex(); + vertex.y += 0.1f; + gl_Position = vertex; + EmitVertex(); + EndPrimitive(); + + // v+z+x+y -> v+z+y -> v+z + vertex = gl_PositionIn[i]; + vertex.z -= 0.1f; + vertex.x += 0.1f; + vertex.y += 0.1f; + gl_Position = vertex; + EmitVertex(); + vertex.x -= 0.1f; + gl_Position = vertex; + EmitVertex(); + vertex.y -= 0.1f; + gl_Position = vertex; + EmitVertex(); + EndPrimitive(); + + } +**/ + + +} \ No newline at end of file diff --git a/interface/resources/shaders/passthrough.vert b/interface/resources/shaders/passthrough.vert new file mode 100644 index 0000000000..a3a6219b6a --- /dev/null +++ b/interface/resources/shaders/passthrough.vert @@ -0,0 +1,6 @@ +#version 120 + +void main(void) { + gl_FrontColor = gl_Color; //vec4(1.0, 0.0, 0.0, 1.0); + gl_Position = gl_Vertex;// ftransform(); +} \ No newline at end of file diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d90c82e6ca..503f8f434e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -389,6 +389,7 @@ void Application::paintGL() { } else { _glowEffect.prepare(); + glMatrixMode(GL_MODELVIEW); glPushMatrix(); @@ -1539,6 +1540,7 @@ void Application::init() { _glowEffect.init(); _ambientOcclusionEffect.init(); + _testGeometry.init(); _handControl.setScreenDimensions(_glWidget->width(), _glWidget->height()); @@ -2579,7 +2581,9 @@ void Application::displaySide(Camera& whichCamera) { // brad's frustum for debugging if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayFrustum)) { + _testGeometry.begin(); renderViewFrustum(_viewFrustum); + _testGeometry.end(); } // render voxel fades if they exist diff --git a/interface/src/Application.h b/interface/src/Application.h index e951afc735..690dbc154c 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -51,6 +51,7 @@ #include "renderer/AmbientOcclusionEffect.h" #include "renderer/GeometryCache.h" #include "renderer/GlowEffect.h" +#include "renderer/TestGeometry.h" #include "renderer/TextureCache.h" #include "ui/BandwidthDialog.h" #include "ui/ChatEntry.h" @@ -342,6 +343,7 @@ private: GlowEffect _glowEffect; AmbientOcclusionEffect _ambientOcclusionEffect; + TestGeometry _testGeometry; #ifndef _WIN32 Audio _audio; diff --git a/interface/src/renderer/TestGeometry.cpp b/interface/src/renderer/TestGeometry.cpp new file mode 100644 index 0000000000..e30a210dde --- /dev/null +++ b/interface/src/renderer/TestGeometry.cpp @@ -0,0 +1,65 @@ +// +// TestGeometry.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 "TestGeometry.h" +#include "ProgramObject.h" +#include "RenderUtil.h" + +TestGeometry::TestGeometry() + : _initialized(false) +{ +} + +TestGeometry::~TestGeometry() { + if (_initialized) { + delete _testProgram; + } +} + +static ProgramObject* createGeometryShaderProgram(const QString& name) { + ProgramObject* program = new ProgramObject(); + program->addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/passthrough.vert" ); + + + program->addShaderFromSourceFile(QGLShader::Geometry, "resources/shaders/" + name + ".geom" ); + + program->setGeometryInputType(GL_LINES); + program->setGeometryOutputType(GL_LINE_STRIP); + program->setGeometryOutputVertexCount(100); // hack? + + program->link(); + //program->log(); + + return program; +} + +void TestGeometry::init() { + if (_initialized) { + qDebug("[ERROR] TestProgram is already initialized.\n"); + return; + } + + switchToResourcesParentIfRequired(); + + _testProgram = createGeometryShaderProgram("passthrough"); + _initialized = true; +} + +void TestGeometry::begin() { + _testProgram->bind(); +} + +void TestGeometry::end() { + _testProgram->release(); +} + diff --git a/interface/src/renderer/TestGeometry.h b/interface/src/renderer/TestGeometry.h new file mode 100644 index 0000000000..cec13196b0 --- /dev/null +++ b/interface/src/renderer/TestGeometry.h @@ -0,0 +1,44 @@ +// +// TestGeometry.h +// interface +// +// Created by Andrzej Kapolka on 8/7/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#ifndef __interface__TestGeometry__ +#define __interface__TestGeometry__ + +#include +#include + +class QOpenGLFramebufferObject; + +class ProgramObject; + +/// A generic full screen glow effect. +class TestGeometry : public QObject { + Q_OBJECT + +public: + TestGeometry(); + ~TestGeometry(); + + void init(); + + /// Starts using the geometry shader effect. + void begin(); + + /// Stops using the geometry shader effect. + void end(); + +public slots: + +private: + + bool _initialized; + + ProgramObject* _testProgram; +}; + +#endif /* defined(__interface__TestGeometry__) */ diff --git a/libraries/voxels/src/VoxelConstants.h b/libraries/voxels/src/VoxelConstants.h index 08fdbefee3..1c6e6cd0e6 100644 --- a/libraries/voxels/src/VoxelConstants.h +++ b/libraries/voxels/src/VoxelConstants.h @@ -33,9 +33,9 @@ const int NUMBER_OF_CHILDREN = 8; const int MAX_VOXEL_PACKET_SIZE = 1492; const int MAX_TREE_SLICE_BYTES = 26; const int MAX_VOXELS_PER_SYSTEM = 200000; -const int VERTICES_PER_VOXEL = 24; -const int VERTEX_POINTS_PER_VOXEL = 3 * VERTICES_PER_VOXEL; -const int INDICES_PER_VOXEL = 3 * 12; +const int VERTICES_PER_VOXEL = 24; // 6 sides * 4 corners per side +const int VERTEX_POINTS_PER_VOXEL = 3 * VERTICES_PER_VOXEL; // ???? xyz for each VERTICE_PER_VOXEL?? +const int INDICES_PER_VOXEL = 3 * 12; // 6 sides * 2 triangles per size * 3 vertices per triangle const int COLOR_VALUES_PER_VOXEL = NUMBER_OF_COLORS * VERTICES_PER_VOXEL; typedef unsigned long int glBufferIndex; From 552d9fadd88862b3903c6d39f08e1395f7e1ab70 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 26 Sep 2013 14:51:57 -0700 Subject: [PATCH 02/11] rearranged menus, some hacking on voxel shader --- interface/resources/shaders/passthrough.geom | 68 --- interface/resources/shaders/passthrough.vert | 6 +- interface/resources/shaders/voxel.geom | 86 ++++ interface/src/Application.cpp | 95 ++++- interface/src/Application.h | 6 +- interface/src/Menu.cpp | 221 +++++----- interface/src/Menu.h | 7 +- interface/src/VoxelSystem.cpp | 396 ++++++++++++------ interface/src/VoxelSystem.h | 18 + interface/src/renderer/TestGeometry.h | 44 -- .../{TestGeometry.cpp => VoxelShader.cpp} | 50 ++- interface/src/renderer/VoxelShader.h | 46 ++ 12 files changed, 670 insertions(+), 373 deletions(-) create mode 100644 interface/resources/shaders/voxel.geom delete mode 100644 interface/src/renderer/TestGeometry.h rename interface/src/renderer/{TestGeometry.cpp => VoxelShader.cpp} (50%) create mode 100644 interface/src/renderer/VoxelShader.h diff --git a/interface/resources/shaders/passthrough.geom b/interface/resources/shaders/passthrough.geom index 1ce193cda9..4ea2959b19 100644 --- a/interface/resources/shaders/passthrough.geom +++ b/interface/resources/shaders/passthrough.geom @@ -79,72 +79,4 @@ void main() EmitVertex(); } EndPrimitive(); - -/** - - for(i = 0; i < gl_VerticesIn; i++) { - green = vec4(0,1.0,0,1.0); - red = vec4(1.0,0,0,1.0); - //gl_FrontColor = gl_FrontColorIn[i]; - gl_FrontColor = red; - - // v -> v+x -> v+x+y - vertex = gl_PositionIn[i]; - gl_Position = vertex; - EmitVertex(); - vertex.x += 0.1f; - gl_Position = vertex; - EmitVertex(); - vertex.y += 0.1f; - gl_Position = vertex; - EmitVertex(); - EndPrimitive(); - - // v+x+y -> v+y -> v - vertex = gl_PositionIn[i]; - vertex.x += 0.1f; - vertex.y += 0.1f; - gl_Position = vertex; - EmitVertex(); - vertex.x -= 0.1f; - gl_Position = vertex; - EmitVertex(); - vertex.y -= 0.1f; - gl_Position = vertex; - EmitVertex(); - EndPrimitive(); - // v+z -> v+z+x -> v+z+x+y - gl_FrontColor = green; - vertex = gl_PositionIn[i]; - vertex.z -= 0.1f; - gl_Position = vertex; - EmitVertex(); - - vertex.x += 0.1f; - gl_Position = vertex; - EmitVertex(); - vertex.y += 0.1f; - gl_Position = vertex; - EmitVertex(); - EndPrimitive(); - - // v+z+x+y -> v+z+y -> v+z - vertex = gl_PositionIn[i]; - vertex.z -= 0.1f; - vertex.x += 0.1f; - vertex.y += 0.1f; - gl_Position = vertex; - EmitVertex(); - vertex.x -= 0.1f; - gl_Position = vertex; - EmitVertex(); - vertex.y -= 0.1f; - gl_Position = vertex; - EmitVertex(); - EndPrimitive(); - - } -**/ - - } \ No newline at end of file diff --git a/interface/resources/shaders/passthrough.vert b/interface/resources/shaders/passthrough.vert index a3a6219b6a..f770ab115f 100644 --- a/interface/resources/shaders/passthrough.vert +++ b/interface/resources/shaders/passthrough.vert @@ -1,6 +1,10 @@ #version 120 +attribute float voxelSizeIn; +varying float voxelSize; + void main(void) { gl_FrontColor = gl_Color; //vec4(1.0, 0.0, 0.0, 1.0); - gl_Position = gl_Vertex;// ftransform(); + gl_Position = gl_ModelViewMatrix * gl_Vertex;// ftransform(); + voxelSize = voxelSizeIn; } \ No newline at end of file diff --git a/interface/resources/shaders/voxel.geom b/interface/resources/shaders/voxel.geom new file mode 100644 index 0000000000..d3f0b89f10 --- /dev/null +++ b/interface/resources/shaders/voxel.geom @@ -0,0 +1,86 @@ +#version 120 +#extension GL_ARB_geometry_shader4 : enable + +// +// VOXEL GEOMETRY SHADER +// +// Input: gl_VerticesIn/gl_PositionIn +// GL_POINTS +// Assumes vertex shader has not transformed coordinates +// Each gl_PositionIn is the corner of voxel +// +// Second dataset (? similar to how voxel avatars pass in bones??) +// which is the voxel size +// +// Note: In vertex shader DON'T transform. Therefore passing the world coordinate xyz to geometric shader +// In geometric shader calculate xyz for triangles the same way we currently do triangles outside of OpenGL +// do transform on these triangles +// +// gl_Position = gl_ModelViewProjectionMatrix * cube_coord; +// +// Output: GL_TRIANGLE_STRIP +// +// Issues: +// do we need to handle lighting of these colors?? +// how do we handle normals? +// check for size=0 and don't output the primitive +// + +varying in float voxelSize[1]; + +const int VERTICES_PER_FACE = 4; +const int COORD_PER_VERTEX = 3; +const int COORD_PER_FACE = COORD_PER_VERTEX * VERTICES_PER_FACE; + +void faceOfVoxel(vec4 corner, float scale, float[COORD_PER_FACE] facePoints, vec4 color) { + for (int v = 0; v < VERTICES_PER_FACE; v++ ) { + vec4 vertex = corner; + for (int c = 0; c < COORD_PER_VERTEX; c++ ) { + int cIndex = c + (v * COORD_PER_VERTEX); + vertex[c] += (facePoints[cIndex] * scale); + } + gl_FrontColor = color; + gl_Position = gl_ProjectionMatrix * vertex; + EmitVertex(); + } + EndPrimitive(); +} + + +void main() +{ + //increment variable + int i; + vec4 corner; + float scale; + + float bottomFace[COORD_PER_FACE] = float[COORD_PER_FACE]( 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1 ); + float topFace[COORD_PER_FACE] = float[COORD_PER_FACE]( 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1 ); + float rightFace[COORD_PER_FACE] = float[COORD_PER_FACE]( 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1 ); + float leftFace[COORD_PER_FACE] = float[COORD_PER_FACE]( 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1 ); + float frontFace[COORD_PER_FACE] = float[COORD_PER_FACE]( 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0 ); + float backFace[COORD_PER_FACE] = float[COORD_PER_FACE]( 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1 ); + + vec4 color,red,green,blue,yellow,cyan,purple; + + green = vec4(0,1.0,0,1.0); + red = vec4(1.0,0,0,1.0); + blue = vec4(0,0,1.0,1.0); + yellow = vec4(1.0,1.0,0,1.0); + cyan = vec4(0,1.0,1.0,1.0); + purple = vec4(1.0,0,1.0,1.0); + + for(i = 0; i < gl_VerticesIn; i++) { + gl_FrontColor = gl_FrontColorIn[i]; + corner = gl_PositionIn[i]; + scale = voxelSize[i]; + color = gl_FrontColorIn[i]; + + faceOfVoxel(corner, scale, bottomFace, color); + faceOfVoxel(corner, scale, topFace, color); + faceOfVoxel(corner, scale, rightFace, color); + faceOfVoxel(corner, scale, leftFace, color); + faceOfVoxel(corner, scale, frontFace, color); + faceOfVoxel(corner, scale, backFace, color); + } +} \ No newline at end of file diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 503f8f434e..b10ed430bf 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -542,6 +542,10 @@ void Application::keyPressEvent(QKeyEvent* event) { _myAvatar.setDriveKeys(UP, 1); } break; + + case Qt::Key_Asterisk: + Menu::getInstance()->triggerOption(MenuOption::Stars); + break; case Qt::Key_C: if (isShifted) { @@ -811,8 +815,6 @@ void Application::keyPressEvent(QKeyEvent* event) { case Qt::Key_F: if (isShifted) { Menu::getInstance()->triggerOption(MenuOption::DisplayFrustum); - } else { - Menu::getInstance()->triggerOption(MenuOption::Fullscreen); } break; case Qt::Key_V: @@ -1540,7 +1542,7 @@ void Application::init() { _glowEffect.init(); _ambientOcclusionEffect.init(); - _testGeometry.init(); + _voxelShader.init(); _handControl.setScreenDimensions(_glWidget->width(), _glWidget->height()); @@ -2581,9 +2583,92 @@ void Application::displaySide(Camera& whichCamera) { // brad's frustum for debugging if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayFrustum)) { - _testGeometry.begin(); renderViewFrustum(_viewFrustum); - _testGeometry.end(); + } + + // brad's voxel shader debugging + if (false) { + + const float TEST_STRIP_COLOR[] = { 0.0f, 1.0f, 0.0f }; + glColor3fv(TEST_STRIP_COLOR); + + _voxelShader.begin(); + const float VOXEL_COLOR[] = { 1.0f, 0.0f, 0.0f }; + glColor3fv(VOXEL_COLOR); + + struct VoxelData + { + float x, y, z; // position + float s; // size + unsigned char r,g,b; // color + }; + + VoxelData voxels[3]; + + //VERTEX 0 + voxels[0].x = 0.0; + voxels[0].y = 0.0; + voxels[0].z = 1.0; + voxels[0].s = 0.1; + voxels[0].r = 255; + voxels[0].g = 0; + voxels[0].b = 0; + + //VERTEX 1 + voxels[1].x = 1.0; + voxels[1].y = 0.0; + voxels[1].z = 0.0; + voxels[1].s = 0.2; + voxels[1].r = 0; + voxels[1].g = 255; + voxels[1].b = 0; + + //VERTEX 2 + voxels[2].x = 0.0; + voxels[2].y = 1.0; + voxels[2].z = 0.0; + voxels[2].s = 0.3; + voxels[2].r = 0; + voxels[2].g = 0; + voxels[2].b = 255; + + GLuint VertexVBOID; + GLuint IndexVBOID; + + glGenBuffers(1, &VertexVBOID); + glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID); + glBufferData(GL_ARRAY_BUFFER, sizeof(voxels), &voxels[0].x, GL_STATIC_DRAW); + + ushort indices[3]; + indices[0] = 0; + indices[1] = 1; + indices[2] = 2; + + glGenBuffers(1, &IndexVBOID); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); + + //Define this somewhere in your header file + #define BUFFER_OFFSET(i) ((void*)(i)) + + glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(VoxelData), BUFFER_OFFSET(0)); //The starting point of the VBO, for the vertices + int loc = _voxelShader.attributeLocation("voxelSizeIn"); + glEnableVertexAttribArray(loc); + glVertexAttribPointer(loc, 1, GL_FLOAT, false, sizeof(VoxelData), BUFFER_OFFSET(3*sizeof(float))); + + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VoxelData), BUFFER_OFFSET(4*sizeof(float)));//The starting point of colors + + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID); + glDrawElements(GL_POINTS, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0)); //The starting point of the IBO + + glDeleteBuffers(1, &VertexVBOID); + glDeleteBuffers(1, &IndexVBOID); + + _voxelShader.end(); } // render voxel fades if they exist diff --git a/interface/src/Application.h b/interface/src/Application.h index 690dbc154c..0860d9057a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -51,7 +51,7 @@ #include "renderer/AmbientOcclusionEffect.h" #include "renderer/GeometryCache.h" #include "renderer/GlowEffect.h" -#include "renderer/TestGeometry.h" +#include "renderer/VoxelShader.h" #include "renderer/TextureCache.h" #include "ui/BandwidthDialog.h" #include "ui/ChatEntry.h" @@ -143,6 +143,8 @@ public: virtual void nodeAdded(Node* node); virtual void nodeKilled(Node* node); virtual void packetSentNotification(ssize_t length); + + VoxelShader& getVoxelShader() { return _voxelShader; } public slots: void sendAvatarFaceVideoMessage(int frameCount, const QByteArray& data); @@ -343,7 +345,7 @@ private: GlowEffect _glowEffect; AmbientOcclusionEffect _ambientOcclusionEffect; - TestGeometry _testGeometry; + VoxelShader _voxelShader; #ifndef _WIN32 Audio _audio; diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 560f72807b..6f385c3e99 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -188,50 +188,36 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Fullscreen, - Qt::Key_F, + Qt::CTRL | Qt::META | Qt::Key_F, false, appInstance, SLOT(setFullscreen(bool))); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson, Qt::Key_P, true); + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, Qt::Key_H); - addActionToQMenuAndActionHash(viewMenu, + QMenu* avatarSizeMenu = viewMenu->addMenu("Avatar Size"); + + addActionToQMenuAndActionHash(avatarSizeMenu, MenuOption::IncreaseAvatarSize, Qt::Key_Plus, appInstance->getAvatar(), SLOT(increaseSize())); - addActionToQMenuAndActionHash(viewMenu, + addActionToQMenuAndActionHash(avatarSizeMenu, MenuOption::DecreaseAvatarSize, Qt::Key_Minus, appInstance->getAvatar(), SLOT(decreaseSize())); - addActionToQMenuAndActionHash(viewMenu, + addActionToQMenuAndActionHash(avatarSizeMenu, MenuOption::ResetAvatarSize, 0, appInstance->getAvatar(), SLOT(resetSize())); - - - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, Qt::Key_H); - - addCheckableActionToQMenuAndActionHash(viewMenu, - MenuOption::SkeletonTracking, - 0, - false, - appInstance->getWebcam(), - SLOT(setSkeletonTrackingOn(bool))); - - addCheckableActionToQMenuAndActionHash(viewMenu, - MenuOption::LEDTracking, - 0, - false, - appInstance->getWebcam()->getGrabber(), - SLOT(setLEDTrackingOn(bool))); - + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::OffAxisProjection, 0, false); - + addDisabledActionAndSeparator(viewMenu, "Stats"); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats, Qt::Key_Slash); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Log, Qt::CTRL | Qt::Key_L); @@ -241,50 +227,119 @@ Menu::Menu() : addActionToQMenuAndActionHash(viewMenu, MenuOption::VoxelStats, 0, this, SLOT(voxelStatsDetails())); QMenu* developerMenu = addMenu("Developer"); - addDisabledActionAndSeparator(developerMenu, "Rendering"); - - addCheckableActionToQMenuAndActionHash(developerMenu, + + QMenu* renderOptionsMenu = developerMenu->addMenu("Rendering Options"); + + addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Stars, Qt::Key_Asterisk, true); + addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Atmosphere, Qt::SHIFT | Qt::Key_A, true); + addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::GroundPlane, 0, true); + addActionToQMenuAndActionHash(renderOptionsMenu, + MenuOption::GlowMode, + 0, + appInstance->getGlowEffect(), + SLOT(cycleRenderMode())); + + QMenu* voxelOptionsMenu = developerMenu->addMenu("Voxel Options"); + + addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::Voxels, Qt::SHIFT | Qt::Key_V, true, appInstance, SLOT(setRenderVoxels(bool))); - addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::VoxelTextures); - addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::AmbientOcclusion); - addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::Stars, 0, true); - addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::Atmosphere, Qt::SHIFT | Qt::Key_A, true); - addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::GroundPlane, 0, true); - addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::Avatars, 0, true); - addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::AvatarAsBalls); + addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelTextures); + addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AmbientOcclusion); + addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::UseVoxelShader); - addActionToQMenuAndActionHash(developerMenu, + QMenu* avatarOptionsMenu = developerMenu->addMenu("Avatar Options"); + + addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::Avatars, 0, true); + addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::AvatarAsBalls); + + addActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::VoxelMode, 0, appInstance->getAvatar()->getVoxels(), SLOT(cycleMode())); - addActionToQMenuAndActionHash(developerMenu, + addActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::FaceMode, 0, &appInstance->getAvatar()->getHead().getFace(), SLOT(cycleRenderMode())); - addActionToQMenuAndActionHash(developerMenu, - MenuOption::GlowMode, + addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::UsePerlinFace, 0, false); + addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::LookAtVectors, 0, true); + addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::LookAtIndicator, 0, true); + addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, + MenuOption::FaceshiftTCP, + 0, + false, + appInstance->getFaceshift(), + SLOT(setTCPEnabled(bool))); + + QMenu* webcamOptionsMenu = developerMenu->addMenu("Webcam Options"); + + addCheckableActionToQMenuAndActionHash(webcamOptionsMenu, + MenuOption::Webcam, + 0, + false, + appInstance->getWebcam(), + SLOT(setEnabled(bool))); + + addActionToQMenuAndActionHash(webcamOptionsMenu, + MenuOption::WebcamMode, 0, - appInstance->getGlowEffect(), - SLOT(cycleRenderMode())); + appInstance->getWebcam()->getGrabber(), + SLOT(cycleVideoSendMode())); + + addCheckableActionToQMenuAndActionHash(webcamOptionsMenu, + MenuOption::WebcamTexture, + 0, + false, + appInstance->getWebcam()->getGrabber(), + SLOT(setDepthOnly(bool))); + + QMenu* raveGloveOptionsMenu = developerMenu->addMenu("Rave Glove Options"); + + addCheckableActionToQMenuAndActionHash(raveGloveOptionsMenu, MenuOption::SimulateLeapHand); + addCheckableActionToQMenuAndActionHash(raveGloveOptionsMenu, MenuOption::TestRaveGlove); + + + QMenu* gyroOptionsMenu = developerMenu->addMenu("Gyro Options"); + addCheckableActionToQMenuAndActionHash(gyroOptionsMenu, MenuOption::GyroLook, 0, true); + addCheckableActionToQMenuAndActionHash(gyroOptionsMenu, MenuOption::HeadMouse); + + + QMenu* trackingOptionsMenu = developerMenu->addMenu("Tracking Options"); + addCheckableActionToQMenuAndActionHash(trackingOptionsMenu, + MenuOption::SkeletonTracking, + 0, + false, + appInstance->getWebcam(), + SLOT(setSkeletonTrackingOn(bool))); - addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::UsePerlinFace, 0, false); - addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::LookAtVectors, 0, true); - addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::LookAtIndicator, 0, true); - addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::FrameTimer); + addCheckableActionToQMenuAndActionHash(trackingOptionsMenu, + MenuOption::LEDTracking, + 0, + false, + appInstance->getWebcam()->getGrabber(), + SLOT(setLEDTrackingOn(bool))); addDisabledActionAndSeparator(developerMenu, "Testing"); + + QMenu* timingMenu = developerMenu->addMenu("Timing and Statistics Tools"); + addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::TestPing, 0, true); + addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::FrameTimer); + addActionToQMenuAndActionHash(timingMenu, MenuOption::RunTimingTests, 0, this, SLOT(runTests())); + addActionToQMenuAndActionHash(timingMenu, + MenuOption::TreeStats, + Qt::SHIFT | Qt::Key_S, + appInstance->getVoxels(), + SLOT(collectStatsForTreesAndVBOs())); QMenu* frustumMenu = developerMenu->addMenu("View Frustum Debugging Tools"); addCheckableActionToQMenuAndActionHash(frustumMenu, MenuOption::DisplayFrustum, Qt::SHIFT | Qt::Key_F); - addActionToQMenuAndActionHash(frustumMenu, MenuOption::FrustumRenderMode, Qt::SHIFT | Qt::Key_R, @@ -292,12 +347,6 @@ Menu::Menu() : SLOT(cycleFrustumRenderMode())); updateFrustumRenderModeAction(); - addActionToQMenuAndActionHash(developerMenu, MenuOption::RunTimingTests, 0, this, SLOT(runTests())); - addActionToQMenuAndActionHash(developerMenu, - MenuOption::TreeStats, - Qt::SHIFT | Qt::Key_S, - appInstance->getVoxels(), - SLOT(collectStatsForTreesAndVBOs())); QMenu* renderDebugMenu = developerMenu->addMenu("Render Debugging Tools"); addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::PipelineWarnings); @@ -337,18 +386,6 @@ Menu::Menu() : appInstance->getVoxels(), SLOT(falseColorizeInView())); - addActionToQMenuAndActionHash(renderDebugMenu, - MenuOption::FalseColorOccluded, - 0, - appInstance->getVoxels(), - SLOT(falseColorizeOccluded())); - - addActionToQMenuAndActionHash(renderDebugMenu, - MenuOption::FalseColorOccludedV2, - 0, - appInstance->getVoxels(), - SLOT(falseColorizeOccludedV2())); - addActionToQMenuAndActionHash(renderDebugMenu, MenuOption::FalseColorBySource, 0, @@ -361,32 +398,21 @@ Menu::Menu() : appInstance->getVoxels(), SLOT(trueColorize())); - - addCheckableActionToQMenuAndActionHash(developerMenu, - MenuOption::Webcam, - 0, - false, - appInstance->getWebcam(), - SLOT(setEnabled(bool))); - - addActionToQMenuAndActionHash(developerMenu, - MenuOption::WebcamMode, + addDisabledActionAndSeparator(renderDebugMenu, "Coverage Maps"); + addActionToQMenuAndActionHash(renderDebugMenu, + MenuOption::FalseColorOccluded, 0, - appInstance->getWebcam()->getGrabber(), - SLOT(cycleVideoSendMode())); - addCheckableActionToQMenuAndActionHash(developerMenu, - MenuOption::WebcamTexture, - 0, - false, - appInstance->getWebcam()->getGrabber(), - SLOT(setDepthOnly(bool))); + appInstance->getVoxels(), + SLOT(falseColorizeOccluded())); - addCheckableActionToQMenuAndActionHash(developerMenu, - MenuOption::FaceshiftTCP, - 0, - false, - appInstance->getFaceshift(), - SLOT(setTCPEnabled(bool))); + addActionToQMenuAndActionHash(renderDebugMenu, + MenuOption::FalseColorOccludedV2, + 0, + appInstance->getVoxels(), + SLOT(falseColorizeOccludedV2())); + + addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::CoverageMap, Qt::SHIFT | Qt::CTRL | Qt::Key_O); + addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::CoverageMapV2, Qt::SHIFT | Qt::CTRL | Qt::Key_P); QMenu* audioDebugMenu = developerMenu->addMenu("Audio Debugging Tools"); addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoAudio); @@ -406,47 +432,38 @@ Menu::Menu() : appInstance, SLOT(setListenModeSingleSource())); - addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::TestPing, 0, true); + QMenu* voxelProtoOptionsMenu = developerMenu->addMenu("Voxel Server Protocol Options"); - addCheckableActionToQMenuAndActionHash(developerMenu, + addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::SendVoxelColors, 0, true, appInstance->getAvatar(), SLOT(setWantColor(bool))); - addCheckableActionToQMenuAndActionHash(developerMenu, + addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::LowRes, 0, true, appInstance->getAvatar(), SLOT(setWantLowResMoving(bool))); - addCheckableActionToQMenuAndActionHash(developerMenu, + addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DeltaSending, 0, true, appInstance->getAvatar(), SLOT(setWantDelta(bool))); - addCheckableActionToQMenuAndActionHash(developerMenu, + addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::OcclusionCulling, Qt::SHIFT | Qt::Key_C, true, appInstance->getAvatar(), SLOT(setWantOcclusionCulling(bool))); - - addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::CoverageMap, Qt::SHIFT | Qt::CTRL | Qt::Key_O); - addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::CoverageMapV2, Qt::SHIFT | Qt::CTRL | Qt::Key_P); - addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::SimulateLeapHand); - addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::TestRaveGlove); - - addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::GyroLook, 0, true); - addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::HeadMouse); - - addDisabledActionAndSeparator(developerMenu, "Voxels"); - addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::DestructiveAddVoxel); + addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DestructiveAddVoxel); + #ifndef Q_OS_MAC QMenu* helpMenu = addMenu("Help"); QAction* helpAction = helpMenu->addAction(MenuOption::AboutApp); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 78ef65221c..a30fc4cdb0 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -201,9 +201,7 @@ namespace MenuOption { const QString TransmitterDrive = "Transmitter Drive"; const QString UsePerlinFace = "Use Perlin's Face"; const QString Quit = "Quit"; - const QString Webcam = "Webcam"; - const QString WebcamMode = "Cycle Webcam Send Mode"; - const QString WebcamTexture = "Webcam Texture"; + const QString UseVoxelShader = "Use Voxel Shader"; const QString Voxels = "Voxels"; const QString VoxelAddMode = "Add Voxel Mode"; const QString VoxelColorMode = "Color Voxel Mode"; @@ -214,6 +212,9 @@ namespace MenuOption { const QString VoxelSelectMode = "Select Voxel Mode"; const QString VoxelStats = "Voxel Stats"; const QString VoxelTextures = "Voxel Textures"; + const QString Webcam = "Webcam"; + const QString WebcamMode = "Cycle Webcam Send Mode"; + const QString WebcamTexture = "Webcam Texture"; } #endif /* defined(__hifi__Menu__) */ diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index a1595f0de0..759a2f178a 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -74,6 +74,19 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) connect(_tree, SIGNAL(importSize(float,float,float)), SIGNAL(importSize(float,float,float))); connect(_tree, SIGNAL(importProgress(int)), SIGNAL(importProgress(int))); + + _voxelShaderInitialized = false; + _initializingVoxelShader = false; + _writeVoxelShaderData = NULL; + _readVoxelShaderData = NULL; + + _readVerticesArray = NULL; + _writeVerticesArray = NULL; + _readColorsArray = NULL; + _writeColorsArray = NULL; + _writeVoxelDirtyArray = NULL; + _readVoxelDirtyArray = NULL; + } void VoxelSystem::nodeDeleted(VoxelNode* node) { @@ -125,13 +138,20 @@ VoxelSystem::~VoxelSystem() { glDeleteBuffers(1, &_vboNormalsID); glDeleteBuffers(1, &_vboColorsID); glDeleteBuffers(1, &_vboIndicesID); - + delete[] _readVerticesArray; delete[] _writeVerticesArray; delete[] _readColorsArray; delete[] _writeColorsArray; delete[] _writeVoxelDirtyArray; delete[] _readVoxelDirtyArray; + + // these are used when in VoxelShader mode. + glDeleteBuffers(1, &_vboVoxelsID); + glDeleteBuffers(1, &_vboVoxelsIndicesID); + + delete[] _writeVoxelShaderData; + delete[] _readVoxelShaderData; } delete _tree; @@ -141,6 +161,45 @@ VoxelSystem::~VoxelSystem() { VoxelNode::removeDeleteHook(this); } +bool VoxelSystem::getUseVoxelShader() { + bool useVoxelShader = false; //Menu::getInstance()->isOptionChecked(MenuOption::UseVoxelShader); + + return useVoxelShader; +} + +void VoxelSystem::initVoxelShader() { + GLuint* indicesArray = new GLuint[_maxVoxels]; + + // populate the indicesArray + // this will not change given new voxels, so we can set it all up now + for (int n = 0; n < _maxVoxels; n++) { + indicesArray[n] = n; + } + + // bind the indices VBO to the actual indices array + glGenBuffers(1, &_vboVoxelsIndicesID); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboVoxelsIndicesID); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, _maxVoxels, indicesArray, GL_STATIC_DRAW); + + + glGenBuffers(1, &_vboVoxelsID); + glBindBuffer(GL_ARRAY_BUFFER, _vboVoxelsID); + glBufferData(GL_ARRAY_BUFFER, _maxVoxels * sizeof(VoxelShaderVBOData), NULL, GL_DYNAMIC_DRAW); + + // delete the indices and normals arrays that are no longer needed + delete[] indicesArray; + + // we will track individual dirty sections with these arrays of bools + _writeVoxelDirtyArray = new bool[_maxVoxels]; + memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); + _readVoxelDirtyArray = new bool[_maxVoxels]; + memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); + + // prep the data structures for incoming voxel data + _writeVoxelShaderData = new VoxelShaderVBOData[_maxVoxels]; + _readVoxelShaderData = new VoxelShaderVBOData[_maxVoxels]; +} + void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) { _tree->loadVoxelsFile(fileName, wantColorRandomizer); setupNewVoxelsForDrawing(); @@ -398,18 +457,24 @@ void VoxelSystem::copyWrittenDataToReadArraysPartialVBOs() { void VoxelSystem::copyWrittenDataSegmentToReadArrays(glBufferIndex segmentStart, glBufferIndex segmentEnd) { int segmentLength = (segmentEnd - segmentStart) + 1; + if (getUseVoxelShader()) { + GLsizeiptr segmentSizeBytes = segmentLength * sizeof(VoxelShaderVBOData); + void* readDataAt = &_readVoxelShaderData[segmentStart]; + void* writeDataAt = &_writeVoxelShaderData[segmentStart]; + memcpy(readDataAt, writeDataAt, segmentSizeBytes); + } else { + GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat); + GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat); + GLfloat* readVerticesAt = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); + GLfloat* writeVerticesAt = _writeVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); + memcpy(readVerticesAt, writeVerticesAt, segmentSizeBytes); - GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat); - GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat); - GLfloat* readVerticesAt = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); - GLfloat* writeVerticesAt = _writeVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); - memcpy(readVerticesAt, writeVerticesAt, segmentSizeBytes); - - segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte); - segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte); - GLubyte* readColorsAt = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); - GLubyte* writeColorsAt = _writeColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); - memcpy(readColorsAt, writeColorsAt, segmentSizeBytes); + segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte); + segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte); + GLubyte* readColorsAt = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); + GLubyte* writeColorsAt = _writeColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); + memcpy(readColorsAt, writeColorsAt, segmentSizeBytes); + } } void VoxelSystem::copyWrittenDataToReadArrays(bool fullVBOs) { @@ -532,11 +597,29 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) { void VoxelSystem::updateNodeInArrays(glBufferIndex nodeIndex, const glm::vec3& startVertex, float voxelScale, const nodeColor& color) { - for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) { - GLfloat* writeVerticesAt = _writeVerticesArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL); - GLubyte* writeColorsAt = _writeColorsArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL); - *(writeVerticesAt+j) = startVertex[j % 3] + (identityVertices[j] * voxelScale); - *(writeColorsAt +j) = color[j % 3]; + + if (getUseVoxelShader()) { + VoxelShaderVBOData* writeVerticesAt = &_writeVoxelShaderData[nodeIndex]; + writeVerticesAt->x = startVertex.x * TREE_SCALE; + writeVerticesAt->y = startVertex.y * TREE_SCALE; + writeVerticesAt->z = startVertex.z * TREE_SCALE; + writeVerticesAt->s = voxelScale * TREE_SCALE; + writeVerticesAt->r = color[RED_INDEX]; + writeVerticesAt->g = color[GREEN_INDEX]; + writeVerticesAt->b = color[BLUE_INDEX]; + + /** + printf("updateNodeInArrays() nodeIndex=%lu writeVerticesAt=[%f,%f,%f,%f (%u,%u,%u)]\n", + nodeIndex, writeVerticesAt->x, writeVerticesAt->y, writeVerticesAt->z, writeVerticesAt->s, + writeVerticesAt->r, writeVerticesAt->g, writeVerticesAt->b ); + **/ + } else { + for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) { + GLfloat* writeVerticesAt = _writeVerticesArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL); + GLubyte* writeColorsAt = _writeColorsArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL); + *(writeVerticesAt+j) = startVertex[j % 3] + (identityVertices[j] * voxelScale); + *(writeColorsAt +j) = color[j % 3]; + } } } @@ -563,85 +646,89 @@ void VoxelSystem::init() { _voxelsInWriteArrays = 0; _voxelsInReadArrays = 0; - GLuint* indicesArray = new GLuint[INDICES_PER_VOXEL * _maxVoxels]; - - // populate the indicesArray - // this will not change given new voxels, so we can set it all up now - for (int n = 0; n < _maxVoxels; n++) { - // fill the indices array - int voxelIndexOffset = n * INDICES_PER_VOXEL; - GLuint* currentIndicesPos = indicesArray + voxelIndexOffset; - int startIndex = (n * VERTICES_PER_VOXEL); - - for (int i = 0; i < INDICES_PER_VOXEL; i++) { - // add indices for this side of the cube - currentIndicesPos[i] = startIndex + identityIndices[i]; - } - } - - GLfloat* normalsArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; - GLfloat* normalsArrayEndPointer = normalsArray; - - // populate the normalsArray - for (int n = 0; n < _maxVoxels; n++) { - for (int i = 0; i < VERTEX_POINTS_PER_VOXEL; i++) { - *(normalsArrayEndPointer++) = identityNormals[i]; - } - } - // VBO for the verticesArray - glGenBuffers(1, &_vboVerticesID); - glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID); - glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, NULL, GL_DYNAMIC_DRAW); + //initVoxelShader(); - // VBO for the normalsArray - glGenBuffers(1, &_vboNormalsID); - glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID); - glBufferData(GL_ARRAY_BUFFER, - VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, - normalsArray, GL_STATIC_DRAW); + if (true) { + GLuint* indicesArray = new GLuint[INDICES_PER_VOXEL * _maxVoxels]; - // VBO for colorsArray - glGenBuffers(1, &_vboColorsID); - glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); - glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * _maxVoxels, NULL, GL_DYNAMIC_DRAW); + // populate the indicesArray + // this will not change given new voxels, so we can set it all up now + for (int n = 0; n < _maxVoxels; n++) { + // fill the indices array + int voxelIndexOffset = n * INDICES_PER_VOXEL; + GLuint* currentIndicesPos = indicesArray + voxelIndexOffset; + int startIndex = (n * VERTICES_PER_VOXEL); - // VBO for the indicesArray - glGenBuffers(1, &_vboIndicesID); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, - INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels, - indicesArray, GL_STATIC_DRAW); + for (int i = 0; i < INDICES_PER_VOXEL; i++) { + // add indices for this side of the cube + currentIndicesPos[i] = startIndex + identityIndices[i]; + } + } - // delete the indices and normals arrays that are no longer needed - delete[] indicesArray; - delete[] normalsArray; + GLfloat* normalsArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; + GLfloat* normalsArrayEndPointer = normalsArray; + + // populate the normalsArray + for (int n = 0; n < _maxVoxels; n++) { + for (int i = 0; i < VERTEX_POINTS_PER_VOXEL; i++) { + *(normalsArrayEndPointer++) = identityNormals[i]; + } + } + + glGenBuffers(1, &_vboVerticesID); + glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID); + glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, NULL, GL_DYNAMIC_DRAW); + + // VBO for the normalsArray + glGenBuffers(1, &_vboNormalsID); + glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID); + glBufferData(GL_ARRAY_BUFFER, + VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, + normalsArray, GL_STATIC_DRAW); + + // VBO for colorsArray + glGenBuffers(1, &_vboColorsID); + glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); + glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * _maxVoxels, NULL, GL_DYNAMIC_DRAW); + + // VBO for the indicesArray + glGenBuffers(1, &_vboIndicesID); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, + INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels, + indicesArray, GL_STATIC_DRAW); + + // delete the indices and normals arrays that are no longer needed + delete[] indicesArray; + delete[] normalsArray; - // we will track individual dirty sections with these arrays of bools - _writeVoxelDirtyArray = new bool[_maxVoxels]; - memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); - _readVoxelDirtyArray = new bool[_maxVoxels]; - memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); + // we will track individual dirty sections with these arrays of bools + _writeVoxelDirtyArray = new bool[_maxVoxels]; + memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); + _readVoxelDirtyArray = new bool[_maxVoxels]; + memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); - // prep the data structures for incoming voxel data - _writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; - _readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; + // prep the data structures for incoming voxel data + _writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; + _readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; - _writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; - _readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; + _writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; + _readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; - // create our simple fragment shader if we're the first system to init - if (!_perlinModulateProgram.isLinked()) { - switchToResourcesParentIfRequired(); - _perlinModulateProgram.addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/perlin_modulate.vert"); - _perlinModulateProgram.addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/perlin_modulate.frag"); - _perlinModulateProgram.link(); + // create our simple fragment shader if we're the first system to init + if (!_perlinModulateProgram.isLinked()) { + switchToResourcesParentIfRequired(); + _perlinModulateProgram.addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/perlin_modulate.vert"); + _perlinModulateProgram.addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/perlin_modulate.frag"); + _perlinModulateProgram.link(); - _perlinModulateProgram.bind(); - _perlinModulateProgram.setUniformValue("permutationNormalTexture", 0); - _perlinModulateProgram.release(); + _perlinModulateProgram.bind(); + _perlinModulateProgram.setUniformValue("permutationNormalTexture", 0); + _perlinModulateProgram.release(); + } } _initialized = true; } @@ -714,17 +801,34 @@ void VoxelSystem::updateVBOs() { } void VoxelSystem::updateVBOSegment(glBufferIndex segmentStart, glBufferIndex segmentEnd) { - int segmentLength = (segmentEnd - segmentStart) + 1; - GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat); - GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat); - GLfloat* readVerticesFrom = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); - glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID); - glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom); - segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte); - segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte); - GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); - glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); - glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom); + if (getUseVoxelShader()) { + int segmentLength = (segmentEnd - segmentStart) + 1; + GLintptr segmentStartAt = segmentStart * sizeof(VoxelShaderVBOData); + GLsizeiptr segmentSizeBytes = segmentLength * sizeof(VoxelShaderVBOData); + void* readVerticesFrom = &_readVoxelShaderData[segmentStart]; + + glBindBuffer(GL_ARRAY_BUFFER, _vboVoxelsID); + glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom); + } else { + int segmentLength = (segmentEnd - segmentStart) + 1; + GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat); + GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat); + GLfloat* readVerticesFrom = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); + glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID); + glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom); +//printf("VoxelSystem::updateVBOSegment() segmentStart=%lu, segmentEnd=%lu, segmentSizeBytes=%lu \n", +// segmentStart, segmentEnd, segmentSizeBytes); + + + segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte); + segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte); + GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); + glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); + glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom); + +//printf("VoxelSystem::updateVBOSegment() segmentStart=%lu, segmentEnd=%lu, segmentSizeBytes=%lu \n", +// segmentStart, segmentEnd, segmentSizeBytes); + } } void VoxelSystem::render(bool texture) { @@ -734,43 +838,85 @@ void VoxelSystem::render(bool texture) { pthread_mutex_lock(&_bufferWriteLock); updateVBOs(); + + //printf("render() _voxelsInReadArrays=%lu voxel shader=%s\n", _voxelsInReadArrays, debug::valueOf(getUseVoxelShader())); - // tell OpenGL where to find vertex and color information - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - - glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID); - glVertexPointer(3, GL_FLOAT, 0, 0); - - glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID); - glNormalPointer(GL_FLOAT, 0, 0); - - glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); - glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0); - - applyScaleAndBindProgram(texture); + if (getUseVoxelShader()) { - // for performance, enable backface culling - glEnable(GL_CULL_FACE); + Application::getInstance()->getVoxelShader().begin(); - // draw the number of voxels we have - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID); - glDrawRangeElementsEXT(GL_TRIANGLES, 0, VERTICES_PER_VOXEL * _voxelsInReadArrays - 1, - 36 * _voxelsInReadArrays, GL_UNSIGNED_INT, 0); + //Define this somewhere in your header file + #define BUFFER_OFFSET(i) ((void*)(i)) - glDisable(GL_CULL_FACE); + glBindBuffer(GL_ARRAY_BUFFER, _vboVoxelsID); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(VoxelShaderVBOData), BUFFER_OFFSET(0)); //The starting point of the VBO, for the vertices + int loc = Application::getInstance()->getVoxelShader().attributeLocation("voxelSizeIn"); + glEnableVertexAttribArray(loc); + glVertexAttribPointer(loc, 1, GL_FLOAT, false, sizeof(VoxelShaderVBOData), BUFFER_OFFSET(3*sizeof(float))); + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VoxelShaderVBOData), BUFFER_OFFSET(4*sizeof(float)));//The starting point of colors - removeScaleAndReleaseProgram(texture); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboVoxelsIndicesID); + glDrawElements(GL_POINTS, _voxelsInReadArrays, GL_UNSIGNED_INT, BUFFER_OFFSET(0)); //The starting point of the IBO + + /** + for (int i=0; i < _voxelsInReadArrays; i++) { + VoxelShaderVBOData* readDataAt = &_readVoxelShaderData[i]; + printf("render() _voxelsInReadArrays=%lu i=%d readDataAt=[%f,%f,%f,%f (%u,%u,%u)]\n", + _voxelsInReadArrays, i, readDataAt->x, readDataAt->y, readDataAt->z, readDataAt->s, + readDataAt->r, readDataAt->g, readDataAt->b ); + } + **/ + + // deactivate vertex and color arrays after drawing + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + // bind with 0 to switch back to normal operation + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + Application::getInstance()->getVoxelShader().end(); + + } else { + // tell OpenGL where to find vertex and color information + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID); + glVertexPointer(3, GL_FLOAT, 0, 0); + + glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID); + glNormalPointer(GL_FLOAT, 0, 0); + + glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); + glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0); + + applyScaleAndBindProgram(texture); - // deactivate vertex and color arrays after drawing - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); + // for performance, enable backface culling + glEnable(GL_CULL_FACE); - // bind with 0 to switch back to normal operation - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + // draw the number of voxels we have + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID); + glDrawRangeElementsEXT(GL_TRIANGLES, 0, VERTICES_PER_VOXEL * _voxelsInReadArrays - 1, + 36 * _voxelsInReadArrays, GL_UNSIGNED_INT, 0); + + glDisable(GL_CULL_FACE); + + removeScaleAndReleaseProgram(texture); + + // deactivate vertex and color arrays after drawing + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + // bind with 0 to switch back to normal operation + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } pthread_mutex_unlock(&_bufferWriteLock); } diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 5ac5310b76..fe088ce042 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -23,11 +23,20 @@ #include "Camera.h" #include "Util.h" #include "world.h" +#include "renderer/VoxelShader.h" class ProgramObject; const int NUM_CHILDREN = 8; +struct VoxelShaderVBOData +{ + float x, y, z; // position + float s; // size + unsigned char r,g,b; // color +}; + + class VoxelSystem : public NodeData, public VoxelNodeDeleteHook, public NodeListHook { Q_OBJECT public: @@ -190,6 +199,15 @@ private: uint64_t _lastViewCulling; int _lastViewCullingElapsed; + bool getUseVoxelShader(); + void initVoxelShader(); + bool _voxelShaderInitialized; + bool _initializingVoxelShader; + GLuint _vboVoxelsID; /// when using voxel shader, we'll use this VBO + GLuint _vboVoxelsIndicesID; /// when using voxel shader, we'll use this VBO for our indexes + VoxelShaderVBOData* _writeVoxelShaderData; + VoxelShaderVBOData* _readVoxelShaderData; + GLuint _vboVerticesID; GLuint _vboNormalsID; GLuint _vboColorsID; diff --git a/interface/src/renderer/TestGeometry.h b/interface/src/renderer/TestGeometry.h deleted file mode 100644 index cec13196b0..0000000000 --- a/interface/src/renderer/TestGeometry.h +++ /dev/null @@ -1,44 +0,0 @@ -// -// TestGeometry.h -// interface -// -// Created by Andrzej Kapolka on 8/7/13. -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. -// - -#ifndef __interface__TestGeometry__ -#define __interface__TestGeometry__ - -#include -#include - -class QOpenGLFramebufferObject; - -class ProgramObject; - -/// A generic full screen glow effect. -class TestGeometry : public QObject { - Q_OBJECT - -public: - TestGeometry(); - ~TestGeometry(); - - void init(); - - /// Starts using the geometry shader effect. - void begin(); - - /// Stops using the geometry shader effect. - void end(); - -public slots: - -private: - - bool _initialized; - - ProgramObject* _testProgram; -}; - -#endif /* defined(__interface__TestGeometry__) */ diff --git a/interface/src/renderer/TestGeometry.cpp b/interface/src/renderer/VoxelShader.cpp similarity index 50% rename from interface/src/renderer/TestGeometry.cpp rename to interface/src/renderer/VoxelShader.cpp index e30a210dde..b8a907c917 100644 --- a/interface/src/renderer/TestGeometry.cpp +++ b/interface/src/renderer/VoxelShader.cpp @@ -1,5 +1,5 @@ // -// TestGeometry.cpp +// VoxelShader.cpp // interface // // Created by Brad Hefta-Gaub on 9/22/13. @@ -11,55 +11,59 @@ #include #include "Application.h" -#include "TestGeometry.h" +#include "VoxelShader.h" #include "ProgramObject.h" #include "RenderUtil.h" -TestGeometry::TestGeometry() +VoxelShader::VoxelShader() : _initialized(false) { + _program = NULL; } -TestGeometry::~TestGeometry() { +VoxelShader::~VoxelShader() { if (_initialized) { - delete _testProgram; + delete _program; } } -static ProgramObject* createGeometryShaderProgram(const QString& name) { +ProgramObject* VoxelShader::createGeometryShaderProgram(const QString& name) { ProgramObject* program = new ProgramObject(); program->addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/passthrough.vert" ); - - program->addShaderFromSourceFile(QGLShader::Geometry, "resources/shaders/" + name + ".geom" ); - - program->setGeometryInputType(GL_LINES); - program->setGeometryOutputType(GL_LINE_STRIP); - program->setGeometryOutputVertexCount(100); // hack? - + program->setGeometryInputType(GL_POINTS); + program->setGeometryOutputType(GL_TRIANGLE_STRIP); + const int VERTICES_PER_FACE = 4; + const int FACES_PER_VOXEL = 6; + const int VERTICES_PER_VOXEL = VERTICES_PER_FACE * FACES_PER_VOXEL; + program->setGeometryOutputVertexCount(VERTICES_PER_VOXEL); program->link(); - //program->log(); - return program; } -void TestGeometry::init() { +void VoxelShader::init() { if (_initialized) { qDebug("[ERROR] TestProgram is already initialized.\n"); return; } - switchToResourcesParentIfRequired(); - - _testProgram = createGeometryShaderProgram("passthrough"); + _program = createGeometryShaderProgram("voxel"); _initialized = true; } -void TestGeometry::begin() { - _testProgram->bind(); +void VoxelShader::begin() { + _program->bind(); } -void TestGeometry::end() { - _testProgram->release(); +void VoxelShader::end() { + _program->release(); +} + +int VoxelShader::attributeLocation(const char * name) const { + if (_program) { + return _program->attributeLocation(name); + } else { + return -1; + } } diff --git a/interface/src/renderer/VoxelShader.h b/interface/src/renderer/VoxelShader.h new file mode 100644 index 0000000000..33e8ea0073 --- /dev/null +++ b/interface/src/renderer/VoxelShader.h @@ -0,0 +1,46 @@ +// +// VoxelShader.h +// interface +// +// Created by Brad Hefta-Gaub on 9/23/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#ifndef __interface__VoxelShader__ +#define __interface__VoxelShader__ + +#include + +class ProgramObject; + +/// A generic full screen glow effect. +class VoxelShader : public QObject { + Q_OBJECT + +public: + VoxelShader(); + ~VoxelShader(); + + 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; + + static ProgramObject* createGeometryShaderProgram(const QString& name); + +public slots: + +private: + + bool _initialized; + + ProgramObject* _program; +}; + +#endif /* defined(__interface__VoxelShader__) */ From 78453402792d296f277574ae657759f6262fbb63 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 26 Sep 2013 16:26:49 -0700 Subject: [PATCH 03/11] menu cleanup, support for on the fly switching of maxVoxels and useVoxelShader --- interface/src/Application.cpp | 12 +- interface/src/Menu.cpp | 51 ++++- interface/src/Menu.h | 5 + interface/src/VoxelSystem.cpp | 313 ++++++++++++++------------ interface/src/VoxelSystem.h | 13 +- libraries/voxels/src/VoxelConstants.h | 2 +- 6 files changed, 237 insertions(+), 159 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b10ed430bf..1f231b9e2f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1521,7 +1521,6 @@ void Application::initDisplay() { } void Application::init() { - _voxels.init(); _sharedVoxelSystemViewFrustum.setPosition(glm::vec3(TREE_SCALE / 2.0f, TREE_SCALE / 2.0f, 3.0f * TREE_SCALE / 2.0f)); @@ -1573,9 +1572,13 @@ void Application::init() { if (Menu::getInstance()->getAudioJitterBufferSamples() != 0) { _audio.setJitterBufferSamples(Menu::getInstance()->getAudioJitterBufferSamples()); } - qDebug("Loaded settings.\n"); + // Set up VoxelSystem after loading preferences so we can get the desired max voxel count + _voxels.setMaxVoxels(Menu::getInstance()->getMaxVoxels()); + _voxels.init(); + + Avatar::sendAvatarURLsMessage(_myAvatar.getVoxels()->getVoxelURL(), _myAvatar.getHead().getBlendFace().getModelURL()); _palette.init(_glWidget->width(), _glWidget->height()); @@ -2915,7 +2918,10 @@ void Application::displayStats() { std::stringstream voxelStats; voxelStats.precision(4); - voxelStats << "Voxels Rendered: " << _voxels.getVoxelsRendered() / 1000.f << "K Updated: " << _voxels.getVoxelsUpdated()/1000.f << "K"; + voxelStats << "Voxels Rendered: " << _voxels.getVoxelsRendered() / 1000.f << "K " << + "Updated: " << _voxels.getVoxelsUpdated()/1000.f << "K " << + "Max: " << _voxels.getMaxVoxels()/1000.f << "K "; + drawtext(10, statsVerticalOffset + 230, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); voxelStats.str(""); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 6f385c3e99..3fd9334830 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -48,7 +48,8 @@ Menu::Menu() : _frustumDrawMode(FRUSTUM_DRAW_MODE_ALL), _viewFrustumOffset(DEFAULT_FRUSTUM_OFFSET), _voxelModeActionsGroup(NULL), - _voxelStatsDialog(NULL) + _voxelStatsDialog(NULL), + _maxVoxels(DEFAULT_MAX_VOXELS_PER_SYSTEM) { Application *appInstance = Application::getInstance(); @@ -249,7 +250,8 @@ Menu::Menu() : SLOT(setRenderVoxels(bool))); addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelTextures); addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AmbientOcclusion); - addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::UseVoxelShader); + addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::UseVoxelShader, 0, + false, this, SLOT(switchVoxelShader())); QMenu* avatarOptionsMenu = developerMenu->addMenu("Avatar Options"); @@ -485,6 +487,7 @@ void Menu::loadSettings(QSettings* settings) { _gyroCameraSensitivity = loadSetting(settings, "gyroCameraSensitivity", 0.5f); _audioJitterBufferSamples = loadSetting(settings, "audioJitterBufferSamples", 0); _fieldOfView = loadSetting(settings, "fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES); + _maxVoxels = loadSetting(settings, "maxVoxels", DEFAULT_MAX_VOXELS_PER_SYSTEM); settings->beginGroup("View Frustum Offset Camera"); // in case settings is corrupt or missing loadSetting() will check for NaN @@ -508,6 +511,7 @@ void Menu::saveSettings(QSettings* settings) { settings->setValue("gyroCameraSensitivity", _gyroCameraSensitivity); settings->setValue("audioJitterBufferSamples", _audioJitterBufferSamples); settings->setValue("fieldOfView", _fieldOfView); + settings->setValue("maxVoxels", _maxVoxels); settings->beginGroup("View Frustum Offset Camera"); settings->setValue("viewFrustumOffsetYaw", _viewFrustumOffset.yaw); settings->setValue("viewFrustumOffsetPitch", _viewFrustumOffset.pitch); @@ -755,9 +759,6 @@ void Menu::editPreferences() { QFormLayout* form = new QFormLayout(); layout->addLayout(form, 1); - QLineEdit* domainServerLineEdit = lineEditForDomainHostname(); - form->addRow("Domain server:", domainServerLineEdit); - QLineEdit* avatarURL = new QLineEdit(applicationInstance->getAvatar()->getVoxels()->getVoxelURL().toString()); avatarURL->setMinimumWidth(QLINE_MINIMUM_WIDTH); form->addRow("Avatar URL:", avatarURL); @@ -785,6 +786,13 @@ void Menu::editPreferences() { audioJitterBufferSamples->setMinimum(-10000); audioJitterBufferSamples->setValue(_audioJitterBufferSamples); form->addRow("Audio Jitter Buffer Samples (0 for automatic):", audioJitterBufferSamples); + + QSpinBox* maxVoxels = new QSpinBox(); + maxVoxels->setMaximum(5000000); + maxVoxels->setMinimum(0); + maxVoxels->setSingleStep(50000); + maxVoxels->setValue(_maxVoxels); + form->addRow("Maximum Voxels:", maxVoxels); QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); dialog.connect(buttons, SIGNAL(accepted()), SLOT(accept())); @@ -797,8 +805,6 @@ void Menu::editPreferences() { return; } - updateDSHostname(domainServerLineEdit->text()); - QUrl avatarVoxelURL(avatarURL->text()); applicationInstance->getAvatar()->getVoxels()->setVoxelURL(avatarVoxelURL); @@ -808,6 +814,8 @@ void Menu::editPreferences() { Avatar::sendAvatarURLsMessage(avatarVoxelURL, faceModelURL); _gyroCameraSensitivity = gyroCameraSensitivity->value(); + _maxVoxels = maxVoxels->value(); + applicationInstance->getVoxels()->setMaxVoxels(_maxVoxels); applicationInstance->getAvatar()->setLeanScale(leanScale->value()); @@ -1007,3 +1015,32 @@ void Menu::updateFrustumRenderModeAction() { break; } } + +void Menu::switchVoxelShader() { + Application::getInstance()->getVoxels()->setUseVoxelShader(isOptionChecked(MenuOption::UseVoxelShader)); +} + +void Menu::displayGPUMemory() { + + const int NUM_RESULTS = 4; // see notes, these APIs return up to 4 results + GLint results[NUM_RESULTS] = { 0, 0, 0, 0}; + + // ATI + // http://www.opengl.org/registry/specs/ATI/meminfo.txt + // + // TEXTURE_FREE_MEMORY_ATI 0x87FC + // RENDERBUFFER_FREE_MEMORY_ATI 0x87FD + const GLenum VBO_FREE_MEMORY_ATI = 0x87FB; + glGetIntegerv(VBO_FREE_MEMORY_ATI, &results[0]); + + // NVIDIA + // http://developer.download.nvidia.com/opengl/specs/GL_NVX_gpu_memory_info.txt + // + // GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047 + // GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048 + // GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049 + // GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A + // GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B + + +} diff --git a/interface/src/Menu.h b/interface/src/Menu.h index a30fc4cdb0..332f89176c 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -54,6 +54,8 @@ public: FrustumDrawMode getFrustumDrawMode() const { return _frustumDrawMode; } ViewFrustumOffset getViewFrustumOffset() const { return _viewFrustumOffset; } VoxelStatsDialog* getVoxelStatsDialog() const { return _voxelStatsDialog; } + int getMaxVoxels() const { return _maxVoxels; } + void handleViewFrustumOffsetKeyModifier(int key); @@ -78,6 +80,8 @@ private slots: void chooseVoxelPaintColor(); void runTests(); void resetSwatchColors(); + void displayGPUMemory(); + void switchVoxelShader(); private: static Menu* _instance; @@ -115,6 +119,7 @@ private: ViewFrustumOffset _viewFrustumOffset; QActionGroup* _voxelModeActionsGroup; VoxelStatsDialog* _voxelStatsDialog; + int _maxVoxels; }; namespace MenuOption { diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 759a2f178a..b430afdd10 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -74,9 +74,8 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) connect(_tree, SIGNAL(importSize(float,float,float)), SIGNAL(importSize(float,float,float))); connect(_tree, SIGNAL(importProgress(int)), SIGNAL(importProgress(int))); - - _voxelShaderInitialized = false; - _initializingVoxelShader = false; + + _useVoxelShader = false; _writeVoxelShaderData = NULL; _readVoxelShaderData = NULL; @@ -132,28 +131,7 @@ void VoxelSystem::clearFreeBufferIndexes() { } VoxelSystem::~VoxelSystem() { - if (_initialized) { - // Destroy glBuffers - glDeleteBuffers(1, &_vboVerticesID); - glDeleteBuffers(1, &_vboNormalsID); - glDeleteBuffers(1, &_vboColorsID); - glDeleteBuffers(1, &_vboIndicesID); - - delete[] _readVerticesArray; - delete[] _writeVerticesArray; - delete[] _readColorsArray; - delete[] _writeColorsArray; - delete[] _writeVoxelDirtyArray; - delete[] _readVoxelDirtyArray; - - // these are used when in VoxelShader mode. - glDeleteBuffers(1, &_vboVoxelsID); - glDeleteBuffers(1, &_vboVoxelsIndicesID); - - delete[] _writeVoxelShaderData; - delete[] _readVoxelShaderData; - } - + cleanupVoxelMemory(); delete _tree; pthread_mutex_destroy(&_bufferWriteLock); pthread_mutex_destroy(&_treeLock); @@ -161,43 +139,172 @@ VoxelSystem::~VoxelSystem() { VoxelNode::removeDeleteHook(this); } -bool VoxelSystem::getUseVoxelShader() { - bool useVoxelShader = false; //Menu::getInstance()->isOptionChecked(MenuOption::UseVoxelShader); - - return useVoxelShader; +void VoxelSystem::setMaxVoxels(int maxVoxels) { + pthread_mutex_lock(&_bufferWriteLock); + bool wasInitialized = _initialized; + if (wasInitialized) { + cleanupVoxelMemory(); + } + _maxVoxels = maxVoxels; + if (wasInitialized) { + init(); + } + pthread_mutex_unlock(&_bufferWriteLock); } -void VoxelSystem::initVoxelShader() { - GLuint* indicesArray = new GLuint[_maxVoxels]; - - // populate the indicesArray - // this will not change given new voxels, so we can set it all up now - for (int n = 0; n < _maxVoxels; n++) { - indicesArray[n] = n; +void VoxelSystem::setUseVoxelShader(bool useVoxelShader) { + pthread_mutex_lock(&_bufferWriteLock); + bool wasInitialized = _initialized; + if (wasInitialized) { + cleanupVoxelMemory(); } + _useVoxelShader = useVoxelShader; + if (wasInitialized) { + init(); + } + pthread_mutex_unlock(&_bufferWriteLock); +} - // bind the indices VBO to the actual indices array - glGenBuffers(1, &_vboVoxelsIndicesID); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboVoxelsIndicesID); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, _maxVoxels, indicesArray, GL_STATIC_DRAW); +void VoxelSystem::cleanupVoxelMemory() { + if (_initialized) { + if (_useVoxelShader) { + // these are used when in VoxelShader mode. + glDeleteBuffers(1, &_vboVoxelsID); + glDeleteBuffers(1, &_vboVoxelsIndicesID); + + delete[] _writeVoxelShaderData; + delete[] _readVoxelShaderData; + } else { + // Destroy glBuffers + glDeleteBuffers(1, &_vboVerticesID); + glDeleteBuffers(1, &_vboNormalsID); + glDeleteBuffers(1, &_vboColorsID); + glDeleteBuffers(1, &_vboIndicesID); + + delete[] _readVerticesArray; + delete[] _writeVerticesArray; + delete[] _readColorsArray; + delete[] _writeColorsArray; + delete[] _writeVoxelDirtyArray; + delete[] _readVoxelDirtyArray; + } + } + _initialized = false; // no longer initialized +} + +void VoxelSystem::initVoxelMemory() { + if (_useVoxelShader) { + GLuint* indicesArray = new GLuint[_maxVoxels]; + + // populate the indicesArray + // this will not change given new voxels, so we can set it all up now + for (int n = 0; n < _maxVoxels; n++) { + indicesArray[n] = n; + } + + // bind the indices VBO to the actual indices array + glGenBuffers(1, &_vboVoxelsIndicesID); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboVoxelsIndicesID); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, _maxVoxels, indicesArray, GL_STATIC_DRAW); - glGenBuffers(1, &_vboVoxelsID); - glBindBuffer(GL_ARRAY_BUFFER, _vboVoxelsID); - glBufferData(GL_ARRAY_BUFFER, _maxVoxels * sizeof(VoxelShaderVBOData), NULL, GL_DYNAMIC_DRAW); + glGenBuffers(1, &_vboVoxelsID); + glBindBuffer(GL_ARRAY_BUFFER, _vboVoxelsID); + glBufferData(GL_ARRAY_BUFFER, _maxVoxels * sizeof(VoxelShaderVBOData), NULL, GL_DYNAMIC_DRAW); - // delete the indices and normals arrays that are no longer needed - delete[] indicesArray; + // delete the indices and normals arrays that are no longer needed + delete[] indicesArray; - // we will track individual dirty sections with these arrays of bools - _writeVoxelDirtyArray = new bool[_maxVoxels]; - memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); - _readVoxelDirtyArray = new bool[_maxVoxels]; - memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); + // we will track individual dirty sections with these arrays of bools + _writeVoxelDirtyArray = new bool[_maxVoxels]; + memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); + _readVoxelDirtyArray = new bool[_maxVoxels]; + memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); - // prep the data structures for incoming voxel data - _writeVoxelShaderData = new VoxelShaderVBOData[_maxVoxels]; - _readVoxelShaderData = new VoxelShaderVBOData[_maxVoxels]; + // prep the data structures for incoming voxel data + _writeVoxelShaderData = new VoxelShaderVBOData[_maxVoxels]; + _readVoxelShaderData = new VoxelShaderVBOData[_maxVoxels]; + } else { + GLuint* indicesArray = new GLuint[INDICES_PER_VOXEL * _maxVoxels]; + + // populate the indicesArray + // this will not change given new voxels, so we can set it all up now + for (int n = 0; n < _maxVoxels; n++) { + // fill the indices array + int voxelIndexOffset = n * INDICES_PER_VOXEL; + GLuint* currentIndicesPos = indicesArray + voxelIndexOffset; + int startIndex = (n * VERTICES_PER_VOXEL); + + for (int i = 0; i < INDICES_PER_VOXEL; i++) { + // add indices for this side of the cube + currentIndicesPos[i] = startIndex + identityIndices[i]; + } + } + + GLfloat* normalsArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; + GLfloat* normalsArrayEndPointer = normalsArray; + + // populate the normalsArray + for (int n = 0; n < _maxVoxels; n++) { + for (int i = 0; i < VERTEX_POINTS_PER_VOXEL; i++) { + *(normalsArrayEndPointer++) = identityNormals[i]; + } + } + + glGenBuffers(1, &_vboVerticesID); + glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID); + glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, NULL, GL_DYNAMIC_DRAW); + + // VBO for the normalsArray + glGenBuffers(1, &_vboNormalsID); + glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID); + glBufferData(GL_ARRAY_BUFFER, + VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, + normalsArray, GL_STATIC_DRAW); + + // VBO for colorsArray + glGenBuffers(1, &_vboColorsID); + glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); + glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * _maxVoxels, NULL, GL_DYNAMIC_DRAW); + + // VBO for the indicesArray + glGenBuffers(1, &_vboIndicesID); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, + INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels, + indicesArray, GL_STATIC_DRAW); + + // delete the indices and normals arrays that are no longer needed + delete[] indicesArray; + delete[] normalsArray; + + + // we will track individual dirty sections with these arrays of bools + _writeVoxelDirtyArray = new bool[_maxVoxels]; + memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); + _readVoxelDirtyArray = new bool[_maxVoxels]; + memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); + + // prep the data structures for incoming voxel data + _writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; + _readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; + + _writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; + _readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; + + + // create our simple fragment shader if we're the first system to init + if (!_perlinModulateProgram.isLinked()) { + switchToResourcesParentIfRequired(); + _perlinModulateProgram.addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/perlin_modulate.vert"); + _perlinModulateProgram.addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/perlin_modulate.frag"); + _perlinModulateProgram.link(); + + _perlinModulateProgram.bind(); + _perlinModulateProgram.setUniformValue("permutationNormalTexture", 0); + _perlinModulateProgram.release(); + } + } } void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) { @@ -457,7 +564,7 @@ void VoxelSystem::copyWrittenDataToReadArraysPartialVBOs() { void VoxelSystem::copyWrittenDataSegmentToReadArrays(glBufferIndex segmentStart, glBufferIndex segmentEnd) { int segmentLength = (segmentEnd - segmentStart) + 1; - if (getUseVoxelShader()) { + if (_useVoxelShader) { GLsizeiptr segmentSizeBytes = segmentLength * sizeof(VoxelShaderVBOData); void* readDataAt = &_readVoxelShaderData[segmentStart]; void* writeDataAt = &_writeVoxelShaderData[segmentStart]; @@ -598,7 +705,7 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) { void VoxelSystem::updateNodeInArrays(glBufferIndex nodeIndex, const glm::vec3& startVertex, float voxelScale, const nodeColor& color) { - if (getUseVoxelShader()) { + if (_useVoxelShader) { VoxelShaderVBOData* writeVerticesAt = &_writeVoxelShaderData[nodeIndex]; writeVerticesAt->x = startVertex.x * TREE_SCALE; writeVerticesAt->y = startVertex.y * TREE_SCALE; @@ -647,89 +754,7 @@ void VoxelSystem::init() { _voxelsInReadArrays = 0; // VBO for the verticesArray - //initVoxelShader(); - - if (true) { - GLuint* indicesArray = new GLuint[INDICES_PER_VOXEL * _maxVoxels]; - - // populate the indicesArray - // this will not change given new voxels, so we can set it all up now - for (int n = 0; n < _maxVoxels; n++) { - // fill the indices array - int voxelIndexOffset = n * INDICES_PER_VOXEL; - GLuint* currentIndicesPos = indicesArray + voxelIndexOffset; - int startIndex = (n * VERTICES_PER_VOXEL); - - for (int i = 0; i < INDICES_PER_VOXEL; i++) { - // add indices for this side of the cube - currentIndicesPos[i] = startIndex + identityIndices[i]; - } - } - - GLfloat* normalsArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; - GLfloat* normalsArrayEndPointer = normalsArray; - - // populate the normalsArray - for (int n = 0; n < _maxVoxels; n++) { - for (int i = 0; i < VERTEX_POINTS_PER_VOXEL; i++) { - *(normalsArrayEndPointer++) = identityNormals[i]; - } - } - - glGenBuffers(1, &_vboVerticesID); - glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID); - glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, NULL, GL_DYNAMIC_DRAW); - - // VBO for the normalsArray - glGenBuffers(1, &_vboNormalsID); - glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID); - glBufferData(GL_ARRAY_BUFFER, - VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, - normalsArray, GL_STATIC_DRAW); - - // VBO for colorsArray - glGenBuffers(1, &_vboColorsID); - glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); - glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * _maxVoxels, NULL, GL_DYNAMIC_DRAW); - - // VBO for the indicesArray - glGenBuffers(1, &_vboIndicesID); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, - INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels, - indicesArray, GL_STATIC_DRAW); - - // delete the indices and normals arrays that are no longer needed - delete[] indicesArray; - delete[] normalsArray; - - - // we will track individual dirty sections with these arrays of bools - _writeVoxelDirtyArray = new bool[_maxVoxels]; - memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); - _readVoxelDirtyArray = new bool[_maxVoxels]; - memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); - - // prep the data structures for incoming voxel data - _writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; - _readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; - - _writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; - _readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; - - - // create our simple fragment shader if we're the first system to init - if (!_perlinModulateProgram.isLinked()) { - switchToResourcesParentIfRequired(); - _perlinModulateProgram.addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/perlin_modulate.vert"); - _perlinModulateProgram.addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/perlin_modulate.frag"); - _perlinModulateProgram.link(); - - _perlinModulateProgram.bind(); - _perlinModulateProgram.setUniformValue("permutationNormalTexture", 0); - _perlinModulateProgram.release(); - } - } + initVoxelMemory(); _initialized = true; } @@ -801,7 +826,7 @@ void VoxelSystem::updateVBOs() { } void VoxelSystem::updateVBOSegment(glBufferIndex segmentStart, glBufferIndex segmentEnd) { - if (getUseVoxelShader()) { + if (_useVoxelShader) { int segmentLength = (segmentEnd - segmentStart) + 1; GLintptr segmentStartAt = segmentStart * sizeof(VoxelShaderVBOData); GLsizeiptr segmentSizeBytes = segmentLength * sizeof(VoxelShaderVBOData); @@ -839,9 +864,9 @@ void VoxelSystem::render(bool texture) { updateVBOs(); - //printf("render() _voxelsInReadArrays=%lu voxel shader=%s\n", _voxelsInReadArrays, debug::valueOf(getUseVoxelShader())); + //printf("render() _voxelsInReadArrays=%lu voxel shader=%s\n", _voxelsInReadArrays, debug::valueOf(_useVoxelShader)); - if (getUseVoxelShader()) { + if (_useVoxelShader) { Application::getInstance()->getVoxelShader().begin(); @@ -1349,7 +1374,7 @@ public: duplicateVBOIndex(0), leafNodes(0) { - memset(hasIndexFound, false, MAX_VOXELS_PER_SYSTEM * sizeof(bool)); + memset(hasIndexFound, false, DEFAULT_MAX_VOXELS_PER_SYSTEM * sizeof(bool)); }; unsigned long totalNodes; @@ -1364,7 +1389,7 @@ public: unsigned long expectedMax; - bool hasIndexFound[MAX_VOXELS_PER_SYSTEM]; + bool hasIndexFound[DEFAULT_MAX_VOXELS_PER_SYSTEM]; }; bool VoxelSystem::collectStatsForTreesAndVBOsOperation(VoxelNode* node, void* extraData) { @@ -1439,7 +1464,7 @@ void VoxelSystem::collectStatsForTreesAndVBOs() { glBufferIndex minInVBO = GLBUFFER_INDEX_UNKNOWN; glBufferIndex maxInVBO = 0; - for (glBufferIndex i = 0; i < MAX_VOXELS_PER_SYSTEM; i++) { + for (glBufferIndex i = 0; i < DEFAULT_MAX_VOXELS_PER_SYSTEM; i++) { if (args.hasIndexFound[i]) { minInVBO = std::min(minInVBO,i); maxInVBO = std::max(maxInVBO,i); diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index fe088ce042..7a44034590 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -40,7 +40,7 @@ struct VoxelShaderVBOData class VoxelSystem : public NodeData, public VoxelNodeDeleteHook, public NodeListHook { Q_OBJECT public: - VoxelSystem(float treeScale = TREE_SCALE, int maxVoxels = MAX_VOXELS_PER_SYSTEM); + VoxelSystem(float treeScale = TREE_SCALE, int maxVoxels = DEFAULT_MAX_VOXELS_PER_SYSTEM); ~VoxelSystem(); void setDataSourceID(int dataSourceID) { _dataSourceID = dataSourceID; } @@ -65,6 +65,10 @@ public: bool readFromSquareARGB32Pixels(const char* filename); bool readFromSchematicFile(const char* filename); + void setUseVoxelShader(bool useVoxelShader); + + void setMaxVoxels(int maxVoxels); + long int getMaxVoxels() const { return _maxVoxels; } long int getVoxelsCreated(); long int getVoxelsColored(); long int getVoxelsBytesRead(); @@ -200,9 +204,10 @@ private: int _lastViewCullingElapsed; bool getUseVoxelShader(); - void initVoxelShader(); - bool _voxelShaderInitialized; - bool _initializingVoxelShader; + void initVoxelMemory(); + void cleanupVoxelMemory(); + + bool _useVoxelShader; GLuint _vboVoxelsID; /// when using voxel shader, we'll use this VBO GLuint _vboVoxelsIndicesID; /// when using voxel shader, we'll use this VBO for our indexes VoxelShaderVBOData* _writeVoxelShaderData; diff --git a/libraries/voxels/src/VoxelConstants.h b/libraries/voxels/src/VoxelConstants.h index 1c6e6cd0e6..0e89ab9cdb 100644 --- a/libraries/voxels/src/VoxelConstants.h +++ b/libraries/voxels/src/VoxelConstants.h @@ -32,7 +32,7 @@ const float VOXEL_SIZE_SCALE = TREE_SCALE * 400.0f; const int NUMBER_OF_CHILDREN = 8; const int MAX_VOXEL_PACKET_SIZE = 1492; const int MAX_TREE_SLICE_BYTES = 26; -const int MAX_VOXELS_PER_SYSTEM = 200000; +const int DEFAULT_MAX_VOXELS_PER_SYSTEM = 200000; const int VERTICES_PER_VOXEL = 24; // 6 sides * 4 corners per side const int VERTEX_POINTS_PER_VOXEL = 3 * VERTICES_PER_VOXEL; // ???? xyz for each VERTICE_PER_VOXEL?? const int INDICES_PER_VOXEL = 3 * 12; // 6 sides * 2 triangles per size * 3 vertices per triangle From fd0cc3b417368c82407b583931852628446f0986 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 26 Sep 2013 16:33:37 -0700 Subject: [PATCH 04/11] style fixes --- interface/src/Application.cpp | 85 ----------------------------------- interface/src/Menu.cpp | 9 ++-- 2 files changed, 6 insertions(+), 88 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1f231b9e2f..1659127def 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2589,91 +2589,6 @@ void Application::displaySide(Camera& whichCamera) { renderViewFrustum(_viewFrustum); } - // brad's voxel shader debugging - if (false) { - - const float TEST_STRIP_COLOR[] = { 0.0f, 1.0f, 0.0f }; - glColor3fv(TEST_STRIP_COLOR); - - _voxelShader.begin(); - const float VOXEL_COLOR[] = { 1.0f, 0.0f, 0.0f }; - glColor3fv(VOXEL_COLOR); - - struct VoxelData - { - float x, y, z; // position - float s; // size - unsigned char r,g,b; // color - }; - - VoxelData voxels[3]; - - //VERTEX 0 - voxels[0].x = 0.0; - voxels[0].y = 0.0; - voxels[0].z = 1.0; - voxels[0].s = 0.1; - voxels[0].r = 255; - voxels[0].g = 0; - voxels[0].b = 0; - - //VERTEX 1 - voxels[1].x = 1.0; - voxels[1].y = 0.0; - voxels[1].z = 0.0; - voxels[1].s = 0.2; - voxels[1].r = 0; - voxels[1].g = 255; - voxels[1].b = 0; - - //VERTEX 2 - voxels[2].x = 0.0; - voxels[2].y = 1.0; - voxels[2].z = 0.0; - voxels[2].s = 0.3; - voxels[2].r = 0; - voxels[2].g = 0; - voxels[2].b = 255; - - GLuint VertexVBOID; - GLuint IndexVBOID; - - glGenBuffers(1, &VertexVBOID); - glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID); - glBufferData(GL_ARRAY_BUFFER, sizeof(voxels), &voxels[0].x, GL_STATIC_DRAW); - - ushort indices[3]; - indices[0] = 0; - indices[1] = 1; - indices[2] = 2; - - glGenBuffers(1, &IndexVBOID); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); - - //Define this somewhere in your header file - #define BUFFER_OFFSET(i) ((void*)(i)) - - glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VoxelData), BUFFER_OFFSET(0)); //The starting point of the VBO, for the vertices - int loc = _voxelShader.attributeLocation("voxelSizeIn"); - glEnableVertexAttribArray(loc); - glVertexAttribPointer(loc, 1, GL_FLOAT, false, sizeof(VoxelData), BUFFER_OFFSET(3*sizeof(float))); - - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VoxelData), BUFFER_OFFSET(4*sizeof(float)));//The starting point of colors - - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID); - glDrawElements(GL_POINTS, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0)); //The starting point of the IBO - - glDeleteBuffers(1, &VertexVBOID); - glDeleteBuffers(1, &IndexVBOID); - - _voxelShader.end(); - } - // render voxel fades if they exist if (_voxelFades.size() > 0) { for(std::vector::iterator fade = _voxelFades.begin(); fade != _voxelFades.end();) { diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 3fd9334830..ec322def85 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -788,9 +788,12 @@ void Menu::editPreferences() { form->addRow("Audio Jitter Buffer Samples (0 for automatic):", audioJitterBufferSamples); QSpinBox* maxVoxels = new QSpinBox(); - maxVoxels->setMaximum(5000000); - maxVoxels->setMinimum(0); - maxVoxels->setSingleStep(50000); + const int MAX_MAX_VOXELS = 5000000; + const int MIN_MAX_VOXELS = 0; + const int STEP_MAX_VOXELS = 50000; + maxVoxels->setMaximum(MAX_MAX_VOXELS); + maxVoxels->setMinimum(MIN_MAX_VOXELS); + maxVoxels->setSingleStep(STEP_MAX_VOXELS); maxVoxels->setValue(_maxVoxels); form->addRow("Maximum Voxels:", maxVoxels); From 5695429a7883f08e6e03a24f96d1a42a72224b7e Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 26 Sep 2013 16:36:59 -0700 Subject: [PATCH 05/11] style fixes --- interface/src/VoxelSystem.cpp | 24 ------------------------ libraries/voxels/src/VoxelConstants.h | 2 +- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index b430afdd10..86d8704905 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -714,12 +714,6 @@ void VoxelSystem::updateNodeInArrays(glBufferIndex nodeIndex, const glm::vec3& s writeVerticesAt->r = color[RED_INDEX]; writeVerticesAt->g = color[GREEN_INDEX]; writeVerticesAt->b = color[BLUE_INDEX]; - - /** - printf("updateNodeInArrays() nodeIndex=%lu writeVerticesAt=[%f,%f,%f,%f (%u,%u,%u)]\n", - nodeIndex, writeVerticesAt->x, writeVerticesAt->y, writeVerticesAt->z, writeVerticesAt->s, - writeVerticesAt->r, writeVerticesAt->g, writeVerticesAt->b ); - **/ } else { for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) { GLfloat* writeVerticesAt = _writeVerticesArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL); @@ -841,18 +835,11 @@ void VoxelSystem::updateVBOSegment(glBufferIndex segmentStart, glBufferIndex seg GLfloat* readVerticesFrom = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID); glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom); -//printf("VoxelSystem::updateVBOSegment() segmentStart=%lu, segmentEnd=%lu, segmentSizeBytes=%lu \n", -// segmentStart, segmentEnd, segmentSizeBytes); - - segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte); segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte); GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom); - -//printf("VoxelSystem::updateVBOSegment() segmentStart=%lu, segmentEnd=%lu, segmentSizeBytes=%lu \n", -// segmentStart, segmentEnd, segmentSizeBytes); } } @@ -864,8 +851,6 @@ void VoxelSystem::render(bool texture) { updateVBOs(); - //printf("render() _voxelsInReadArrays=%lu voxel shader=%s\n", _voxelsInReadArrays, debug::valueOf(_useVoxelShader)); - if (_useVoxelShader) { Application::getInstance()->getVoxelShader().begin(); @@ -885,15 +870,6 @@ void VoxelSystem::render(bool texture) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboVoxelsIndicesID); glDrawElements(GL_POINTS, _voxelsInReadArrays, GL_UNSIGNED_INT, BUFFER_OFFSET(0)); //The starting point of the IBO - /** - for (int i=0; i < _voxelsInReadArrays; i++) { - VoxelShaderVBOData* readDataAt = &_readVoxelShaderData[i]; - printf("render() _voxelsInReadArrays=%lu i=%d readDataAt=[%f,%f,%f,%f (%u,%u,%u)]\n", - _voxelsInReadArrays, i, readDataAt->x, readDataAt->y, readDataAt->z, readDataAt->s, - readDataAt->r, readDataAt->g, readDataAt->b ); - } - **/ - // deactivate vertex and color arrays after drawing glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); diff --git a/libraries/voxels/src/VoxelConstants.h b/libraries/voxels/src/VoxelConstants.h index 0e89ab9cdb..391be29282 100644 --- a/libraries/voxels/src/VoxelConstants.h +++ b/libraries/voxels/src/VoxelConstants.h @@ -34,7 +34,7 @@ const int MAX_VOXEL_PACKET_SIZE = 1492; const int MAX_TREE_SLICE_BYTES = 26; const int DEFAULT_MAX_VOXELS_PER_SYSTEM = 200000; const int VERTICES_PER_VOXEL = 24; // 6 sides * 4 corners per side -const int VERTEX_POINTS_PER_VOXEL = 3 * VERTICES_PER_VOXEL; // ???? xyz for each VERTICE_PER_VOXEL?? +const int VERTEX_POINTS_PER_VOXEL = 3 * VERTICES_PER_VOXEL; // xyz for each VERTICE_PER_VOXEL const int INDICES_PER_VOXEL = 3 * 12; // 6 sides * 2 triangles per size * 3 vertices per triangle const int COLOR_VALUES_PER_VOXEL = NUMBER_OF_COLORS * VERTICES_PER_VOXEL; From 864c00c6e02b604cb13fca26af95967f05072b35 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 26 Sep 2013 16:38:29 -0700 Subject: [PATCH 06/11] removed some dead code --- .../resources/shaders/duplicate_geometry.geom | 46 ----------- interface/resources/shaders/passthrough.geom | 82 ------------------- 2 files changed, 128 deletions(-) delete mode 100644 interface/resources/shaders/duplicate_geometry.geom delete mode 100644 interface/resources/shaders/passthrough.geom diff --git a/interface/resources/shaders/duplicate_geometry.geom b/interface/resources/shaders/duplicate_geometry.geom deleted file mode 100644 index 2ab92fc4e3..0000000000 --- a/interface/resources/shaders/duplicate_geometry.geom +++ /dev/null @@ -1,46 +0,0 @@ -#version 420 - -layout(triangles) in; -layout (triangle_strip, max_vertices=6) out; - -layout (std140) uniform Matrices { - mat4 projModelViewMatrix; - mat3 normalMatrix; -}; - -in VertexData { - vec2 texCoord; - vec3 normal; -} VertexIn[]; - -out VertexData { - vec2 texCoord; - vec3 normal; -} VertexOut; - -void main() -{ - for(int i = 0; i < gl_in.length(); i++) - { - // copy attributes - gl_Position = projModelViewMatrix * gl_in[i].gl_Position; - VertexOut.normal = normalize(normalMatrix * VertexIn[i].normal); - VertexOut.texCoord = VertexIn[i].texCoord; - - // done with the vertex - EmitVertex(); - } - EndPrimitive(); - - for(int i = 0; i < gl_in.length(); i++) - { - // copy attributes and displace copy - gl_Position = projModelViewMatrix * (gl_in[i].gl_Position + vec4(20.0, 0.0, 0.0, 0.0)); - VertexOut.normal = normalize(normalMatrix * VertexIn[i].normal); - VertexOut.texCoord = VertexIn[i].texCoord; - - // done with the vertex - EmitVertex(); - } - EndPrimitive(); -} diff --git a/interface/resources/shaders/passthrough.geom b/interface/resources/shaders/passthrough.geom deleted file mode 100644 index 4ea2959b19..0000000000 --- a/interface/resources/shaders/passthrough.geom +++ /dev/null @@ -1,82 +0,0 @@ -#version 120 -#extension GL_ARB_geometry_shader4 : enable - -// use GL_POINTS -// have point be the corner of voxel -// have a second dataset (? similar to how voxel avatars pass in bones??) -// which is the voxel size? -// -// In vertex shader DON'T transform.. therefor passing the world coordinate xyz to geometric shader -// In geometric shader calculate xyz for triangles the same way we currently do triangles outside of OpenGL -// do transform on these triangles -// gl_Position = gl_ModelViewProjectionMatrix * cube_coord; -// -// output GL_TRIANGLE_STRIP -// -// NOTE: updateNodeInArrays() does the covert from voxel corner to 12 triangles or 36 points or 36*3 floats -// but since it operates on the array of floats, it is kinda weird and hard to follow. The %3 is for the -// xyz.. and identityVertices[j] term in the math is actually a string of floats but they should be thought -// of as triplets of x,y,z -// -// do we need to add the light to these colors?? -// - -//GEOMETRY SHADER -/////////////////////// -void main() -{ - //increment variable - int i; - vec4 vertex; - vec4 color,red,green,blue; - - green = vec4(0,1.0,0,1.0); - red = vec4(1.0,0,0,1.0); - blue = vec4(0,0,1.0,1.0); - - ///////////////////////////////////////////////////////////// - //This example has two parts - // step a) draw the primitive pushed down the pipeline - // there are gl_VerticesIn # of vertices - // put the vertex value into gl_Position - // use EmitVertex => 'create' a new vertex - // use EndPrimitive to signal that you are done creating a primitive! - // step b) create a new piece of geometry - // I just do the same loop, but I negate the vertex.z - // result => the primitive is now mirrored. - //Pass-thru! - for(i = 0; i < gl_VerticesIn; i++) { - color = gl_FrontColorIn[i]; - gl_FrontColor = color; // - gl_Position = gl_ModelViewProjectionMatrix * gl_PositionIn[i]; - EmitVertex(); - } - EndPrimitive(); - - for(i = 0; i < gl_VerticesIn; i++) { - gl_FrontColor = red; // - vertex = gl_PositionIn[i]; - vertex.y += 0.05f; - gl_Position = gl_ModelViewProjectionMatrix * vertex; - EmitVertex(); - } - EndPrimitive(); - - for(i = 0; i < gl_VerticesIn; i++) { - gl_FrontColor = green; // - vertex = gl_PositionIn[i]; - vertex.x += 0.05f; - gl_Position = gl_ModelViewProjectionMatrix * vertex; - EmitVertex(); - } - EndPrimitive(); - - for(i = 0; i < gl_VerticesIn; i++) { - gl_FrontColor = blue; // - vertex = gl_PositionIn[i]; - vertex.z += 0.05f; - gl_Position = gl_ModelViewProjectionMatrix * vertex; - EmitVertex(); - } - EndPrimitive(); -} \ No newline at end of file From 57b30c13d89284a1bd7772eb8f39ca1c6b8f5c88 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 26 Sep 2013 16:45:09 -0700 Subject: [PATCH 07/11] style cleanup --- interface/resources/shaders/passthrough.vert | 6 ++--- interface/resources/shaders/voxel.geom | 27 +++++--------------- 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/interface/resources/shaders/passthrough.vert b/interface/resources/shaders/passthrough.vert index f770ab115f..af55842c67 100644 --- a/interface/resources/shaders/passthrough.vert +++ b/interface/resources/shaders/passthrough.vert @@ -4,7 +4,7 @@ attribute float voxelSizeIn; varying float voxelSize; void main(void) { - gl_FrontColor = gl_Color; //vec4(1.0, 0.0, 0.0, 1.0); - gl_Position = gl_ModelViewMatrix * gl_Vertex;// ftransform(); - voxelSize = voxelSizeIn; + gl_FrontColor = gl_Color; + gl_Position = gl_ModelViewMatrix * gl_Vertex; // don't call ftransform(), because we do projection in geometry shader + voxelSize = voxelSizeIn; } \ No newline at end of file diff --git a/interface/resources/shaders/voxel.geom b/interface/resources/shaders/voxel.geom index d3f0b89f10..0ea4075f65 100644 --- a/interface/resources/shaders/voxel.geom +++ b/interface/resources/shaders/voxel.geom @@ -47,8 +47,7 @@ void faceOfVoxel(vec4 corner, float scale, float[COORD_PER_FACE] facePoints, vec } -void main() -{ +void main() { //increment variable int i; vec4 corner; @@ -61,26 +60,14 @@ void main() float frontFace[COORD_PER_FACE] = float[COORD_PER_FACE]( 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0 ); float backFace[COORD_PER_FACE] = float[COORD_PER_FACE]( 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1 ); - vec4 color,red,green,blue,yellow,cyan,purple; - - green = vec4(0,1.0,0,1.0); - red = vec4(1.0,0,0,1.0); - blue = vec4(0,0,1.0,1.0); - yellow = vec4(1.0,1.0,0,1.0); - cyan = vec4(0,1.0,1.0,1.0); - purple = vec4(1.0,0,1.0,1.0); - for(i = 0; i < gl_VerticesIn; i++) { - gl_FrontColor = gl_FrontColorIn[i]; corner = gl_PositionIn[i]; scale = voxelSize[i]; - color = gl_FrontColorIn[i]; - - faceOfVoxel(corner, scale, bottomFace, color); - faceOfVoxel(corner, scale, topFace, color); - faceOfVoxel(corner, scale, rightFace, color); - faceOfVoxel(corner, scale, leftFace, color); - faceOfVoxel(corner, scale, frontFace, color); - faceOfVoxel(corner, scale, backFace, color); + faceOfVoxel(corner, scale, bottomFace, gl_FrontColorIn[i]); + faceOfVoxel(corner, scale, topFace, gl_FrontColorIn[i]); + faceOfVoxel(corner, scale, rightFace, gl_FrontColorIn[i]); + faceOfVoxel(corner, scale, leftFace, gl_FrontColorIn[i]); + faceOfVoxel(corner, scale, frontFace, gl_FrontColorIn[i]); + faceOfVoxel(corner, scale, backFace, gl_FrontColorIn[i]); } } \ No newline at end of file From 3f8e55da28e3c919afa802151857b33cf9881eed Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 26 Sep 2013 16:46:34 -0700 Subject: [PATCH 08/11] style cleanup --- interface/src/Menu.cpp | 24 ------------------------ interface/src/Menu.h | 1 - 2 files changed, 25 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index ec322def85..89ce92052e 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -1023,27 +1023,3 @@ void Menu::switchVoxelShader() { Application::getInstance()->getVoxels()->setUseVoxelShader(isOptionChecked(MenuOption::UseVoxelShader)); } -void Menu::displayGPUMemory() { - - const int NUM_RESULTS = 4; // see notes, these APIs return up to 4 results - GLint results[NUM_RESULTS] = { 0, 0, 0, 0}; - - // ATI - // http://www.opengl.org/registry/specs/ATI/meminfo.txt - // - // TEXTURE_FREE_MEMORY_ATI 0x87FC - // RENDERBUFFER_FREE_MEMORY_ATI 0x87FD - const GLenum VBO_FREE_MEMORY_ATI = 0x87FB; - glGetIntegerv(VBO_FREE_MEMORY_ATI, &results[0]); - - // NVIDIA - // http://developer.download.nvidia.com/opengl/specs/GL_NVX_gpu_memory_info.txt - // - // GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047 - // GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048 - // GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049 - // GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A - // GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B - - -} diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 332f89176c..3f242f5fd9 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -80,7 +80,6 @@ private slots: void chooseVoxelPaintColor(); void runTests(); void resetSwatchColors(); - void displayGPUMemory(); void switchVoxelShader(); private: From c0bfdfbc4f206003448eea14a7327b99f318a6fa Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 26 Sep 2013 16:54:20 -0700 Subject: [PATCH 09/11] fix comment --- interface/resources/shaders/voxel.geom | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/interface/resources/shaders/voxel.geom b/interface/resources/shaders/voxel.geom index 0ea4075f65..bfc94b3f26 100644 --- a/interface/resources/shaders/voxel.geom +++ b/interface/resources/shaders/voxel.geom @@ -12,16 +12,12 @@ // Second dataset (? similar to how voxel avatars pass in bones??) // which is the voxel size // -// Note: In vertex shader DON'T transform. Therefore passing the world coordinate xyz to geometric shader -// In geometric shader calculate xyz for triangles the same way we currently do triangles outside of OpenGL -// do transform on these triangles -// -// gl_Position = gl_ModelViewProjectionMatrix * cube_coord; -// +// Note: In vertex shader DON'T do projection transform. Therefore passing the 3D coordinates xyz to geometric shader +// // Output: GL_TRIANGLE_STRIP // // Issues: -// do we need to handle lighting of these colors?? +// how do we need to handle lighting of these colors?? // how do we handle normals? // check for size=0 and don't output the primitive // From 07515d1c5fca933a738a629bd8ffdfb3c2d036cc Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 26 Sep 2013 17:03:50 -0700 Subject: [PATCH 10/11] fix projection between shaders --- interface/resources/shaders/passthrough.vert | 2 +- interface/resources/shaders/voxel.geom | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/resources/shaders/passthrough.vert b/interface/resources/shaders/passthrough.vert index af55842c67..f3d5c5b504 100644 --- a/interface/resources/shaders/passthrough.vert +++ b/interface/resources/shaders/passthrough.vert @@ -5,6 +5,6 @@ varying float voxelSize; void main(void) { gl_FrontColor = gl_Color; - gl_Position = gl_ModelViewMatrix * gl_Vertex; // don't call ftransform(), because we do projection in geometry shader + gl_Position = gl_Vertex; // don't call ftransform(), because we do projection in geometry shader voxelSize = voxelSizeIn; } \ No newline at end of file diff --git a/interface/resources/shaders/voxel.geom b/interface/resources/shaders/voxel.geom index bfc94b3f26..6f4534a003 100644 --- a/interface/resources/shaders/voxel.geom +++ b/interface/resources/shaders/voxel.geom @@ -12,7 +12,7 @@ // Second dataset (? similar to how voxel avatars pass in bones??) // which is the voxel size // -// Note: In vertex shader DON'T do projection transform. Therefore passing the 3D coordinates xyz to geometric shader +// Note: In vertex shader doesn't do any transform. Therefore passing the 3D world coordinates xyz to us // // Output: GL_TRIANGLE_STRIP // @@ -36,7 +36,7 @@ void faceOfVoxel(vec4 corner, float scale, float[COORD_PER_FACE] facePoints, vec vertex[c] += (facePoints[cIndex] * scale); } gl_FrontColor = color; - gl_Position = gl_ProjectionMatrix * vertex; + gl_Position = gl_ModelViewProjectionMatrix * vertex; EmitVertex(); } EndPrimitive(); From 3ab92a592a7b9cb91ba6f61d71c18a3b03d37199 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 26 Sep 2013 17:05:04 -0700 Subject: [PATCH 11/11] fix comments in shaders --- interface/resources/shaders/voxel.geom | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/interface/resources/shaders/voxel.geom b/interface/resources/shaders/voxel.geom index 6f4534a003..13b502357e 100644 --- a/interface/resources/shaders/voxel.geom +++ b/interface/resources/shaders/voxel.geom @@ -8,9 +8,7 @@ // GL_POINTS // Assumes vertex shader has not transformed coordinates // Each gl_PositionIn is the corner of voxel -// -// Second dataset (? similar to how voxel avatars pass in bones??) -// which is the voxel size +// varying voxelSize - which is the voxel size // // Note: In vertex shader doesn't do any transform. Therefore passing the 3D world coordinates xyz to us //