rearranged menus, some hacking on voxel shader

This commit is contained in:
ZappoMan 2013-09-26 14:51:57 -07:00
parent 3d4341cee4
commit 552d9fadd8
12 changed files with 670 additions and 373 deletions

View file

@ -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();
}
**/
}

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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

View file

@ -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;

View file

@ -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);

View file

@ -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__) */

View file

@ -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);
}

View file

@ -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;

View file

@ -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 <QObject>
#include <QStack>
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__) */

View file

@ -1,5 +1,5 @@
//
// TestGeometry.cpp
// VoxelShader.cpp
// interface
//
// Created by Brad Hefta-Gaub on 9/22/13.
@ -11,55 +11,59 @@
#include <QOpenGLFramebufferObject>
#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;
}
}

View file

@ -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 <QObject>
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__) */