mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-10 19:18:44 +02:00
Merge branch 'master' of https://github.com/worklist/hifi
This commit is contained in:
commit
462d0b90c1
11 changed files with 686 additions and 272 deletions
10
interface/resources/shaders/passthrough.vert
Normal file
10
interface/resources/shaders/passthrough.vert
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
attribute float voxelSizeIn;
|
||||||
|
varying float voxelSize;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
gl_FrontColor = gl_Color;
|
||||||
|
gl_Position = gl_Vertex; // don't call ftransform(), because we do projection in geometry shader
|
||||||
|
voxelSize = voxelSizeIn;
|
||||||
|
}
|
67
interface/resources/shaders/voxel.geom
Normal file
67
interface/resources/shaders/voxel.geom
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
#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
|
||||||
|
// varying voxelSize - which is the voxel size
|
||||||
|
//
|
||||||
|
// Note: In vertex shader doesn't do any transform. Therefore passing the 3D world coordinates xyz to us
|
||||||
|
//
|
||||||
|
// Output: GL_TRIANGLE_STRIP
|
||||||
|
//
|
||||||
|
// Issues:
|
||||||
|
// how do we need to handle lighting of these colors??
|
||||||
|
// how do we handle normals?
|
||||||
|
// check for size=0 and don't output the primitive
|
||||||
|
//
|
||||||
|
|
||||||
|
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_ModelViewProjectionMatrix * 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 );
|
||||||
|
|
||||||
|
for(i = 0; i < gl_VerticesIn; i++) {
|
||||||
|
corner = gl_PositionIn[i];
|
||||||
|
scale = voxelSize[i];
|
||||||
|
faceOfVoxel(corner, scale, bottomFace, gl_FrontColorIn[i]);
|
||||||
|
faceOfVoxel(corner, scale, topFace, gl_FrontColorIn[i]);
|
||||||
|
faceOfVoxel(corner, scale, rightFace, gl_FrontColorIn[i]);
|
||||||
|
faceOfVoxel(corner, scale, leftFace, gl_FrontColorIn[i]);
|
||||||
|
faceOfVoxel(corner, scale, frontFace, gl_FrontColorIn[i]);
|
||||||
|
faceOfVoxel(corner, scale, backFace, gl_FrontColorIn[i]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -389,6 +389,7 @@ void Application::paintGL() {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_glowEffect.prepare();
|
_glowEffect.prepare();
|
||||||
|
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
@ -541,6 +542,10 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
_myAvatar.setDriveKeys(UP, 1);
|
_myAvatar.setDriveKeys(UP, 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Qt::Key_Asterisk:
|
||||||
|
Menu::getInstance()->triggerOption(MenuOption::Stars);
|
||||||
|
break;
|
||||||
|
|
||||||
case Qt::Key_C:
|
case Qt::Key_C:
|
||||||
if (isShifted) {
|
if (isShifted) {
|
||||||
|
@ -810,8 +815,6 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
case Qt::Key_F:
|
case Qt::Key_F:
|
||||||
if (isShifted) {
|
if (isShifted) {
|
||||||
Menu::getInstance()->triggerOption(MenuOption::DisplayFrustum);
|
Menu::getInstance()->triggerOption(MenuOption::DisplayFrustum);
|
||||||
} else {
|
|
||||||
Menu::getInstance()->triggerOption(MenuOption::Fullscreen);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::Key_V:
|
case Qt::Key_V:
|
||||||
|
@ -1518,7 +1521,6 @@ void Application::initDisplay() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::init() {
|
void Application::init() {
|
||||||
_voxels.init();
|
|
||||||
_sharedVoxelSystemViewFrustum.setPosition(glm::vec3(TREE_SCALE / 2.0f,
|
_sharedVoxelSystemViewFrustum.setPosition(glm::vec3(TREE_SCALE / 2.0f,
|
||||||
TREE_SCALE / 2.0f,
|
TREE_SCALE / 2.0f,
|
||||||
3.0f * TREE_SCALE / 2.0f));
|
3.0f * TREE_SCALE / 2.0f));
|
||||||
|
@ -1539,6 +1541,7 @@ void Application::init() {
|
||||||
|
|
||||||
_glowEffect.init();
|
_glowEffect.init();
|
||||||
_ambientOcclusionEffect.init();
|
_ambientOcclusionEffect.init();
|
||||||
|
_voxelShader.init();
|
||||||
|
|
||||||
_handControl.setScreenDimensions(_glWidget->width(), _glWidget->height());
|
_handControl.setScreenDimensions(_glWidget->width(), _glWidget->height());
|
||||||
|
|
||||||
|
@ -1569,9 +1572,13 @@ void Application::init() {
|
||||||
if (Menu::getInstance()->getAudioJitterBufferSamples() != 0) {
|
if (Menu::getInstance()->getAudioJitterBufferSamples() != 0) {
|
||||||
_audio.setJitterBufferSamples(Menu::getInstance()->getAudioJitterBufferSamples());
|
_audio.setJitterBufferSamples(Menu::getInstance()->getAudioJitterBufferSamples());
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug("Loaded settings.\n");
|
qDebug("Loaded settings.\n");
|
||||||
|
|
||||||
|
// Set up VoxelSystem after loading preferences so we can get the desired max voxel count
|
||||||
|
_voxels.setMaxVoxels(Menu::getInstance()->getMaxVoxels());
|
||||||
|
_voxels.init();
|
||||||
|
|
||||||
|
|
||||||
Avatar::sendAvatarURLsMessage(_myAvatar.getVoxels()->getVoxelURL(), _myAvatar.getHead().getBlendFace().getModelURL());
|
Avatar::sendAvatarURLsMessage(_myAvatar.getVoxels()->getVoxelURL(), _myAvatar.getHead().getBlendFace().getModelURL());
|
||||||
|
|
||||||
_palette.init(_glWidget->width(), _glWidget->height());
|
_palette.init(_glWidget->width(), _glWidget->height());
|
||||||
|
@ -2565,7 +2572,7 @@ void Application::displaySide(Camera& whichCamera) {
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayFrustum)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayFrustum)) {
|
||||||
renderViewFrustum(_viewFrustum);
|
renderViewFrustum(_viewFrustum);
|
||||||
}
|
}
|
||||||
|
|
||||||
// render voxel fades if they exist
|
// render voxel fades if they exist
|
||||||
if (_voxelFades.size() > 0) {
|
if (_voxelFades.size() > 0) {
|
||||||
for(std::vector<VoxelFade>::iterator fade = _voxelFades.begin(); fade != _voxelFades.end();) {
|
for(std::vector<VoxelFade>::iterator fade = _voxelFades.begin(); fade != _voxelFades.end();) {
|
||||||
|
@ -2810,7 +2817,10 @@ void Application::displayStats() {
|
||||||
|
|
||||||
std::stringstream voxelStats;
|
std::stringstream voxelStats;
|
||||||
voxelStats.precision(4);
|
voxelStats.precision(4);
|
||||||
voxelStats << "Voxels Rendered: " << _voxels.getVoxelsRendered() / 1000.f << "K Updated: " << _voxels.getVoxelsUpdated()/1000.f << "K";
|
voxelStats << "Voxels Rendered: " << _voxels.getVoxelsRendered() / 1000.f << "K " <<
|
||||||
|
"Updated: " << _voxels.getVoxelsUpdated()/1000.f << "K " <<
|
||||||
|
"Max: " << _voxels.getMaxVoxels()/1000.f << "K ";
|
||||||
|
|
||||||
drawtext(10, statsVerticalOffset + 230, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
|
drawtext(10, statsVerticalOffset + 230, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
|
||||||
|
|
||||||
voxelStats.str("");
|
voxelStats.str("");
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
#include "renderer/AmbientOcclusionEffect.h"
|
#include "renderer/AmbientOcclusionEffect.h"
|
||||||
#include "renderer/GeometryCache.h"
|
#include "renderer/GeometryCache.h"
|
||||||
#include "renderer/GlowEffect.h"
|
#include "renderer/GlowEffect.h"
|
||||||
|
#include "renderer/VoxelShader.h"
|
||||||
#include "renderer/TextureCache.h"
|
#include "renderer/TextureCache.h"
|
||||||
#include "ui/BandwidthDialog.h"
|
#include "ui/BandwidthDialog.h"
|
||||||
#include "ui/ChatEntry.h"
|
#include "ui/ChatEntry.h"
|
||||||
|
@ -144,6 +145,8 @@ public:
|
||||||
virtual void nodeAdded(Node* node);
|
virtual void nodeAdded(Node* node);
|
||||||
virtual void nodeKilled(Node* node);
|
virtual void nodeKilled(Node* node);
|
||||||
virtual void packetSentNotification(ssize_t length);
|
virtual void packetSentNotification(ssize_t length);
|
||||||
|
|
||||||
|
VoxelShader& getVoxelShader() { return _voxelShader; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void sendAvatarFaceVideoMessage(int frameCount, const QByteArray& data);
|
void sendAvatarFaceVideoMessage(int frameCount, const QByteArray& data);
|
||||||
|
@ -346,6 +349,7 @@ private:
|
||||||
|
|
||||||
GlowEffect _glowEffect;
|
GlowEffect _glowEffect;
|
||||||
AmbientOcclusionEffect _ambientOcclusionEffect;
|
AmbientOcclusionEffect _ambientOcclusionEffect;
|
||||||
|
VoxelShader _voxelShader;
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
Audio _audio;
|
Audio _audio;
|
||||||
|
|
|
@ -49,7 +49,8 @@ Menu::Menu() :
|
||||||
_frustumDrawMode(FRUSTUM_DRAW_MODE_ALL),
|
_frustumDrawMode(FRUSTUM_DRAW_MODE_ALL),
|
||||||
_viewFrustumOffset(DEFAULT_FRUSTUM_OFFSET),
|
_viewFrustumOffset(DEFAULT_FRUSTUM_OFFSET),
|
||||||
_voxelModeActionsGroup(NULL),
|
_voxelModeActionsGroup(NULL),
|
||||||
_voxelStatsDialog(NULL)
|
_voxelStatsDialog(NULL),
|
||||||
|
_maxVoxels(DEFAULT_MAX_VOXELS_PER_SYSTEM)
|
||||||
{
|
{
|
||||||
Application *appInstance = Application::getInstance();
|
Application *appInstance = Application::getInstance();
|
||||||
|
|
||||||
|
@ -189,50 +190,36 @@ Menu::Menu() :
|
||||||
|
|
||||||
addCheckableActionToQMenuAndActionHash(viewMenu,
|
addCheckableActionToQMenuAndActionHash(viewMenu,
|
||||||
MenuOption::Fullscreen,
|
MenuOption::Fullscreen,
|
||||||
Qt::Key_F,
|
Qt::CTRL | Qt::META | Qt::Key_F,
|
||||||
false,
|
false,
|
||||||
appInstance,
|
appInstance,
|
||||||
SLOT(setFullscreen(bool)));
|
SLOT(setFullscreen(bool)));
|
||||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson, Qt::Key_P, true);
|
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,
|
MenuOption::IncreaseAvatarSize,
|
||||||
Qt::Key_Plus,
|
Qt::Key_Plus,
|
||||||
appInstance->getAvatar(),
|
appInstance->getAvatar(),
|
||||||
SLOT(increaseSize()));
|
SLOT(increaseSize()));
|
||||||
addActionToQMenuAndActionHash(viewMenu,
|
addActionToQMenuAndActionHash(avatarSizeMenu,
|
||||||
MenuOption::DecreaseAvatarSize,
|
MenuOption::DecreaseAvatarSize,
|
||||||
Qt::Key_Minus,
|
Qt::Key_Minus,
|
||||||
appInstance->getAvatar(),
|
appInstance->getAvatar(),
|
||||||
SLOT(decreaseSize()));
|
SLOT(decreaseSize()));
|
||||||
addActionToQMenuAndActionHash(viewMenu,
|
addActionToQMenuAndActionHash(avatarSizeMenu,
|
||||||
MenuOption::ResetAvatarSize,
|
MenuOption::ResetAvatarSize,
|
||||||
0,
|
0,
|
||||||
appInstance->getAvatar(),
|
appInstance->getAvatar(),
|
||||||
SLOT(resetSize()));
|
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,
|
addCheckableActionToQMenuAndActionHash(viewMenu,
|
||||||
MenuOption::OffAxisProjection,
|
MenuOption::OffAxisProjection,
|
||||||
0,
|
0,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
addDisabledActionAndSeparator(viewMenu, "Stats");
|
addDisabledActionAndSeparator(viewMenu, "Stats");
|
||||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats, Qt::Key_Slash);
|
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats, Qt::Key_Slash);
|
||||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Log, Qt::CTRL | Qt::Key_L);
|
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Log, Qt::CTRL | Qt::Key_L);
|
||||||
|
@ -242,50 +229,120 @@ Menu::Menu() :
|
||||||
addActionToQMenuAndActionHash(viewMenu, MenuOption::VoxelStats, 0, this, SLOT(voxelStatsDetails()));
|
addActionToQMenuAndActionHash(viewMenu, MenuOption::VoxelStats, 0, this, SLOT(voxelStatsDetails()));
|
||||||
|
|
||||||
QMenu* developerMenu = addMenu("Developer");
|
QMenu* developerMenu = addMenu("Developer");
|
||||||
addDisabledActionAndSeparator(developerMenu, "Rendering");
|
|
||||||
|
QMenu* renderOptionsMenu = developerMenu->addMenu("Rendering Options");
|
||||||
addCheckableActionToQMenuAndActionHash(developerMenu,
|
|
||||||
|
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,
|
MenuOption::Voxels,
|
||||||
Qt::SHIFT | Qt::Key_V,
|
Qt::SHIFT | Qt::Key_V,
|
||||||
true,
|
true,
|
||||||
appInstance,
|
appInstance,
|
||||||
SLOT(setRenderVoxels(bool)));
|
SLOT(setRenderVoxels(bool)));
|
||||||
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::VoxelTextures);
|
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelTextures);
|
||||||
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::AmbientOcclusion);
|
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AmbientOcclusion);
|
||||||
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::Stars, 0, true);
|
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::UseVoxelShader, 0,
|
||||||
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::Atmosphere, Qt::SHIFT | Qt::Key_A, true);
|
false, this, SLOT(switchVoxelShader()));
|
||||||
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::GroundPlane, 0, true);
|
|
||||||
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::Avatars, 0, true);
|
|
||||||
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::AvatarAsBalls);
|
|
||||||
|
|
||||||
addActionToQMenuAndActionHash(developerMenu,
|
QMenu* avatarOptionsMenu = developerMenu->addMenu("Avatar Options");
|
||||||
|
|
||||||
|
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::Avatars, 0, true);
|
||||||
|
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::AvatarAsBalls);
|
||||||
|
|
||||||
|
addActionToQMenuAndActionHash(avatarOptionsMenu,
|
||||||
MenuOption::VoxelMode,
|
MenuOption::VoxelMode,
|
||||||
0,
|
0,
|
||||||
appInstance->getAvatar()->getVoxels(),
|
appInstance->getAvatar()->getVoxels(),
|
||||||
SLOT(cycleMode()));
|
SLOT(cycleMode()));
|
||||||
|
|
||||||
addActionToQMenuAndActionHash(developerMenu,
|
addActionToQMenuAndActionHash(avatarOptionsMenu,
|
||||||
MenuOption::FaceMode,
|
MenuOption::FaceMode,
|
||||||
0,
|
0,
|
||||||
&appInstance->getAvatar()->getHead().getFace(),
|
&appInstance->getAvatar()->getHead().getFace(),
|
||||||
SLOT(cycleRenderMode()));
|
SLOT(cycleRenderMode()));
|
||||||
|
|
||||||
addActionToQMenuAndActionHash(developerMenu,
|
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::UsePerlinFace, 0, false);
|
||||||
MenuOption::GlowMode,
|
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,
|
0,
|
||||||
appInstance->getGlowEffect(),
|
appInstance->getWebcam()->getGrabber(),
|
||||||
SLOT(cycleRenderMode()));
|
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(trackingOptionsMenu,
|
||||||
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::LookAtVectors, 0, true);
|
MenuOption::LEDTracking,
|
||||||
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::LookAtIndicator, 0, true);
|
0,
|
||||||
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::FrameTimer);
|
false,
|
||||||
|
appInstance->getWebcam()->getGrabber(),
|
||||||
|
SLOT(setLEDTrackingOn(bool)));
|
||||||
|
|
||||||
addDisabledActionAndSeparator(developerMenu, "Testing");
|
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");
|
QMenu* frustumMenu = developerMenu->addMenu("View Frustum Debugging Tools");
|
||||||
addCheckableActionToQMenuAndActionHash(frustumMenu, MenuOption::DisplayFrustum, Qt::SHIFT | Qt::Key_F);
|
addCheckableActionToQMenuAndActionHash(frustumMenu, MenuOption::DisplayFrustum, Qt::SHIFT | Qt::Key_F);
|
||||||
|
|
||||||
addActionToQMenuAndActionHash(frustumMenu,
|
addActionToQMenuAndActionHash(frustumMenu,
|
||||||
MenuOption::FrustumRenderMode,
|
MenuOption::FrustumRenderMode,
|
||||||
Qt::SHIFT | Qt::Key_R,
|
Qt::SHIFT | Qt::Key_R,
|
||||||
|
@ -293,12 +350,6 @@ Menu::Menu() :
|
||||||
SLOT(cycleFrustumRenderMode()));
|
SLOT(cycleFrustumRenderMode()));
|
||||||
updateFrustumRenderModeAction();
|
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");
|
QMenu* renderDebugMenu = developerMenu->addMenu("Render Debugging Tools");
|
||||||
addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::PipelineWarnings);
|
addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::PipelineWarnings);
|
||||||
|
@ -338,18 +389,6 @@ Menu::Menu() :
|
||||||
appInstance->getVoxels(),
|
appInstance->getVoxels(),
|
||||||
SLOT(falseColorizeInView()));
|
SLOT(falseColorizeInView()));
|
||||||
|
|
||||||
addActionToQMenuAndActionHash(renderDebugMenu,
|
|
||||||
MenuOption::FalseColorOccluded,
|
|
||||||
0,
|
|
||||||
appInstance->getVoxels(),
|
|
||||||
SLOT(falseColorizeOccluded()));
|
|
||||||
|
|
||||||
addActionToQMenuAndActionHash(renderDebugMenu,
|
|
||||||
MenuOption::FalseColorOccludedV2,
|
|
||||||
0,
|
|
||||||
appInstance->getVoxels(),
|
|
||||||
SLOT(falseColorizeOccludedV2()));
|
|
||||||
|
|
||||||
addActionToQMenuAndActionHash(renderDebugMenu,
|
addActionToQMenuAndActionHash(renderDebugMenu,
|
||||||
MenuOption::FalseColorBySource,
|
MenuOption::FalseColorBySource,
|
||||||
0,
|
0,
|
||||||
|
@ -362,32 +401,21 @@ Menu::Menu() :
|
||||||
appInstance->getVoxels(),
|
appInstance->getVoxels(),
|
||||||
SLOT(trueColorize()));
|
SLOT(trueColorize()));
|
||||||
|
|
||||||
|
addDisabledActionAndSeparator(renderDebugMenu, "Coverage Maps");
|
||||||
addCheckableActionToQMenuAndActionHash(developerMenu,
|
addActionToQMenuAndActionHash(renderDebugMenu,
|
||||||
MenuOption::Webcam,
|
MenuOption::FalseColorOccluded,
|
||||||
0,
|
|
||||||
false,
|
|
||||||
appInstance->getWebcam(),
|
|
||||||
SLOT(setEnabled(bool)));
|
|
||||||
|
|
||||||
addActionToQMenuAndActionHash(developerMenu,
|
|
||||||
MenuOption::WebcamMode,
|
|
||||||
0,
|
0,
|
||||||
appInstance->getWebcam()->getGrabber(),
|
appInstance->getVoxels(),
|
||||||
SLOT(cycleVideoSendMode()));
|
SLOT(falseColorizeOccluded()));
|
||||||
addCheckableActionToQMenuAndActionHash(developerMenu,
|
|
||||||
MenuOption::WebcamTexture,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
appInstance->getWebcam()->getGrabber(),
|
|
||||||
SLOT(setDepthOnly(bool)));
|
|
||||||
|
|
||||||
addCheckableActionToQMenuAndActionHash(developerMenu,
|
addActionToQMenuAndActionHash(renderDebugMenu,
|
||||||
MenuOption::FaceshiftTCP,
|
MenuOption::FalseColorOccludedV2,
|
||||||
0,
|
0,
|
||||||
false,
|
appInstance->getVoxels(),
|
||||||
appInstance->getFaceshift(),
|
SLOT(falseColorizeOccludedV2()));
|
||||||
SLOT(setTCPEnabled(bool)));
|
|
||||||
|
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");
|
QMenu* audioDebugMenu = developerMenu->addMenu("Audio Debugging Tools");
|
||||||
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoAudio);
|
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoAudio);
|
||||||
|
@ -407,47 +435,38 @@ Menu::Menu() :
|
||||||
appInstance,
|
appInstance,
|
||||||
SLOT(setListenModeSingleSource()));
|
SLOT(setListenModeSingleSource()));
|
||||||
|
|
||||||
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::TestPing, 0, true);
|
QMenu* voxelProtoOptionsMenu = developerMenu->addMenu("Voxel Server Protocol Options");
|
||||||
|
|
||||||
addCheckableActionToQMenuAndActionHash(developerMenu,
|
addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu,
|
||||||
MenuOption::SendVoxelColors,
|
MenuOption::SendVoxelColors,
|
||||||
0,
|
0,
|
||||||
true,
|
true,
|
||||||
appInstance->getAvatar(),
|
appInstance->getAvatar(),
|
||||||
SLOT(setWantColor(bool)));
|
SLOT(setWantColor(bool)));
|
||||||
|
|
||||||
addCheckableActionToQMenuAndActionHash(developerMenu,
|
addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu,
|
||||||
MenuOption::LowRes,
|
MenuOption::LowRes,
|
||||||
0,
|
0,
|
||||||
true,
|
true,
|
||||||
appInstance->getAvatar(),
|
appInstance->getAvatar(),
|
||||||
SLOT(setWantLowResMoving(bool)));
|
SLOT(setWantLowResMoving(bool)));
|
||||||
|
|
||||||
addCheckableActionToQMenuAndActionHash(developerMenu,
|
addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu,
|
||||||
MenuOption::DeltaSending,
|
MenuOption::DeltaSending,
|
||||||
0,
|
0,
|
||||||
true,
|
true,
|
||||||
appInstance->getAvatar(),
|
appInstance->getAvatar(),
|
||||||
SLOT(setWantDelta(bool)));
|
SLOT(setWantDelta(bool)));
|
||||||
|
|
||||||
addCheckableActionToQMenuAndActionHash(developerMenu,
|
addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu,
|
||||||
MenuOption::OcclusionCulling,
|
MenuOption::OcclusionCulling,
|
||||||
Qt::SHIFT | Qt::Key_C,
|
Qt::SHIFT | Qt::Key_C,
|
||||||
true,
|
true,
|
||||||
appInstance->getAvatar(),
|
appInstance->getAvatar(),
|
||||||
SLOT(setWantOcclusionCulling(bool)));
|
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
|
#ifndef Q_OS_MAC
|
||||||
QMenu* helpMenu = addMenu("Help");
|
QMenu* helpMenu = addMenu("Help");
|
||||||
QAction* helpAction = helpMenu->addAction(MenuOption::AboutApp);
|
QAction* helpAction = helpMenu->addAction(MenuOption::AboutApp);
|
||||||
|
@ -469,6 +488,7 @@ void Menu::loadSettings(QSettings* settings) {
|
||||||
_gyroCameraSensitivity = loadSetting(settings, "gyroCameraSensitivity", 0.5f);
|
_gyroCameraSensitivity = loadSetting(settings, "gyroCameraSensitivity", 0.5f);
|
||||||
_audioJitterBufferSamples = loadSetting(settings, "audioJitterBufferSamples", 0);
|
_audioJitterBufferSamples = loadSetting(settings, "audioJitterBufferSamples", 0);
|
||||||
_fieldOfView = loadSetting(settings, "fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES);
|
_fieldOfView = loadSetting(settings, "fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES);
|
||||||
|
_maxVoxels = loadSetting(settings, "maxVoxels", DEFAULT_MAX_VOXELS_PER_SYSTEM);
|
||||||
|
|
||||||
settings->beginGroup("View Frustum Offset Camera");
|
settings->beginGroup("View Frustum Offset Camera");
|
||||||
// in case settings is corrupt or missing loadSetting() will check for NaN
|
// in case settings is corrupt or missing loadSetting() will check for NaN
|
||||||
|
@ -492,6 +512,7 @@ void Menu::saveSettings(QSettings* settings) {
|
||||||
settings->setValue("gyroCameraSensitivity", _gyroCameraSensitivity);
|
settings->setValue("gyroCameraSensitivity", _gyroCameraSensitivity);
|
||||||
settings->setValue("audioJitterBufferSamples", _audioJitterBufferSamples);
|
settings->setValue("audioJitterBufferSamples", _audioJitterBufferSamples);
|
||||||
settings->setValue("fieldOfView", _fieldOfView);
|
settings->setValue("fieldOfView", _fieldOfView);
|
||||||
|
settings->setValue("maxVoxels", _maxVoxels);
|
||||||
settings->beginGroup("View Frustum Offset Camera");
|
settings->beginGroup("View Frustum Offset Camera");
|
||||||
settings->setValue("viewFrustumOffsetYaw", _viewFrustumOffset.yaw);
|
settings->setValue("viewFrustumOffsetYaw", _viewFrustumOffset.yaw);
|
||||||
settings->setValue("viewFrustumOffsetPitch", _viewFrustumOffset.pitch);
|
settings->setValue("viewFrustumOffsetPitch", _viewFrustumOffset.pitch);
|
||||||
|
@ -739,9 +760,6 @@ void Menu::editPreferences() {
|
||||||
QFormLayout* form = new QFormLayout();
|
QFormLayout* form = new QFormLayout();
|
||||||
layout->addLayout(form, 1);
|
layout->addLayout(form, 1);
|
||||||
|
|
||||||
QLineEdit* domainServerLineEdit = lineEditForDomainHostname();
|
|
||||||
form->addRow("Domain server:", domainServerLineEdit);
|
|
||||||
|
|
||||||
QLineEdit* avatarURL = new QLineEdit(applicationInstance->getAvatar()->getVoxels()->getVoxelURL().toString());
|
QLineEdit* avatarURL = new QLineEdit(applicationInstance->getAvatar()->getVoxels()->getVoxelURL().toString());
|
||||||
avatarURL->setMinimumWidth(QLINE_MINIMUM_WIDTH);
|
avatarURL->setMinimumWidth(QLINE_MINIMUM_WIDTH);
|
||||||
form->addRow("Avatar URL:", avatarURL);
|
form->addRow("Avatar URL:", avatarURL);
|
||||||
|
@ -773,6 +791,16 @@ void Menu::editPreferences() {
|
||||||
audioJitterBufferSamples->setMinimum(-10000);
|
audioJitterBufferSamples->setMinimum(-10000);
|
||||||
audioJitterBufferSamples->setValue(_audioJitterBufferSamples);
|
audioJitterBufferSamples->setValue(_audioJitterBufferSamples);
|
||||||
form->addRow("Audio Jitter Buffer Samples (0 for automatic):", audioJitterBufferSamples);
|
form->addRow("Audio Jitter Buffer Samples (0 for automatic):", audioJitterBufferSamples);
|
||||||
|
|
||||||
|
QSpinBox* maxVoxels = new QSpinBox();
|
||||||
|
const int MAX_MAX_VOXELS = 5000000;
|
||||||
|
const int MIN_MAX_VOXELS = 0;
|
||||||
|
const int STEP_MAX_VOXELS = 50000;
|
||||||
|
maxVoxels->setMaximum(MAX_MAX_VOXELS);
|
||||||
|
maxVoxels->setMinimum(MIN_MAX_VOXELS);
|
||||||
|
maxVoxels->setSingleStep(STEP_MAX_VOXELS);
|
||||||
|
maxVoxels->setValue(_maxVoxels);
|
||||||
|
form->addRow("Maximum Voxels:", maxVoxels);
|
||||||
|
|
||||||
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||||
dialog.connect(buttons, SIGNAL(accepted()), SLOT(accept()));
|
dialog.connect(buttons, SIGNAL(accepted()), SLOT(accept()));
|
||||||
|
@ -785,8 +813,6 @@ void Menu::editPreferences() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDSHostname(domainServerLineEdit->text());
|
|
||||||
|
|
||||||
QUrl avatarVoxelURL(avatarURL->text());
|
QUrl avatarVoxelURL(avatarURL->text());
|
||||||
applicationInstance->getAvatar()->getVoxels()->setVoxelURL(avatarVoxelURL);
|
applicationInstance->getAvatar()->getVoxels()->setVoxelURL(avatarVoxelURL);
|
||||||
|
|
||||||
|
@ -798,6 +824,8 @@ void Menu::editPreferences() {
|
||||||
applicationInstance->getAvatar()->getHead().setPupilDilation(pupilDilation->value() / (float)pupilDilation->maximum());
|
applicationInstance->getAvatar()->getHead().setPupilDilation(pupilDilation->value() / (float)pupilDilation->maximum());
|
||||||
|
|
||||||
_gyroCameraSensitivity = gyroCameraSensitivity->value();
|
_gyroCameraSensitivity = gyroCameraSensitivity->value();
|
||||||
|
_maxVoxels = maxVoxels->value();
|
||||||
|
applicationInstance->getVoxels()->setMaxVoxels(_maxVoxels);
|
||||||
|
|
||||||
applicationInstance->getAvatar()->setLeanScale(leanScale->value());
|
applicationInstance->getAvatar()->setLeanScale(leanScale->value());
|
||||||
|
|
||||||
|
@ -997,3 +1025,8 @@ void Menu::updateFrustumRenderModeAction() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Menu::switchVoxelShader() {
|
||||||
|
Application::getInstance()->getVoxels()->setUseVoxelShader(isOptionChecked(MenuOption::UseVoxelShader));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,8 @@ public:
|
||||||
FrustumDrawMode getFrustumDrawMode() const { return _frustumDrawMode; }
|
FrustumDrawMode getFrustumDrawMode() const { return _frustumDrawMode; }
|
||||||
ViewFrustumOffset getViewFrustumOffset() const { return _viewFrustumOffset; }
|
ViewFrustumOffset getViewFrustumOffset() const { return _viewFrustumOffset; }
|
||||||
VoxelStatsDialog* getVoxelStatsDialog() const { return _voxelStatsDialog; }
|
VoxelStatsDialog* getVoxelStatsDialog() const { return _voxelStatsDialog; }
|
||||||
|
int getMaxVoxels() const { return _maxVoxels; }
|
||||||
|
|
||||||
|
|
||||||
void handleViewFrustumOffsetKeyModifier(int key);
|
void handleViewFrustumOffsetKeyModifier(int key);
|
||||||
|
|
||||||
|
@ -78,6 +80,7 @@ private slots:
|
||||||
void chooseVoxelPaintColor();
|
void chooseVoxelPaintColor();
|
||||||
void runTests();
|
void runTests();
|
||||||
void resetSwatchColors();
|
void resetSwatchColors();
|
||||||
|
void switchVoxelShader();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Menu* _instance;
|
static Menu* _instance;
|
||||||
|
@ -115,6 +118,7 @@ private:
|
||||||
ViewFrustumOffset _viewFrustumOffset;
|
ViewFrustumOffset _viewFrustumOffset;
|
||||||
QActionGroup* _voxelModeActionsGroup;
|
QActionGroup* _voxelModeActionsGroup;
|
||||||
VoxelStatsDialog* _voxelStatsDialog;
|
VoxelStatsDialog* _voxelStatsDialog;
|
||||||
|
int _maxVoxels;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace MenuOption {
|
namespace MenuOption {
|
||||||
|
@ -201,9 +205,7 @@ namespace MenuOption {
|
||||||
const QString TransmitterDrive = "Transmitter Drive";
|
const QString TransmitterDrive = "Transmitter Drive";
|
||||||
const QString UsePerlinFace = "Use Perlin's Face";
|
const QString UsePerlinFace = "Use Perlin's Face";
|
||||||
const QString Quit = "Quit";
|
const QString Quit = "Quit";
|
||||||
const QString Webcam = "Webcam";
|
const QString UseVoxelShader = "Use Voxel Shader";
|
||||||
const QString WebcamMode = "Cycle Webcam Send Mode";
|
|
||||||
const QString WebcamTexture = "Webcam Texture";
|
|
||||||
const QString Voxels = "Voxels";
|
const QString Voxels = "Voxels";
|
||||||
const QString VoxelAddMode = "Add Voxel Mode";
|
const QString VoxelAddMode = "Add Voxel Mode";
|
||||||
const QString VoxelColorMode = "Color Voxel Mode";
|
const QString VoxelColorMode = "Color Voxel Mode";
|
||||||
|
@ -214,6 +216,9 @@ namespace MenuOption {
|
||||||
const QString VoxelSelectMode = "Select Voxel Mode";
|
const QString VoxelSelectMode = "Select Voxel Mode";
|
||||||
const QString VoxelStats = "Voxel Stats";
|
const QString VoxelStats = "Voxel Stats";
|
||||||
const QString VoxelTextures = "Voxel Textures";
|
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__) */
|
#endif /* defined(__hifi__Menu__) */
|
||||||
|
|
|
@ -74,6 +74,18 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels)
|
||||||
|
|
||||||
connect(_tree, SIGNAL(importSize(float,float,float)), SIGNAL(importSize(float,float,float)));
|
connect(_tree, SIGNAL(importSize(float,float,float)), SIGNAL(importSize(float,float,float)));
|
||||||
connect(_tree, SIGNAL(importProgress(int)), SIGNAL(importProgress(int)));
|
connect(_tree, SIGNAL(importProgress(int)), SIGNAL(importProgress(int)));
|
||||||
|
|
||||||
|
_useVoxelShader = false;
|
||||||
|
_writeVoxelShaderData = NULL;
|
||||||
|
_readVoxelShaderData = NULL;
|
||||||
|
|
||||||
|
_readVerticesArray = NULL;
|
||||||
|
_writeVerticesArray = NULL;
|
||||||
|
_readColorsArray = NULL;
|
||||||
|
_writeColorsArray = NULL;
|
||||||
|
_writeVoxelDirtyArray = NULL;
|
||||||
|
_readVoxelDirtyArray = NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelSystem::nodeDeleted(VoxelNode* node) {
|
void VoxelSystem::nodeDeleted(VoxelNode* node) {
|
||||||
|
@ -119,21 +131,7 @@ void VoxelSystem::clearFreeBufferIndexes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
VoxelSystem::~VoxelSystem() {
|
VoxelSystem::~VoxelSystem() {
|
||||||
if (_initialized) {
|
cleanupVoxelMemory();
|
||||||
// Destroy glBuffers
|
|
||||||
glDeleteBuffers(1, &_vboVerticesID);
|
|
||||||
glDeleteBuffers(1, &_vboNormalsID);
|
|
||||||
glDeleteBuffers(1, &_vboColorsID);
|
|
||||||
glDeleteBuffers(1, &_vboIndicesID);
|
|
||||||
|
|
||||||
delete[] _readVerticesArray;
|
|
||||||
delete[] _writeVerticesArray;
|
|
||||||
delete[] _readColorsArray;
|
|
||||||
delete[] _writeColorsArray;
|
|
||||||
delete[] _writeVoxelDirtyArray;
|
|
||||||
delete[] _readVoxelDirtyArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete _tree;
|
delete _tree;
|
||||||
pthread_mutex_destroy(&_bufferWriteLock);
|
pthread_mutex_destroy(&_bufferWriteLock);
|
||||||
pthread_mutex_destroy(&_treeLock);
|
pthread_mutex_destroy(&_treeLock);
|
||||||
|
@ -141,6 +139,174 @@ VoxelSystem::~VoxelSystem() {
|
||||||
VoxelNode::removeDeleteHook(this);
|
VoxelNode::removeDeleteHook(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VoxelSystem::setMaxVoxels(int maxVoxels) {
|
||||||
|
pthread_mutex_lock(&_bufferWriteLock);
|
||||||
|
bool wasInitialized = _initialized;
|
||||||
|
if (wasInitialized) {
|
||||||
|
cleanupVoxelMemory();
|
||||||
|
}
|
||||||
|
_maxVoxels = maxVoxels;
|
||||||
|
if (wasInitialized) {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&_bufferWriteLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelSystem::setUseVoxelShader(bool useVoxelShader) {
|
||||||
|
pthread_mutex_lock(&_bufferWriteLock);
|
||||||
|
bool wasInitialized = _initialized;
|
||||||
|
if (wasInitialized) {
|
||||||
|
cleanupVoxelMemory();
|
||||||
|
}
|
||||||
|
_useVoxelShader = useVoxelShader;
|
||||||
|
if (wasInitialized) {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&_bufferWriteLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelSystem::cleanupVoxelMemory() {
|
||||||
|
if (_initialized) {
|
||||||
|
if (_useVoxelShader) {
|
||||||
|
// these are used when in VoxelShader mode.
|
||||||
|
glDeleteBuffers(1, &_vboVoxelsID);
|
||||||
|
glDeleteBuffers(1, &_vboVoxelsIndicesID);
|
||||||
|
|
||||||
|
delete[] _writeVoxelShaderData;
|
||||||
|
delete[] _readVoxelShaderData;
|
||||||
|
} else {
|
||||||
|
// Destroy glBuffers
|
||||||
|
glDeleteBuffers(1, &_vboVerticesID);
|
||||||
|
glDeleteBuffers(1, &_vboNormalsID);
|
||||||
|
glDeleteBuffers(1, &_vboColorsID);
|
||||||
|
glDeleteBuffers(1, &_vboIndicesID);
|
||||||
|
|
||||||
|
delete[] _readVerticesArray;
|
||||||
|
delete[] _writeVerticesArray;
|
||||||
|
delete[] _readColorsArray;
|
||||||
|
delete[] _writeColorsArray;
|
||||||
|
delete[] _writeVoxelDirtyArray;
|
||||||
|
delete[] _readVoxelDirtyArray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_initialized = false; // no longer initialized
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelSystem::initVoxelMemory() {
|
||||||
|
if (_useVoxelShader) {
|
||||||
|
GLuint* indicesArray = new GLuint[_maxVoxels];
|
||||||
|
|
||||||
|
// populate the indicesArray
|
||||||
|
// this will not change given new voxels, so we can set it all up now
|
||||||
|
for (int n = 0; n < _maxVoxels; n++) {
|
||||||
|
indicesArray[n] = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bind the indices VBO to the actual indices array
|
||||||
|
glGenBuffers(1, &_vboVoxelsIndicesID);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboVoxelsIndicesID);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, _maxVoxels, indicesArray, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
|
||||||
|
glGenBuffers(1, &_vboVoxelsID);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _vboVoxelsID);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, _maxVoxels * sizeof(VoxelShaderVBOData), NULL, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
// 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];
|
||||||
|
} else {
|
||||||
|
GLuint* indicesArray = new GLuint[INDICES_PER_VOXEL * _maxVoxels];
|
||||||
|
|
||||||
|
// populate the indicesArray
|
||||||
|
// this will not change given new voxels, so we can set it all up now
|
||||||
|
for (int n = 0; n < _maxVoxels; n++) {
|
||||||
|
// fill the indices array
|
||||||
|
int voxelIndexOffset = n * INDICES_PER_VOXEL;
|
||||||
|
GLuint* currentIndicesPos = indicesArray + voxelIndexOffset;
|
||||||
|
int startIndex = (n * VERTICES_PER_VOXEL);
|
||||||
|
|
||||||
|
for (int i = 0; i < INDICES_PER_VOXEL; i++) {
|
||||||
|
// add indices for this side of the cube
|
||||||
|
currentIndicesPos[i] = startIndex + identityIndices[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GLfloat* normalsArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
|
||||||
|
GLfloat* normalsArrayEndPointer = normalsArray;
|
||||||
|
|
||||||
|
// populate the normalsArray
|
||||||
|
for (int n = 0; n < _maxVoxels; n++) {
|
||||||
|
for (int i = 0; i < VERTEX_POINTS_PER_VOXEL; i++) {
|
||||||
|
*(normalsArrayEndPointer++) = identityNormals[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glGenBuffers(1, &_vboVerticesID);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, NULL, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
// VBO for the normalsArray
|
||||||
|
glGenBuffers(1, &_vboNormalsID);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER,
|
||||||
|
VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels,
|
||||||
|
normalsArray, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
// VBO for colorsArray
|
||||||
|
glGenBuffers(1, &_vboColorsID);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * _maxVoxels, NULL, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
// VBO for the indicesArray
|
||||||
|
glGenBuffers(1, &_vboIndicesID);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
||||||
|
INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels,
|
||||||
|
indicesArray, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
// delete the indices and normals arrays that are no longer needed
|
||||||
|
delete[] indicesArray;
|
||||||
|
delete[] normalsArray;
|
||||||
|
|
||||||
|
|
||||||
|
// we will track individual dirty sections with these arrays of bools
|
||||||
|
_writeVoxelDirtyArray = new bool[_maxVoxels];
|
||||||
|
memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
|
||||||
|
_readVoxelDirtyArray = new bool[_maxVoxels];
|
||||||
|
memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
|
||||||
|
|
||||||
|
// prep the data structures for incoming voxel data
|
||||||
|
_writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
|
||||||
|
_readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
|
||||||
|
|
||||||
|
_writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
|
||||||
|
_readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
|
||||||
|
|
||||||
|
|
||||||
|
// create our simple fragment shader if we're the first system to init
|
||||||
|
if (!_perlinModulateProgram.isLinked()) {
|
||||||
|
switchToResourcesParentIfRequired();
|
||||||
|
_perlinModulateProgram.addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/perlin_modulate.vert");
|
||||||
|
_perlinModulateProgram.addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/perlin_modulate.frag");
|
||||||
|
_perlinModulateProgram.link();
|
||||||
|
|
||||||
|
_perlinModulateProgram.bind();
|
||||||
|
_perlinModulateProgram.setUniformValue("permutationNormalTexture", 0);
|
||||||
|
_perlinModulateProgram.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) {
|
void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) {
|
||||||
_tree->loadVoxelsFile(fileName, wantColorRandomizer);
|
_tree->loadVoxelsFile(fileName, wantColorRandomizer);
|
||||||
setupNewVoxelsForDrawing();
|
setupNewVoxelsForDrawing();
|
||||||
|
@ -398,18 +564,24 @@ void VoxelSystem::copyWrittenDataToReadArraysPartialVBOs() {
|
||||||
|
|
||||||
void VoxelSystem::copyWrittenDataSegmentToReadArrays(glBufferIndex segmentStart, glBufferIndex segmentEnd) {
|
void VoxelSystem::copyWrittenDataSegmentToReadArrays(glBufferIndex segmentStart, glBufferIndex segmentEnd) {
|
||||||
int segmentLength = (segmentEnd - segmentStart) + 1;
|
int segmentLength = (segmentEnd - segmentStart) + 1;
|
||||||
|
if (_useVoxelShader) {
|
||||||
|
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);
|
segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
|
||||||
GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
|
||||||
GLfloat* readVerticesAt = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
GLubyte* readColorsAt = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
||||||
GLfloat* writeVerticesAt = _writeVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
GLubyte* writeColorsAt = _writeColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
||||||
memcpy(readVerticesAt, writeVerticesAt, segmentSizeBytes);
|
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) {
|
void VoxelSystem::copyWrittenDataToReadArrays(bool fullVBOs) {
|
||||||
|
@ -532,11 +704,23 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) {
|
||||||
|
|
||||||
void VoxelSystem::updateNodeInArrays(glBufferIndex nodeIndex, const glm::vec3& startVertex,
|
void VoxelSystem::updateNodeInArrays(glBufferIndex nodeIndex, const glm::vec3& startVertex,
|
||||||
float voxelScale, const nodeColor& color) {
|
float voxelScale, const nodeColor& color) {
|
||||||
for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) {
|
|
||||||
GLfloat* writeVerticesAt = _writeVerticesArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL);
|
if (_useVoxelShader) {
|
||||||
GLubyte* writeColorsAt = _writeColorsArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL);
|
VoxelShaderVBOData* writeVerticesAt = &_writeVoxelShaderData[nodeIndex];
|
||||||
*(writeVerticesAt+j) = startVertex[j % 3] + (identityVertices[j] * voxelScale);
|
writeVerticesAt->x = startVertex.x * TREE_SCALE;
|
||||||
*(writeColorsAt +j) = color[j % 3];
|
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];
|
||||||
|
} 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,86 +747,8 @@ void VoxelSystem::init() {
|
||||||
_voxelsInWriteArrays = 0;
|
_voxelsInWriteArrays = 0;
|
||||||
_voxelsInReadArrays = 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
|
// VBO for the verticesArray
|
||||||
glGenBuffers(1, &_vboVerticesID);
|
initVoxelMemory();
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, NULL, GL_DYNAMIC_DRAW);
|
|
||||||
|
|
||||||
// VBO for the normalsArray
|
|
||||||
glGenBuffers(1, &_vboNormalsID);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER,
|
|
||||||
VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels,
|
|
||||||
normalsArray, GL_STATIC_DRAW);
|
|
||||||
|
|
||||||
// VBO for colorsArray
|
|
||||||
glGenBuffers(1, &_vboColorsID);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * _maxVoxels, NULL, GL_DYNAMIC_DRAW);
|
|
||||||
|
|
||||||
// VBO for the indicesArray
|
|
||||||
glGenBuffers(1, &_vboIndicesID);
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID);
|
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
|
||||||
INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels,
|
|
||||||
indicesArray, GL_STATIC_DRAW);
|
|
||||||
|
|
||||||
// delete the indices and normals arrays that are no longer needed
|
|
||||||
delete[] indicesArray;
|
|
||||||
delete[] normalsArray;
|
|
||||||
|
|
||||||
|
|
||||||
// we will track individual dirty sections with these arrays of bools
|
|
||||||
_writeVoxelDirtyArray = new bool[_maxVoxels];
|
|
||||||
memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
|
|
||||||
_readVoxelDirtyArray = new bool[_maxVoxels];
|
|
||||||
memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
|
|
||||||
|
|
||||||
// prep the data structures for incoming voxel data
|
|
||||||
_writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
|
|
||||||
_readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
|
|
||||||
|
|
||||||
_writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
|
|
||||||
_readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
|
|
||||||
|
|
||||||
|
|
||||||
// create our simple fragment shader if we're the first system to init
|
|
||||||
if (!_perlinModulateProgram.isLinked()) {
|
|
||||||
switchToResourcesParentIfRequired();
|
|
||||||
_perlinModulateProgram.addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/perlin_modulate.vert");
|
|
||||||
_perlinModulateProgram.addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/perlin_modulate.frag");
|
|
||||||
_perlinModulateProgram.link();
|
|
||||||
|
|
||||||
_perlinModulateProgram.bind();
|
|
||||||
_perlinModulateProgram.setUniformValue("permutationNormalTexture", 0);
|
|
||||||
_perlinModulateProgram.release();
|
|
||||||
}
|
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -714,17 +820,27 @@ void VoxelSystem::updateVBOs() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelSystem::updateVBOSegment(glBufferIndex segmentStart, glBufferIndex segmentEnd) {
|
void VoxelSystem::updateVBOSegment(glBufferIndex segmentStart, glBufferIndex segmentEnd) {
|
||||||
int segmentLength = (segmentEnd - segmentStart) + 1;
|
if (_useVoxelShader) {
|
||||||
GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
int segmentLength = (segmentEnd - segmentStart) + 1;
|
||||||
GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
GLintptr segmentStartAt = segmentStart * sizeof(VoxelShaderVBOData);
|
||||||
GLfloat* readVerticesFrom = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
GLsizeiptr segmentSizeBytes = segmentLength * sizeof(VoxelShaderVBOData);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
|
void* readVerticesFrom = &_readVoxelShaderData[segmentStart];
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom);
|
|
||||||
segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
|
glBindBuffer(GL_ARRAY_BUFFER, _vboVoxelsID);
|
||||||
segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
|
glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom);
|
||||||
GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
} else {
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
|
int segmentLength = (segmentEnd - segmentStart) + 1;
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelSystem::render(bool texture) {
|
void VoxelSystem::render(bool texture) {
|
||||||
|
@ -734,43 +850,74 @@ void VoxelSystem::render(bool texture) {
|
||||||
pthread_mutex_lock(&_bufferWriteLock);
|
pthread_mutex_lock(&_bufferWriteLock);
|
||||||
|
|
||||||
updateVBOs();
|
updateVBOs();
|
||||||
|
|
||||||
|
if (_useVoxelShader) {
|
||||||
|
|
||||||
// tell OpenGL where to find vertex and color information
|
Application::getInstance()->getVoxelShader().begin();
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
|
||||||
glEnableClientState(GL_NORMAL_ARRAY);
|
|
||||||
glEnableClientState(GL_COLOR_ARRAY);
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
|
//Define this somewhere in your header file
|
||||||
glVertexPointer(3, GL_FLOAT, 0, 0);
|
#define BUFFER_OFFSET(i) ((void*)(i))
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID);
|
glBindBuffer(GL_ARRAY_BUFFER, _vboVoxelsID);
|
||||||
glNormalPointer(GL_FLOAT, 0, 0);
|
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
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboVoxelsIndicesID);
|
||||||
glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0);
|
glDrawElements(GL_POINTS, _voxelsInReadArrays, GL_UNSIGNED_INT, BUFFER_OFFSET(0)); //The starting point of the IBO
|
||||||
|
|
||||||
applyScaleAndBindProgram(texture);
|
// 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);
|
||||||
|
|
||||||
// for performance, enable backface culling
|
// for performance, enable backface culling
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
|
|
||||||
// draw the number of voxels we have
|
// draw the number of voxels we have
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID);
|
||||||
glDrawRangeElementsEXT(GL_TRIANGLES, 0, VERTICES_PER_VOXEL * _voxelsInReadArrays - 1,
|
glDrawRangeElementsEXT(GL_TRIANGLES, 0, VERTICES_PER_VOXEL * _voxelsInReadArrays - 1,
|
||||||
36 * _voxelsInReadArrays, GL_UNSIGNED_INT, 0);
|
36 * _voxelsInReadArrays, GL_UNSIGNED_INT, 0);
|
||||||
|
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
|
|
||||||
removeScaleAndReleaseProgram(texture);
|
removeScaleAndReleaseProgram(texture);
|
||||||
|
|
||||||
// deactivate vertex and color arrays after drawing
|
// deactivate vertex and color arrays after drawing
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
glDisableClientState(GL_NORMAL_ARRAY);
|
||||||
glDisableClientState(GL_COLOR_ARRAY);
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
|
|
||||||
// bind with 0 to switch back to normal operation
|
// bind with 0 to switch back to normal operation
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&_bufferWriteLock);
|
pthread_mutex_unlock(&_bufferWriteLock);
|
||||||
}
|
}
|
||||||
|
@ -1203,7 +1350,7 @@ public:
|
||||||
duplicateVBOIndex(0),
|
duplicateVBOIndex(0),
|
||||||
leafNodes(0)
|
leafNodes(0)
|
||||||
{
|
{
|
||||||
memset(hasIndexFound, false, MAX_VOXELS_PER_SYSTEM * sizeof(bool));
|
memset(hasIndexFound, false, DEFAULT_MAX_VOXELS_PER_SYSTEM * sizeof(bool));
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned long totalNodes;
|
unsigned long totalNodes;
|
||||||
|
@ -1218,7 +1365,7 @@ public:
|
||||||
|
|
||||||
unsigned long expectedMax;
|
unsigned long expectedMax;
|
||||||
|
|
||||||
bool hasIndexFound[MAX_VOXELS_PER_SYSTEM];
|
bool hasIndexFound[DEFAULT_MAX_VOXELS_PER_SYSTEM];
|
||||||
};
|
};
|
||||||
|
|
||||||
bool VoxelSystem::collectStatsForTreesAndVBOsOperation(VoxelNode* node, void* extraData) {
|
bool VoxelSystem::collectStatsForTreesAndVBOsOperation(VoxelNode* node, void* extraData) {
|
||||||
|
@ -1293,7 +1440,7 @@ void VoxelSystem::collectStatsForTreesAndVBOs() {
|
||||||
glBufferIndex minInVBO = GLBUFFER_INDEX_UNKNOWN;
|
glBufferIndex minInVBO = GLBUFFER_INDEX_UNKNOWN;
|
||||||
glBufferIndex maxInVBO = 0;
|
glBufferIndex maxInVBO = 0;
|
||||||
|
|
||||||
for (glBufferIndex i = 0; i < MAX_VOXELS_PER_SYSTEM; i++) {
|
for (glBufferIndex i = 0; i < DEFAULT_MAX_VOXELS_PER_SYSTEM; i++) {
|
||||||
if (args.hasIndexFound[i]) {
|
if (args.hasIndexFound[i]) {
|
||||||
minInVBO = std::min(minInVBO,i);
|
minInVBO = std::min(minInVBO,i);
|
||||||
maxInVBO = std::max(maxInVBO,i);
|
maxInVBO = std::max(maxInVBO,i);
|
||||||
|
|
|
@ -23,15 +23,24 @@
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "world.h"
|
#include "world.h"
|
||||||
|
#include "renderer/VoxelShader.h"
|
||||||
|
|
||||||
class ProgramObject;
|
class ProgramObject;
|
||||||
|
|
||||||
const int NUM_CHILDREN = 8;
|
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 {
|
class VoxelSystem : public NodeData, public VoxelNodeDeleteHook, public NodeListHook {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
VoxelSystem(float treeScale = TREE_SCALE, int maxVoxels = MAX_VOXELS_PER_SYSTEM);
|
VoxelSystem(float treeScale = TREE_SCALE, int maxVoxels = DEFAULT_MAX_VOXELS_PER_SYSTEM);
|
||||||
~VoxelSystem();
|
~VoxelSystem();
|
||||||
|
|
||||||
void setDataSourceID(int dataSourceID) { _dataSourceID = dataSourceID; }
|
void setDataSourceID(int dataSourceID) { _dataSourceID = dataSourceID; }
|
||||||
|
@ -56,6 +65,10 @@ public:
|
||||||
bool readFromSquareARGB32Pixels(const char* filename);
|
bool readFromSquareARGB32Pixels(const char* filename);
|
||||||
bool readFromSchematicFile(const char* filename);
|
bool readFromSchematicFile(const char* filename);
|
||||||
|
|
||||||
|
void setUseVoxelShader(bool useVoxelShader);
|
||||||
|
|
||||||
|
void setMaxVoxels(int maxVoxels);
|
||||||
|
long int getMaxVoxels() const { return _maxVoxels; }
|
||||||
long int getVoxelsCreated();
|
long int getVoxelsCreated();
|
||||||
long int getVoxelsColored();
|
long int getVoxelsColored();
|
||||||
long int getVoxelsBytesRead();
|
long int getVoxelsBytesRead();
|
||||||
|
@ -190,6 +203,16 @@ private:
|
||||||
uint64_t _lastViewCulling;
|
uint64_t _lastViewCulling;
|
||||||
int _lastViewCullingElapsed;
|
int _lastViewCullingElapsed;
|
||||||
|
|
||||||
|
bool getUseVoxelShader();
|
||||||
|
void initVoxelMemory();
|
||||||
|
void cleanupVoxelMemory();
|
||||||
|
|
||||||
|
bool _useVoxelShader;
|
||||||
|
GLuint _vboVoxelsID; /// when using voxel shader, we'll use this VBO
|
||||||
|
GLuint _vboVoxelsIndicesID; /// when using voxel shader, we'll use this VBO for our indexes
|
||||||
|
VoxelShaderVBOData* _writeVoxelShaderData;
|
||||||
|
VoxelShaderVBOData* _readVoxelShaderData;
|
||||||
|
|
||||||
GLuint _vboVerticesID;
|
GLuint _vboVerticesID;
|
||||||
GLuint _vboNormalsID;
|
GLuint _vboNormalsID;
|
||||||
GLuint _vboColorsID;
|
GLuint _vboColorsID;
|
||||||
|
|
69
interface/src/renderer/VoxelShader.cpp
Normal file
69
interface/src/renderer/VoxelShader.cpp
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
//
|
||||||
|
// VoxelShader.cpp
|
||||||
|
// interface
|
||||||
|
//
|
||||||
|
// Created by Brad Hefta-Gaub on 9/22/13.
|
||||||
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
|
|
||||||
|
// include this before QOpenGLFramebufferObject, which includes an earlier version of OpenGL
|
||||||
|
#include "InterfaceConfig.h"
|
||||||
|
|
||||||
|
#include <QOpenGLFramebufferObject>
|
||||||
|
|
||||||
|
#include "Application.h"
|
||||||
|
#include "VoxelShader.h"
|
||||||
|
#include "ProgramObject.h"
|
||||||
|
#include "RenderUtil.h"
|
||||||
|
|
||||||
|
VoxelShader::VoxelShader()
|
||||||
|
: _initialized(false)
|
||||||
|
{
|
||||||
|
_program = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
VoxelShader::~VoxelShader() {
|
||||||
|
if (_initialized) {
|
||||||
|
delete _program;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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_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();
|
||||||
|
return program;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelShader::init() {
|
||||||
|
if (_initialized) {
|
||||||
|
qDebug("[ERROR] TestProgram is already initialized.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switchToResourcesParentIfRequired();
|
||||||
|
_program = createGeometryShaderProgram("voxel");
|
||||||
|
_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelShader::begin() {
|
||||||
|
_program->bind();
|
||||||
|
}
|
||||||
|
|
||||||
|
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__) */
|
|
@ -32,10 +32,10 @@ const float VOXEL_SIZE_SCALE = TREE_SCALE * 400.0f;
|
||||||
const int NUMBER_OF_CHILDREN = 8;
|
const int NUMBER_OF_CHILDREN = 8;
|
||||||
const int MAX_VOXEL_PACKET_SIZE = 1492;
|
const int MAX_VOXEL_PACKET_SIZE = 1492;
|
||||||
const int MAX_TREE_SLICE_BYTES = 26;
|
const int MAX_TREE_SLICE_BYTES = 26;
|
||||||
const int MAX_VOXELS_PER_SYSTEM = 200000;
|
const int DEFAULT_MAX_VOXELS_PER_SYSTEM = 200000;
|
||||||
const int VERTICES_PER_VOXEL = 24;
|
const int VERTICES_PER_VOXEL = 24; // 6 sides * 4 corners per side
|
||||||
const int VERTEX_POINTS_PER_VOXEL = 3 * VERTICES_PER_VOXEL;
|
const int VERTEX_POINTS_PER_VOXEL = 3 * VERTICES_PER_VOXEL; // xyz for each VERTICE_PER_VOXEL
|
||||||
const int INDICES_PER_VOXEL = 3 * 12;
|
const int INDICES_PER_VOXEL = 3 * 12; // 6 sides * 2 triangles per size * 3 vertices per triangle
|
||||||
const int COLOR_VALUES_PER_VOXEL = NUMBER_OF_COLORS * VERTICES_PER_VOXEL;
|
const int COLOR_VALUES_PER_VOXEL = NUMBER_OF_COLORS * VERTICES_PER_VOXEL;
|
||||||
|
|
||||||
typedef unsigned long int glBufferIndex;
|
typedef unsigned long int glBufferIndex;
|
||||||
|
|
Loading…
Reference in a new issue