mirror of
https://github.com/overte-org/overte.git
synced 2025-04-19 16:23:39 +02:00
rearranged menus, some hacking on voxel shader
This commit is contained in:
parent
3d4341cee4
commit
552d9fadd8
12 changed files with 670 additions and 373 deletions
|
@ -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();
|
||||
|
||||
}
|
||||
**/
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
86
interface/resources/shaders/voxel.geom
Normal file
86
interface/resources/shaders/voxel.geom
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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__) */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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__) */
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
46
interface/src/renderer/VoxelShader.h
Normal file
46
interface/src/renderer/VoxelShader.h
Normal 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__) */
|
Loading…
Reference in a new issue