menu cleanup, support for on the fly switching of maxVoxels and useVoxelShader

This commit is contained in:
ZappoMan 2013-09-26 16:26:49 -07:00
parent 552d9fadd8
commit 7845340279
6 changed files with 237 additions and 159 deletions

View file

@ -1521,7 +1521,6 @@ void Application::initDisplay() {
}
void Application::init() {
_voxels.init();
_sharedVoxelSystemViewFrustum.setPosition(glm::vec3(TREE_SCALE / 2.0f,
TREE_SCALE / 2.0f,
3.0f * TREE_SCALE / 2.0f));
@ -1573,9 +1572,13 @@ void Application::init() {
if (Menu::getInstance()->getAudioJitterBufferSamples() != 0) {
_audio.setJitterBufferSamples(Menu::getInstance()->getAudioJitterBufferSamples());
}
qDebug("Loaded settings.\n");
// Set up VoxelSystem after loading preferences so we can get the desired max voxel count
_voxels.setMaxVoxels(Menu::getInstance()->getMaxVoxels());
_voxels.init();
Avatar::sendAvatarURLsMessage(_myAvatar.getVoxels()->getVoxelURL(), _myAvatar.getHead().getBlendFace().getModelURL());
_palette.init(_glWidget->width(), _glWidget->height());
@ -2915,7 +2918,10 @@ void Application::displayStats() {
std::stringstream voxelStats;
voxelStats.precision(4);
voxelStats << "Voxels Rendered: " << _voxels.getVoxelsRendered() / 1000.f << "K Updated: " << _voxels.getVoxelsUpdated()/1000.f << "K";
voxelStats << "Voxels Rendered: " << _voxels.getVoxelsRendered() / 1000.f << "K " <<
"Updated: " << _voxels.getVoxelsUpdated()/1000.f << "K " <<
"Max: " << _voxels.getMaxVoxels()/1000.f << "K ";
drawtext(10, statsVerticalOffset + 230, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
voxelStats.str("");

View file

@ -48,7 +48,8 @@ Menu::Menu() :
_frustumDrawMode(FRUSTUM_DRAW_MODE_ALL),
_viewFrustumOffset(DEFAULT_FRUSTUM_OFFSET),
_voxelModeActionsGroup(NULL),
_voxelStatsDialog(NULL)
_voxelStatsDialog(NULL),
_maxVoxels(DEFAULT_MAX_VOXELS_PER_SYSTEM)
{
Application *appInstance = Application::getInstance();
@ -249,7 +250,8 @@ Menu::Menu() :
SLOT(setRenderVoxels(bool)));
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelTextures);
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AmbientOcclusion);
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::UseVoxelShader);
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::UseVoxelShader, 0,
false, this, SLOT(switchVoxelShader()));
QMenu* avatarOptionsMenu = developerMenu->addMenu("Avatar Options");
@ -485,6 +487,7 @@ void Menu::loadSettings(QSettings* settings) {
_gyroCameraSensitivity = loadSetting(settings, "gyroCameraSensitivity", 0.5f);
_audioJitterBufferSamples = loadSetting(settings, "audioJitterBufferSamples", 0);
_fieldOfView = loadSetting(settings, "fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES);
_maxVoxels = loadSetting(settings, "maxVoxels", DEFAULT_MAX_VOXELS_PER_SYSTEM);
settings->beginGroup("View Frustum Offset Camera");
// in case settings is corrupt or missing loadSetting() will check for NaN
@ -508,6 +511,7 @@ void Menu::saveSettings(QSettings* settings) {
settings->setValue("gyroCameraSensitivity", _gyroCameraSensitivity);
settings->setValue("audioJitterBufferSamples", _audioJitterBufferSamples);
settings->setValue("fieldOfView", _fieldOfView);
settings->setValue("maxVoxels", _maxVoxels);
settings->beginGroup("View Frustum Offset Camera");
settings->setValue("viewFrustumOffsetYaw", _viewFrustumOffset.yaw);
settings->setValue("viewFrustumOffsetPitch", _viewFrustumOffset.pitch);
@ -755,9 +759,6 @@ void Menu::editPreferences() {
QFormLayout* form = new QFormLayout();
layout->addLayout(form, 1);
QLineEdit* domainServerLineEdit = lineEditForDomainHostname();
form->addRow("Domain server:", domainServerLineEdit);
QLineEdit* avatarURL = new QLineEdit(applicationInstance->getAvatar()->getVoxels()->getVoxelURL().toString());
avatarURL->setMinimumWidth(QLINE_MINIMUM_WIDTH);
form->addRow("Avatar URL:", avatarURL);
@ -785,6 +786,13 @@ void Menu::editPreferences() {
audioJitterBufferSamples->setMinimum(-10000);
audioJitterBufferSamples->setValue(_audioJitterBufferSamples);
form->addRow("Audio Jitter Buffer Samples (0 for automatic):", audioJitterBufferSamples);
QSpinBox* maxVoxels = new QSpinBox();
maxVoxels->setMaximum(5000000);
maxVoxels->setMinimum(0);
maxVoxels->setSingleStep(50000);
maxVoxels->setValue(_maxVoxels);
form->addRow("Maximum Voxels:", maxVoxels);
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
dialog.connect(buttons, SIGNAL(accepted()), SLOT(accept()));
@ -797,8 +805,6 @@ void Menu::editPreferences() {
return;
}
updateDSHostname(domainServerLineEdit->text());
QUrl avatarVoxelURL(avatarURL->text());
applicationInstance->getAvatar()->getVoxels()->setVoxelURL(avatarVoxelURL);
@ -808,6 +814,8 @@ void Menu::editPreferences() {
Avatar::sendAvatarURLsMessage(avatarVoxelURL, faceModelURL);
_gyroCameraSensitivity = gyroCameraSensitivity->value();
_maxVoxels = maxVoxels->value();
applicationInstance->getVoxels()->setMaxVoxels(_maxVoxels);
applicationInstance->getAvatar()->setLeanScale(leanScale->value());
@ -1007,3 +1015,32 @@ void Menu::updateFrustumRenderModeAction() {
break;
}
}
void Menu::switchVoxelShader() {
Application::getInstance()->getVoxels()->setUseVoxelShader(isOptionChecked(MenuOption::UseVoxelShader));
}
void Menu::displayGPUMemory() {
const int NUM_RESULTS = 4; // see notes, these APIs return up to 4 results
GLint results[NUM_RESULTS] = { 0, 0, 0, 0};
// ATI
// http://www.opengl.org/registry/specs/ATI/meminfo.txt
//
// TEXTURE_FREE_MEMORY_ATI 0x87FC
// RENDERBUFFER_FREE_MEMORY_ATI 0x87FD
const GLenum VBO_FREE_MEMORY_ATI = 0x87FB;
glGetIntegerv(VBO_FREE_MEMORY_ATI, &results[0]);
// NVIDIA
// http://developer.download.nvidia.com/opengl/specs/GL_NVX_gpu_memory_info.txt
//
// GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047
// GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048
// GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049
// GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A
// GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B
}

View file

@ -54,6 +54,8 @@ public:
FrustumDrawMode getFrustumDrawMode() const { return _frustumDrawMode; }
ViewFrustumOffset getViewFrustumOffset() const { return _viewFrustumOffset; }
VoxelStatsDialog* getVoxelStatsDialog() const { return _voxelStatsDialog; }
int getMaxVoxels() const { return _maxVoxels; }
void handleViewFrustumOffsetKeyModifier(int key);
@ -78,6 +80,8 @@ private slots:
void chooseVoxelPaintColor();
void runTests();
void resetSwatchColors();
void displayGPUMemory();
void switchVoxelShader();
private:
static Menu* _instance;
@ -115,6 +119,7 @@ private:
ViewFrustumOffset _viewFrustumOffset;
QActionGroup* _voxelModeActionsGroup;
VoxelStatsDialog* _voxelStatsDialog;
int _maxVoxels;
};
namespace MenuOption {

View file

@ -74,9 +74,8 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels)
connect(_tree, SIGNAL(importSize(float,float,float)), SIGNAL(importSize(float,float,float)));
connect(_tree, SIGNAL(importProgress(int)), SIGNAL(importProgress(int)));
_voxelShaderInitialized = false;
_initializingVoxelShader = false;
_useVoxelShader = false;
_writeVoxelShaderData = NULL;
_readVoxelShaderData = NULL;
@ -132,28 +131,7 @@ void VoxelSystem::clearFreeBufferIndexes() {
}
VoxelSystem::~VoxelSystem() {
if (_initialized) {
// Destroy glBuffers
glDeleteBuffers(1, &_vboVerticesID);
glDeleteBuffers(1, &_vboNormalsID);
glDeleteBuffers(1, &_vboColorsID);
glDeleteBuffers(1, &_vboIndicesID);
delete[] _readVerticesArray;
delete[] _writeVerticesArray;
delete[] _readColorsArray;
delete[] _writeColorsArray;
delete[] _writeVoxelDirtyArray;
delete[] _readVoxelDirtyArray;
// these are used when in VoxelShader mode.
glDeleteBuffers(1, &_vboVoxelsID);
glDeleteBuffers(1, &_vboVoxelsIndicesID);
delete[] _writeVoxelShaderData;
delete[] _readVoxelShaderData;
}
cleanupVoxelMemory();
delete _tree;
pthread_mutex_destroy(&_bufferWriteLock);
pthread_mutex_destroy(&_treeLock);
@ -161,43 +139,172 @@ VoxelSystem::~VoxelSystem() {
VoxelNode::removeDeleteHook(this);
}
bool VoxelSystem::getUseVoxelShader() {
bool useVoxelShader = false; //Menu::getInstance()->isOptionChecked(MenuOption::UseVoxelShader);
return useVoxelShader;
void VoxelSystem::setMaxVoxels(int maxVoxels) {
pthread_mutex_lock(&_bufferWriteLock);
bool wasInitialized = _initialized;
if (wasInitialized) {
cleanupVoxelMemory();
}
_maxVoxels = maxVoxels;
if (wasInitialized) {
init();
}
pthread_mutex_unlock(&_bufferWriteLock);
}
void VoxelSystem::initVoxelShader() {
GLuint* indicesArray = new GLuint[_maxVoxels];
// populate the indicesArray
// this will not change given new voxels, so we can set it all up now
for (int n = 0; n < _maxVoxels; n++) {
indicesArray[n] = n;
void VoxelSystem::setUseVoxelShader(bool useVoxelShader) {
pthread_mutex_lock(&_bufferWriteLock);
bool wasInitialized = _initialized;
if (wasInitialized) {
cleanupVoxelMemory();
}
_useVoxelShader = useVoxelShader;
if (wasInitialized) {
init();
}
pthread_mutex_unlock(&_bufferWriteLock);
}
// bind the indices VBO to the actual indices array
glGenBuffers(1, &_vboVoxelsIndicesID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboVoxelsIndicesID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, _maxVoxels, indicesArray, GL_STATIC_DRAW);
void VoxelSystem::cleanupVoxelMemory() {
if (_initialized) {
if (_useVoxelShader) {
// these are used when in VoxelShader mode.
glDeleteBuffers(1, &_vboVoxelsID);
glDeleteBuffers(1, &_vboVoxelsIndicesID);
delete[] _writeVoxelShaderData;
delete[] _readVoxelShaderData;
} else {
// Destroy glBuffers
glDeleteBuffers(1, &_vboVerticesID);
glDeleteBuffers(1, &_vboNormalsID);
glDeleteBuffers(1, &_vboColorsID);
glDeleteBuffers(1, &_vboIndicesID);
delete[] _readVerticesArray;
delete[] _writeVerticesArray;
delete[] _readColorsArray;
delete[] _writeColorsArray;
delete[] _writeVoxelDirtyArray;
delete[] _readVoxelDirtyArray;
}
}
_initialized = false; // no longer initialized
}
void VoxelSystem::initVoxelMemory() {
if (_useVoxelShader) {
GLuint* indicesArray = new GLuint[_maxVoxels];
// populate the indicesArray
// this will not change given new voxels, so we can set it all up now
for (int n = 0; n < _maxVoxels; n++) {
indicesArray[n] = n;
}
// bind the indices VBO to the actual indices array
glGenBuffers(1, &_vboVoxelsIndicesID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboVoxelsIndicesID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, _maxVoxels, indicesArray, GL_STATIC_DRAW);
glGenBuffers(1, &_vboVoxelsID);
glBindBuffer(GL_ARRAY_BUFFER, _vboVoxelsID);
glBufferData(GL_ARRAY_BUFFER, _maxVoxels * sizeof(VoxelShaderVBOData), NULL, GL_DYNAMIC_DRAW);
glGenBuffers(1, &_vboVoxelsID);
glBindBuffer(GL_ARRAY_BUFFER, _vboVoxelsID);
glBufferData(GL_ARRAY_BUFFER, _maxVoxels * sizeof(VoxelShaderVBOData), NULL, GL_DYNAMIC_DRAW);
// delete the indices and normals arrays that are no longer needed
delete[] indicesArray;
// delete the indices and normals arrays that are no longer needed
delete[] indicesArray;
// we will track individual dirty sections with these arrays of bools
_writeVoxelDirtyArray = new bool[_maxVoxels];
memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
_readVoxelDirtyArray = new bool[_maxVoxels];
memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
// we will track individual dirty sections with these arrays of bools
_writeVoxelDirtyArray = new bool[_maxVoxels];
memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
_readVoxelDirtyArray = new bool[_maxVoxels];
memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
// prep the data structures for incoming voxel data
_writeVoxelShaderData = new VoxelShaderVBOData[_maxVoxels];
_readVoxelShaderData = new VoxelShaderVBOData[_maxVoxels];
// prep the data structures for incoming voxel data
_writeVoxelShaderData = new VoxelShaderVBOData[_maxVoxels];
_readVoxelShaderData = new VoxelShaderVBOData[_maxVoxels];
} else {
GLuint* indicesArray = new GLuint[INDICES_PER_VOXEL * _maxVoxels];
// populate the indicesArray
// this will not change given new voxels, so we can set it all up now
for (int n = 0; n < _maxVoxels; n++) {
// fill the indices array
int voxelIndexOffset = n * INDICES_PER_VOXEL;
GLuint* currentIndicesPos = indicesArray + voxelIndexOffset;
int startIndex = (n * VERTICES_PER_VOXEL);
for (int i = 0; i < INDICES_PER_VOXEL; i++) {
// add indices for this side of the cube
currentIndicesPos[i] = startIndex + identityIndices[i];
}
}
GLfloat* normalsArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
GLfloat* normalsArrayEndPointer = normalsArray;
// populate the normalsArray
for (int n = 0; n < _maxVoxels; n++) {
for (int i = 0; i < VERTEX_POINTS_PER_VOXEL; i++) {
*(normalsArrayEndPointer++) = identityNormals[i];
}
}
glGenBuffers(1, &_vboVerticesID);
glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, NULL, GL_DYNAMIC_DRAW);
// VBO for the normalsArray
glGenBuffers(1, &_vboNormalsID);
glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID);
glBufferData(GL_ARRAY_BUFFER,
VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels,
normalsArray, GL_STATIC_DRAW);
// VBO for colorsArray
glGenBuffers(1, &_vboColorsID);
glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * _maxVoxels, NULL, GL_DYNAMIC_DRAW);
// VBO for the indicesArray
glGenBuffers(1, &_vboIndicesID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels,
indicesArray, GL_STATIC_DRAW);
// delete the indices and normals arrays that are no longer needed
delete[] indicesArray;
delete[] normalsArray;
// we will track individual dirty sections with these arrays of bools
_writeVoxelDirtyArray = new bool[_maxVoxels];
memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
_readVoxelDirtyArray = new bool[_maxVoxels];
memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
// prep the data structures for incoming voxel data
_writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
_readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
_writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
_readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
// create our simple fragment shader if we're the first system to init
if (!_perlinModulateProgram.isLinked()) {
switchToResourcesParentIfRequired();
_perlinModulateProgram.addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/perlin_modulate.vert");
_perlinModulateProgram.addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/perlin_modulate.frag");
_perlinModulateProgram.link();
_perlinModulateProgram.bind();
_perlinModulateProgram.setUniformValue("permutationNormalTexture", 0);
_perlinModulateProgram.release();
}
}
}
void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) {
@ -457,7 +564,7 @@ void VoxelSystem::copyWrittenDataToReadArraysPartialVBOs() {
void VoxelSystem::copyWrittenDataSegmentToReadArrays(glBufferIndex segmentStart, glBufferIndex segmentEnd) {
int segmentLength = (segmentEnd - segmentStart) + 1;
if (getUseVoxelShader()) {
if (_useVoxelShader) {
GLsizeiptr segmentSizeBytes = segmentLength * sizeof(VoxelShaderVBOData);
void* readDataAt = &_readVoxelShaderData[segmentStart];
void* writeDataAt = &_writeVoxelShaderData[segmentStart];
@ -598,7 +705,7 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) {
void VoxelSystem::updateNodeInArrays(glBufferIndex nodeIndex, const glm::vec3& startVertex,
float voxelScale, const nodeColor& color) {
if (getUseVoxelShader()) {
if (_useVoxelShader) {
VoxelShaderVBOData* writeVerticesAt = &_writeVoxelShaderData[nodeIndex];
writeVerticesAt->x = startVertex.x * TREE_SCALE;
writeVerticesAt->y = startVertex.y * TREE_SCALE;
@ -647,89 +754,7 @@ void VoxelSystem::init() {
_voxelsInReadArrays = 0;
// VBO for the verticesArray
//initVoxelShader();
if (true) {
GLuint* indicesArray = new GLuint[INDICES_PER_VOXEL * _maxVoxels];
// populate the indicesArray
// this will not change given new voxels, so we can set it all up now
for (int n = 0; n < _maxVoxels; n++) {
// fill the indices array
int voxelIndexOffset = n * INDICES_PER_VOXEL;
GLuint* currentIndicesPos = indicesArray + voxelIndexOffset;
int startIndex = (n * VERTICES_PER_VOXEL);
for (int i = 0; i < INDICES_PER_VOXEL; i++) {
// add indices for this side of the cube
currentIndicesPos[i] = startIndex + identityIndices[i];
}
}
GLfloat* normalsArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
GLfloat* normalsArrayEndPointer = normalsArray;
// populate the normalsArray
for (int n = 0; n < _maxVoxels; n++) {
for (int i = 0; i < VERTEX_POINTS_PER_VOXEL; i++) {
*(normalsArrayEndPointer++) = identityNormals[i];
}
}
glGenBuffers(1, &_vboVerticesID);
glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, NULL, GL_DYNAMIC_DRAW);
// VBO for the normalsArray
glGenBuffers(1, &_vboNormalsID);
glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID);
glBufferData(GL_ARRAY_BUFFER,
VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels,
normalsArray, GL_STATIC_DRAW);
// VBO for colorsArray
glGenBuffers(1, &_vboColorsID);
glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * _maxVoxels, NULL, GL_DYNAMIC_DRAW);
// VBO for the indicesArray
glGenBuffers(1, &_vboIndicesID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels,
indicesArray, GL_STATIC_DRAW);
// delete the indices and normals arrays that are no longer needed
delete[] indicesArray;
delete[] normalsArray;
// we will track individual dirty sections with these arrays of bools
_writeVoxelDirtyArray = new bool[_maxVoxels];
memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
_readVoxelDirtyArray = new bool[_maxVoxels];
memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
// prep the data structures for incoming voxel data
_writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
_readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
_writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
_readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
// create our simple fragment shader if we're the first system to init
if (!_perlinModulateProgram.isLinked()) {
switchToResourcesParentIfRequired();
_perlinModulateProgram.addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/perlin_modulate.vert");
_perlinModulateProgram.addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/perlin_modulate.frag");
_perlinModulateProgram.link();
_perlinModulateProgram.bind();
_perlinModulateProgram.setUniformValue("permutationNormalTexture", 0);
_perlinModulateProgram.release();
}
}
initVoxelMemory();
_initialized = true;
}
@ -801,7 +826,7 @@ void VoxelSystem::updateVBOs() {
}
void VoxelSystem::updateVBOSegment(glBufferIndex segmentStart, glBufferIndex segmentEnd) {
if (getUseVoxelShader()) {
if (_useVoxelShader) {
int segmentLength = (segmentEnd - segmentStart) + 1;
GLintptr segmentStartAt = segmentStart * sizeof(VoxelShaderVBOData);
GLsizeiptr segmentSizeBytes = segmentLength * sizeof(VoxelShaderVBOData);
@ -839,9 +864,9 @@ void VoxelSystem::render(bool texture) {
updateVBOs();
//printf("render() _voxelsInReadArrays=%lu voxel shader=%s\n", _voxelsInReadArrays, debug::valueOf(getUseVoxelShader()));
//printf("render() _voxelsInReadArrays=%lu voxel shader=%s\n", _voxelsInReadArrays, debug::valueOf(_useVoxelShader));
if (getUseVoxelShader()) {
if (_useVoxelShader) {
Application::getInstance()->getVoxelShader().begin();
@ -1349,7 +1374,7 @@ public:
duplicateVBOIndex(0),
leafNodes(0)
{
memset(hasIndexFound, false, MAX_VOXELS_PER_SYSTEM * sizeof(bool));
memset(hasIndexFound, false, DEFAULT_MAX_VOXELS_PER_SYSTEM * sizeof(bool));
};
unsigned long totalNodes;
@ -1364,7 +1389,7 @@ public:
unsigned long expectedMax;
bool hasIndexFound[MAX_VOXELS_PER_SYSTEM];
bool hasIndexFound[DEFAULT_MAX_VOXELS_PER_SYSTEM];
};
bool VoxelSystem::collectStatsForTreesAndVBOsOperation(VoxelNode* node, void* extraData) {
@ -1439,7 +1464,7 @@ void VoxelSystem::collectStatsForTreesAndVBOs() {
glBufferIndex minInVBO = GLBUFFER_INDEX_UNKNOWN;
glBufferIndex maxInVBO = 0;
for (glBufferIndex i = 0; i < MAX_VOXELS_PER_SYSTEM; i++) {
for (glBufferIndex i = 0; i < DEFAULT_MAX_VOXELS_PER_SYSTEM; i++) {
if (args.hasIndexFound[i]) {
minInVBO = std::min(minInVBO,i);
maxInVBO = std::max(maxInVBO,i);

View file

@ -40,7 +40,7 @@ struct VoxelShaderVBOData
class VoxelSystem : public NodeData, public VoxelNodeDeleteHook, public NodeListHook {
Q_OBJECT
public:
VoxelSystem(float treeScale = TREE_SCALE, int maxVoxels = MAX_VOXELS_PER_SYSTEM);
VoxelSystem(float treeScale = TREE_SCALE, int maxVoxels = DEFAULT_MAX_VOXELS_PER_SYSTEM);
~VoxelSystem();
void setDataSourceID(int dataSourceID) { _dataSourceID = dataSourceID; }
@ -65,6 +65,10 @@ public:
bool readFromSquareARGB32Pixels(const char* filename);
bool readFromSchematicFile(const char* filename);
void setUseVoxelShader(bool useVoxelShader);
void setMaxVoxels(int maxVoxels);
long int getMaxVoxels() const { return _maxVoxels; }
long int getVoxelsCreated();
long int getVoxelsColored();
long int getVoxelsBytesRead();
@ -200,9 +204,10 @@ private:
int _lastViewCullingElapsed;
bool getUseVoxelShader();
void initVoxelShader();
bool _voxelShaderInitialized;
bool _initializingVoxelShader;
void initVoxelMemory();
void cleanupVoxelMemory();
bool _useVoxelShader;
GLuint _vboVoxelsID; /// when using voxel shader, we'll use this VBO
GLuint _vboVoxelsIndicesID; /// when using voxel shader, we'll use this VBO for our indexes
VoxelShaderVBOData* _writeVoxelShaderData;

View file

@ -32,7 +32,7 @@ const float VOXEL_SIZE_SCALE = TREE_SCALE * 400.0f;
const int NUMBER_OF_CHILDREN = 8;
const int MAX_VOXEL_PACKET_SIZE = 1492;
const int MAX_TREE_SLICE_BYTES = 26;
const int MAX_VOXELS_PER_SYSTEM = 200000;
const int DEFAULT_MAX_VOXELS_PER_SYSTEM = 200000;
const int VERTICES_PER_VOXEL = 24; // 6 sides * 4 corners per side
const int VERTEX_POINTS_PER_VOXEL = 3 * VERTICES_PER_VOXEL; // ???? xyz for each VERTICE_PER_VOXEL??
const int INDICES_PER_VOXEL = 3 * 12; // 6 sides * 2 triangles per size * 3 vertices per triangle