mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 06:44:06 +02:00
menu cleanup, support for on the fly switching of maxVoxels and useVoxelShader
This commit is contained in:
parent
552d9fadd8
commit
7845340279
6 changed files with 237 additions and 159 deletions
|
@ -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("");
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue