mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 03:04:33 +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 {
|
||||
_glowEffect.prepare();
|
||||
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
|
@ -541,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) {
|
||||
|
@ -810,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:
|
||||
|
@ -1518,7 +1521,6 @@ void Application::initDisplay() {
|
|||
}
|
||||
|
||||
void Application::init() {
|
||||
_voxels.init();
|
||||
_sharedVoxelSystemViewFrustum.setPosition(glm::vec3(TREE_SCALE / 2.0f,
|
||||
TREE_SCALE / 2.0f,
|
||||
3.0f * TREE_SCALE / 2.0f));
|
||||
|
@ -1539,6 +1541,7 @@ void Application::init() {
|
|||
|
||||
_glowEffect.init();
|
||||
_ambientOcclusionEffect.init();
|
||||
_voxelShader.init();
|
||||
|
||||
_handControl.setScreenDimensions(_glWidget->width(), _glWidget->height());
|
||||
|
||||
|
@ -1569,9 +1572,13 @@ void Application::init() {
|
|||
if (Menu::getInstance()->getAudioJitterBufferSamples() != 0) {
|
||||
_audio.setJitterBufferSamples(Menu::getInstance()->getAudioJitterBufferSamples());
|
||||
}
|
||||
|
||||
qDebug("Loaded settings.\n");
|
||||
|
||||
// Set up VoxelSystem after loading preferences so we can get the desired max voxel count
|
||||
_voxels.setMaxVoxels(Menu::getInstance()->getMaxVoxels());
|
||||
_voxels.init();
|
||||
|
||||
|
||||
Avatar::sendAvatarURLsMessage(_myAvatar.getVoxels()->getVoxelURL(), _myAvatar.getHead().getBlendFace().getModelURL());
|
||||
|
||||
_palette.init(_glWidget->width(), _glWidget->height());
|
||||
|
@ -2565,7 +2572,7 @@ void Application::displaySide(Camera& whichCamera) {
|
|||
if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayFrustum)) {
|
||||
renderViewFrustum(_viewFrustum);
|
||||
}
|
||||
|
||||
|
||||
// render voxel fades if they exist
|
||||
if (_voxelFades.size() > 0) {
|
||||
for(std::vector<VoxelFade>::iterator fade = _voxelFades.begin(); fade != _voxelFades.end();) {
|
||||
|
@ -2810,7 +2817,10 @@ void Application::displayStats() {
|
|||
|
||||
std::stringstream voxelStats;
|
||||
voxelStats.precision(4);
|
||||
voxelStats << "Voxels Rendered: " << _voxels.getVoxelsRendered() / 1000.f << "K Updated: " << _voxels.getVoxelsUpdated()/1000.f << "K";
|
||||
voxelStats << "Voxels Rendered: " << _voxels.getVoxelsRendered() / 1000.f << "K " <<
|
||||
"Updated: " << _voxels.getVoxelsUpdated()/1000.f << "K " <<
|
||||
"Max: " << _voxels.getMaxVoxels()/1000.f << "K ";
|
||||
|
||||
drawtext(10, statsVerticalOffset + 230, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
|
||||
|
||||
voxelStats.str("");
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "renderer/AmbientOcclusionEffect.h"
|
||||
#include "renderer/GeometryCache.h"
|
||||
#include "renderer/GlowEffect.h"
|
||||
#include "renderer/VoxelShader.h"
|
||||
#include "renderer/TextureCache.h"
|
||||
#include "ui/BandwidthDialog.h"
|
||||
#include "ui/ChatEntry.h"
|
||||
|
@ -144,6 +145,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);
|
||||
|
@ -346,6 +349,7 @@ private:
|
|||
|
||||
GlowEffect _glowEffect;
|
||||
AmbientOcclusionEffect _ambientOcclusionEffect;
|
||||
VoxelShader _voxelShader;
|
||||
|
||||
#ifndef _WIN32
|
||||
Audio _audio;
|
||||
|
|
|
@ -49,7 +49,8 @@ Menu::Menu() :
|
|||
_frustumDrawMode(FRUSTUM_DRAW_MODE_ALL),
|
||||
_viewFrustumOffset(DEFAULT_FRUSTUM_OFFSET),
|
||||
_voxelModeActionsGroup(NULL),
|
||||
_voxelStatsDialog(NULL)
|
||||
_voxelStatsDialog(NULL),
|
||||
_maxVoxels(DEFAULT_MAX_VOXELS_PER_SYSTEM)
|
||||
{
|
||||
Application *appInstance = Application::getInstance();
|
||||
|
||||
|
@ -189,50 +190,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);
|
||||
|
@ -242,50 +229,120 @@ 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, 0,
|
||||
false, this, SLOT(switchVoxelShader()));
|
||||
|
||||
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,
|
||||
|
@ -293,12 +350,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);
|
||||
|
@ -338,18 +389,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,
|
||||
|
@ -362,32 +401,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);
|
||||
|
@ -407,47 +435,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);
|
||||
|
@ -469,6 +488,7 @@ void Menu::loadSettings(QSettings* settings) {
|
|||
_gyroCameraSensitivity = loadSetting(settings, "gyroCameraSensitivity", 0.5f);
|
||||
_audioJitterBufferSamples = loadSetting(settings, "audioJitterBufferSamples", 0);
|
||||
_fieldOfView = loadSetting(settings, "fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES);
|
||||
_maxVoxels = loadSetting(settings, "maxVoxels", DEFAULT_MAX_VOXELS_PER_SYSTEM);
|
||||
|
||||
settings->beginGroup("View Frustum Offset Camera");
|
||||
// in case settings is corrupt or missing loadSetting() will check for NaN
|
||||
|
@ -492,6 +512,7 @@ void Menu::saveSettings(QSettings* settings) {
|
|||
settings->setValue("gyroCameraSensitivity", _gyroCameraSensitivity);
|
||||
settings->setValue("audioJitterBufferSamples", _audioJitterBufferSamples);
|
||||
settings->setValue("fieldOfView", _fieldOfView);
|
||||
settings->setValue("maxVoxels", _maxVoxels);
|
||||
settings->beginGroup("View Frustum Offset Camera");
|
||||
settings->setValue("viewFrustumOffsetYaw", _viewFrustumOffset.yaw);
|
||||
settings->setValue("viewFrustumOffsetPitch", _viewFrustumOffset.pitch);
|
||||
|
@ -739,9 +760,6 @@ void Menu::editPreferences() {
|
|||
QFormLayout* form = new QFormLayout();
|
||||
layout->addLayout(form, 1);
|
||||
|
||||
QLineEdit* domainServerLineEdit = lineEditForDomainHostname();
|
||||
form->addRow("Domain server:", domainServerLineEdit);
|
||||
|
||||
QLineEdit* avatarURL = new QLineEdit(applicationInstance->getAvatar()->getVoxels()->getVoxelURL().toString());
|
||||
avatarURL->setMinimumWidth(QLINE_MINIMUM_WIDTH);
|
||||
form->addRow("Avatar URL:", avatarURL);
|
||||
|
@ -773,6 +791,16 @@ void Menu::editPreferences() {
|
|||
audioJitterBufferSamples->setMinimum(-10000);
|
||||
audioJitterBufferSamples->setValue(_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);
|
||||
dialog.connect(buttons, SIGNAL(accepted()), SLOT(accept()));
|
||||
|
@ -785,8 +813,6 @@ void Menu::editPreferences() {
|
|||
return;
|
||||
}
|
||||
|
||||
updateDSHostname(domainServerLineEdit->text());
|
||||
|
||||
QUrl avatarVoxelURL(avatarURL->text());
|
||||
applicationInstance->getAvatar()->getVoxels()->setVoxelURL(avatarVoxelURL);
|
||||
|
||||
|
@ -798,6 +824,8 @@ void Menu::editPreferences() {
|
|||
applicationInstance->getAvatar()->getHead().setPupilDilation(pupilDilation->value() / (float)pupilDilation->maximum());
|
||||
|
||||
_gyroCameraSensitivity = gyroCameraSensitivity->value();
|
||||
_maxVoxels = maxVoxels->value();
|
||||
applicationInstance->getVoxels()->setMaxVoxels(_maxVoxels);
|
||||
|
||||
applicationInstance->getAvatar()->setLeanScale(leanScale->value());
|
||||
|
||||
|
@ -997,3 +1025,8 @@ void Menu::updateFrustumRenderModeAction() {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Menu::switchVoxelShader() {
|
||||
Application::getInstance()->getVoxels()->setUseVoxelShader(isOptionChecked(MenuOption::UseVoxelShader));
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,8 @@ public:
|
|||
FrustumDrawMode getFrustumDrawMode() const { return _frustumDrawMode; }
|
||||
ViewFrustumOffset getViewFrustumOffset() const { return _viewFrustumOffset; }
|
||||
VoxelStatsDialog* getVoxelStatsDialog() const { return _voxelStatsDialog; }
|
||||
int getMaxVoxels() const { return _maxVoxels; }
|
||||
|
||||
|
||||
void handleViewFrustumOffsetKeyModifier(int key);
|
||||
|
||||
|
@ -78,6 +80,7 @@ private slots:
|
|||
void chooseVoxelPaintColor();
|
||||
void runTests();
|
||||
void resetSwatchColors();
|
||||
void switchVoxelShader();
|
||||
|
||||
private:
|
||||
static Menu* _instance;
|
||||
|
@ -115,6 +118,7 @@ private:
|
|||
ViewFrustumOffset _viewFrustumOffset;
|
||||
QActionGroup* _voxelModeActionsGroup;
|
||||
VoxelStatsDialog* _voxelStatsDialog;
|
||||
int _maxVoxels;
|
||||
};
|
||||
|
||||
namespace MenuOption {
|
||||
|
@ -201,9 +205,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 +216,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,18 @@ 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)));
|
||||
|
||||
_useVoxelShader = false;
|
||||
_writeVoxelShaderData = NULL;
|
||||
_readVoxelShaderData = NULL;
|
||||
|
||||
_readVerticesArray = NULL;
|
||||
_writeVerticesArray = NULL;
|
||||
_readColorsArray = NULL;
|
||||
_writeColorsArray = NULL;
|
||||
_writeVoxelDirtyArray = NULL;
|
||||
_readVoxelDirtyArray = NULL;
|
||||
|
||||
}
|
||||
|
||||
void VoxelSystem::nodeDeleted(VoxelNode* node) {
|
||||
|
@ -119,21 +131,7 @@ void VoxelSystem::clearFreeBufferIndexes() {
|
|||
}
|
||||
|
||||
VoxelSystem::~VoxelSystem() {
|
||||
if (_initialized) {
|
||||
// Destroy glBuffers
|
||||
glDeleteBuffers(1, &_vboVerticesID);
|
||||
glDeleteBuffers(1, &_vboNormalsID);
|
||||
glDeleteBuffers(1, &_vboColorsID);
|
||||
glDeleteBuffers(1, &_vboIndicesID);
|
||||
|
||||
delete[] _readVerticesArray;
|
||||
delete[] _writeVerticesArray;
|
||||
delete[] _readColorsArray;
|
||||
delete[] _writeColorsArray;
|
||||
delete[] _writeVoxelDirtyArray;
|
||||
delete[] _readVoxelDirtyArray;
|
||||
}
|
||||
|
||||
cleanupVoxelMemory();
|
||||
delete _tree;
|
||||
pthread_mutex_destroy(&_bufferWriteLock);
|
||||
pthread_mutex_destroy(&_treeLock);
|
||||
|
@ -141,6 +139,174 @@ VoxelSystem::~VoxelSystem() {
|
|||
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) {
|
||||
_tree->loadVoxelsFile(fileName, wantColorRandomizer);
|
||||
setupNewVoxelsForDrawing();
|
||||
|
@ -398,18 +564,24 @@ void VoxelSystem::copyWrittenDataToReadArraysPartialVBOs() {
|
|||
|
||||
void VoxelSystem::copyWrittenDataSegmentToReadArrays(glBufferIndex segmentStart, glBufferIndex segmentEnd) {
|
||||
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);
|
||||
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 +704,23 @@ 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 (_useVoxelShader) {
|
||||
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];
|
||||
} 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;
|
||||
_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);
|
||||
|
||||
// VBO for the normalsArray
|
||||
glGenBuffers(1, &_vboNormalsID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID);
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels,
|
||||
normalsArray, GL_STATIC_DRAW);
|
||||
|
||||
// VBO for colorsArray
|
||||
glGenBuffers(1, &_vboColorsID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
|
||||
glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * _maxVoxels, NULL, GL_DYNAMIC_DRAW);
|
||||
|
||||
// VBO for the indicesArray
|
||||
glGenBuffers(1, &_vboIndicesID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
||||
INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels,
|
||||
indicesArray, GL_STATIC_DRAW);
|
||||
|
||||
// delete the indices and normals arrays that are no longer needed
|
||||
delete[] indicesArray;
|
||||
delete[] normalsArray;
|
||||
|
||||
|
||||
// we will track individual dirty sections with these arrays of bools
|
||||
_writeVoxelDirtyArray = new bool[_maxVoxels];
|
||||
memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
|
||||
_readVoxelDirtyArray = new bool[_maxVoxels];
|
||||
memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
|
||||
|
||||
// prep the data structures for incoming voxel data
|
||||
_writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
|
||||
_readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
|
||||
|
||||
_writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
|
||||
_readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
|
||||
|
||||
|
||||
// create our simple fragment shader if we're the first system to init
|
||||
if (!_perlinModulateProgram.isLinked()) {
|
||||
switchToResourcesParentIfRequired();
|
||||
_perlinModulateProgram.addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/perlin_modulate.vert");
|
||||
_perlinModulateProgram.addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/perlin_modulate.frag");
|
||||
_perlinModulateProgram.link();
|
||||
|
||||
_perlinModulateProgram.bind();
|
||||
_perlinModulateProgram.setUniformValue("permutationNormalTexture", 0);
|
||||
_perlinModulateProgram.release();
|
||||
}
|
||||
initVoxelMemory();
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
|
@ -714,17 +820,27 @@ 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 (_useVoxelShader) {
|
||||
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);
|
||||
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) {
|
||||
|
@ -734,43 +850,74 @@ void VoxelSystem::render(bool texture) {
|
|||
pthread_mutex_lock(&_bufferWriteLock);
|
||||
|
||||
updateVBOs();
|
||||
|
||||
if (_useVoxelShader) {
|
||||
|
||||
// tell OpenGL where to find vertex and color information
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
Application::getInstance()->getVoxelShader().begin();
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
|
||||
glVertexPointer(3, GL_FLOAT, 0, 0);
|
||||
//Define this somewhere in your header file
|
||||
#define BUFFER_OFFSET(i) ((void*)(i))
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID);
|
||||
glNormalPointer(GL_FLOAT, 0, 0);
|
||||
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
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
|
||||
glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboVoxelsIndicesID);
|
||||
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
|
||||
glEnable(GL_CULL_FACE);
|
||||
// for performance, enable backface culling
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
// 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);
|
||||
// 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);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
removeScaleAndReleaseProgram(texture);
|
||||
removeScaleAndReleaseProgram(texture);
|
||||
|
||||
// deactivate vertex and color arrays after drawing
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
// 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);
|
||||
// bind with 0 to switch back to normal operation
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&_bufferWriteLock);
|
||||
}
|
||||
|
@ -1203,7 +1350,7 @@ public:
|
|||
duplicateVBOIndex(0),
|
||||
leafNodes(0)
|
||||
{
|
||||
memset(hasIndexFound, false, MAX_VOXELS_PER_SYSTEM * sizeof(bool));
|
||||
memset(hasIndexFound, false, DEFAULT_MAX_VOXELS_PER_SYSTEM * sizeof(bool));
|
||||
};
|
||||
|
||||
unsigned long totalNodes;
|
||||
|
@ -1218,7 +1365,7 @@ public:
|
|||
|
||||
unsigned long expectedMax;
|
||||
|
||||
bool hasIndexFound[MAX_VOXELS_PER_SYSTEM];
|
||||
bool hasIndexFound[DEFAULT_MAX_VOXELS_PER_SYSTEM];
|
||||
};
|
||||
|
||||
bool VoxelSystem::collectStatsForTreesAndVBOsOperation(VoxelNode* node, void* extraData) {
|
||||
|
@ -1293,7 +1440,7 @@ void VoxelSystem::collectStatsForTreesAndVBOs() {
|
|||
glBufferIndex minInVBO = GLBUFFER_INDEX_UNKNOWN;
|
||||
glBufferIndex maxInVBO = 0;
|
||||
|
||||
for (glBufferIndex i = 0; i < MAX_VOXELS_PER_SYSTEM; i++) {
|
||||
for (glBufferIndex i = 0; i < DEFAULT_MAX_VOXELS_PER_SYSTEM; i++) {
|
||||
if (args.hasIndexFound[i]) {
|
||||
minInVBO = std::min(minInVBO,i);
|
||||
maxInVBO = std::max(maxInVBO,i);
|
||||
|
|
|
@ -23,15 +23,24 @@
|
|||
#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:
|
||||
VoxelSystem(float treeScale = TREE_SCALE, int maxVoxels = MAX_VOXELS_PER_SYSTEM);
|
||||
VoxelSystem(float treeScale = TREE_SCALE, int maxVoxels = DEFAULT_MAX_VOXELS_PER_SYSTEM);
|
||||
~VoxelSystem();
|
||||
|
||||
void setDataSourceID(int dataSourceID) { _dataSourceID = dataSourceID; }
|
||||
|
@ -56,6 +65,10 @@ public:
|
|||
bool readFromSquareARGB32Pixels(const char* filename);
|
||||
bool readFromSchematicFile(const char* filename);
|
||||
|
||||
void setUseVoxelShader(bool useVoxelShader);
|
||||
|
||||
void setMaxVoxels(int maxVoxels);
|
||||
long int getMaxVoxels() const { return _maxVoxels; }
|
||||
long int getVoxelsCreated();
|
||||
long int getVoxelsColored();
|
||||
long int getVoxelsBytesRead();
|
||||
|
@ -190,6 +203,16 @@ private:
|
|||
uint64_t _lastViewCulling;
|
||||
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 _vboNormalsID;
|
||||
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 MAX_VOXEL_PACKET_SIZE = 1492;
|
||||
const int MAX_TREE_SLICE_BYTES = 26;
|
||||
const int MAX_VOXELS_PER_SYSTEM = 200000;
|
||||
const int VERTICES_PER_VOXEL = 24;
|
||||
const int VERTEX_POINTS_PER_VOXEL = 3 * VERTICES_PER_VOXEL;
|
||||
const int INDICES_PER_VOXEL = 3 * 12;
|
||||
const int DEFAULT_MAX_VOXELS_PER_SYSTEM = 200000;
|
||||
const int VERTICES_PER_VOXEL = 24; // 6 sides * 4 corners per side
|
||||
const int VERTEX_POINTS_PER_VOXEL = 3 * VERTICES_PER_VOXEL; // xyz for each VERTICE_PER_VOXEL
|
||||
const int INDICES_PER_VOXEL = 3 * 12; // 6 sides * 2 triangles per size * 3 vertices per triangle
|
||||
const int COLOR_VALUES_PER_VOXEL = NUMBER_OF_COLORS * VERTICES_PER_VOXEL;
|
||||
|
||||
typedef unsigned long int glBufferIndex;
|
||||
|
|
Loading…
Reference in a new issue