mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 14:29:03 +02:00
More work on partial VBO updates still not working 100% correctly
This commit is contained in:
parent
a08d89a074
commit
f490f3ed53
3 changed files with 165 additions and 8 deletions
|
@ -422,22 +422,29 @@ void VoxelSystem::updateFullVBOs() {
|
||||||
GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
|
glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);
|
glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);
|
||||||
|
|
||||||
|
// consider the _voxelDirtyArray[] clean!
|
||||||
|
memset(_voxelDirtyArray, false, MAX_VOXELS_PER_SYSTEM * sizeof(bool));
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelSystem::updatePartialVBOs() {
|
void VoxelSystem::updatePartialVBOs() {
|
||||||
|
int segmentCount = 0;
|
||||||
glBufferIndex segmentStart = 0;
|
glBufferIndex segmentStart = 0;
|
||||||
glBufferIndex segmentEnd = 0;
|
glBufferIndex segmentEnd = 0;
|
||||||
bool inSegment = false;
|
bool inSegment = false;
|
||||||
for (glBufferIndex i = 0; i < _voxelsInWriteArrays; i++) {
|
for (glBufferIndex i = 0; i < _voxelsInWriteArrays; i++) {
|
||||||
|
bool thisVoxelDirty = _voxelDirtyArray[i];
|
||||||
if (!inSegment) {
|
if (!inSegment) {
|
||||||
if (_voxelDirtyArray[i]) {
|
if (thisVoxelDirty) {
|
||||||
segmentStart = i;
|
segmentStart = i;
|
||||||
inSegment = true;
|
inSegment = true;
|
||||||
_voxelDirtyArray[i] = false; // consider us clean!
|
_voxelDirtyArray[i] = false; // consider us clean!
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!_voxelDirtyArray[i] || (i == (_voxelsInWriteArrays - 1)) ) {
|
if (!thisVoxelDirty) {
|
||||||
segmentEnd = i;
|
// If we got here because because this voxel is NOT dirty, so the last dirty voxel was the one before
|
||||||
|
// this one and so that's where the "segment" ends
|
||||||
|
segmentEnd = i - 1;
|
||||||
inSegment = false;
|
inSegment = false;
|
||||||
int segmentLength = (segmentEnd - segmentStart) + 1;
|
int segmentLength = (segmentEnd - segmentStart) + 1;
|
||||||
GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
|
||||||
|
@ -450,9 +457,113 @@ void VoxelSystem::updatePartialVBOs() {
|
||||||
GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
|
glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);
|
glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);
|
||||||
|
|
||||||
|
// debug
|
||||||
|
segmentCount++;
|
||||||
|
printLog("updatePartialVBOs() start=%ld, end=%ld, length=%ld, segmentCount=%d \n",
|
||||||
|
segmentStart, segmentEnd, segmentLength, segmentCount);
|
||||||
}
|
}
|
||||||
|
_voxelDirtyArray[i] = false; // consider us clean!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if we got to the end of the array, and we're in an active dirty segment...
|
||||||
|
if (inSegment) {
|
||||||
|
segmentEnd = _voxelsInWriteArrays - 1;
|
||||||
|
inSegment = false;
|
||||||
|
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);
|
||||||
|
|
||||||
|
// debug
|
||||||
|
segmentCount++;
|
||||||
|
printLog("updatePartialVBOs() start=%ld, end=%ld, length=%ld, segmentCount=%d \n",
|
||||||
|
segmentStart, segmentEnd, segmentLength, segmentCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void debugOpenGLError(const char* label) {
|
||||||
|
GLenum error = glGetError();
|
||||||
|
const char* errorMessage;
|
||||||
|
switch (error) {
|
||||||
|
case GL_NO_ERROR:
|
||||||
|
return;
|
||||||
|
case GL_INVALID_ENUM:
|
||||||
|
errorMessage = "GL_INVALID_ENUM";
|
||||||
|
break;
|
||||||
|
case GL_INVALID_VALUE:
|
||||||
|
errorMessage = "GL_INVALID_VALUE";
|
||||||
|
break;
|
||||||
|
case GL_INVALID_OPERATION:
|
||||||
|
errorMessage = "GL_INVALID_OPERATION";
|
||||||
|
break;
|
||||||
|
case GL_STACK_OVERFLOW:
|
||||||
|
errorMessage = "GL_STACK_OVERFLOW";
|
||||||
|
break;
|
||||||
|
case GL_STACK_UNDERFLOW:
|
||||||
|
errorMessage = "GL_STACK_UNDERFLOW";
|
||||||
|
break;
|
||||||
|
case GL_OUT_OF_MEMORY:
|
||||||
|
errorMessage = "GL_OUT_OF_MEMORY";
|
||||||
|
break;
|
||||||
|
case GL_INVALID_FRAMEBUFFER_OPERATION:
|
||||||
|
errorMessage = "GL_INVALID_FRAMEBUFFER_OPERATION";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printLog("%s generated %s", label, errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelSystem::updateJustEnoughVBOs() {
|
||||||
|
bool somethingDirty = false;
|
||||||
|
glBufferIndex minDirty = GLBUFFER_INDEX_UNKNOWN;
|
||||||
|
glBufferIndex maxDirty = 0;
|
||||||
|
|
||||||
|
for (glBufferIndex i = 0; i < _voxelsInWriteArrays; i++) {
|
||||||
|
if (_voxelDirtyArray[i]) {
|
||||||
|
somethingDirty = true;
|
||||||
|
minDirty = std::min(minDirty,i);
|
||||||
|
maxDirty = std::max(maxDirty,i);
|
||||||
|
_voxelDirtyArray[i] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (somethingDirty) {
|
||||||
|
glBufferIndex segmentStart = minDirty;
|
||||||
|
glBufferIndex segmentEnd = maxDirty;
|
||||||
|
|
||||||
|
glGetError(); // clear errors
|
||||||
|
|
||||||
|
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);
|
||||||
|
debugOpenGLError("glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID)");
|
||||||
|
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom);
|
||||||
|
debugOpenGLError("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);
|
||||||
|
debugOpenGLError("glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID)");
|
||||||
|
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);
|
||||||
|
debugOpenGLError("glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom)");
|
||||||
|
|
||||||
|
// debug
|
||||||
|
printLog("updateJustEnoughVBOs() start=%ld, end=%ld, length=%ld, \n", segmentStart, segmentEnd, segmentLength);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelSystem::updateVBOs() {
|
void VoxelSystem::updateVBOs() {
|
||||||
|
@ -463,10 +574,12 @@ void VoxelSystem::updateVBOs() {
|
||||||
PerformanceWarning warn(_renderWarningsOn, buffer); // would like to include _callsToTreesToArrays
|
PerformanceWarning warn(_renderWarningsOn, buffer); // would like to include _callsToTreesToArrays
|
||||||
if (_voxelsDirty) {
|
if (_voxelsDirty) {
|
||||||
// updatePartialVBOs() is not yet working. For now, ALWAYS call updateFullVBOs()
|
// updatePartialVBOs() is not yet working. For now, ALWAYS call updateFullVBOs()
|
||||||
if (true || _renderFullVBO) {
|
bool alwaysRenderFullVBO = true;
|
||||||
|
if (alwaysRenderFullVBO || _renderFullVBO) {
|
||||||
updateFullVBOs();
|
updateFullVBOs();
|
||||||
} else {
|
} else {
|
||||||
updatePartialVBOs();
|
updateJustEnoughVBOs();
|
||||||
|
//updatePartialVBOs(); // too many small segments?
|
||||||
}
|
}
|
||||||
_voxelsDirty = false;
|
_voxelsDirty = false;
|
||||||
}
|
}
|
||||||
|
@ -726,3 +839,34 @@ void VoxelSystem::removeOutOfView() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class falseColorizeRandomEveryOtherArgs {
|
||||||
|
public:
|
||||||
|
falseColorizeRandomEveryOtherArgs() : totalNodes(0), colorableNodes(0), coloredNodes(0), colorThis(true) {};
|
||||||
|
unsigned long totalNodes;
|
||||||
|
unsigned long colorableNodes;
|
||||||
|
unsigned long coloredNodes;
|
||||||
|
bool colorThis;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool VoxelSystem::falseColorizeRandomEveryOtherOperation(VoxelNode* node, void* extraData) {
|
||||||
|
falseColorizeRandomEveryOtherArgs* args = (falseColorizeRandomEveryOtherArgs*)extraData;
|
||||||
|
args->totalNodes++;
|
||||||
|
if (node->isColored()) {
|
||||||
|
args->colorableNodes++;
|
||||||
|
if (args->colorThis) {
|
||||||
|
args->coloredNodes++;
|
||||||
|
node->setFalseColor(255, randomColorValue(150), randomColorValue(150));
|
||||||
|
}
|
||||||
|
args->colorThis = !args->colorThis;
|
||||||
|
}
|
||||||
|
return true; // keep going!
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelSystem::falseColorizeRandomEveryOther() {
|
||||||
|
falseColorizeRandomEveryOtherArgs args;
|
||||||
|
_tree->recurseTreeWithOperation(falseColorizeRandomEveryOtherOperation,&args);
|
||||||
|
printLog("randomized false color for every other node: total %ld, colorable %ld, colored %ld\n",
|
||||||
|
args.totalNodes, args.colorableNodes, args.coloredNodes);
|
||||||
|
setupNewVoxelsForDrawing();
|
||||||
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ public:
|
||||||
void trueColorize();
|
void trueColorize();
|
||||||
void falseColorizeInView(ViewFrustum* viewFrustum);
|
void falseColorizeInView(ViewFrustum* viewFrustum);
|
||||||
void falseColorizeDistanceFromView(ViewFrustum* viewFrustum);
|
void falseColorizeDistanceFromView(ViewFrustum* viewFrustum);
|
||||||
|
void falseColorizeRandomEveryOther();
|
||||||
|
|
||||||
void killLocalVoxels();
|
void killLocalVoxels();
|
||||||
void setRenderPipelineWarnings(bool on) { _renderWarningsOn = on; };
|
void setRenderPipelineWarnings(bool on) { _renderWarningsOn = on; };
|
||||||
|
@ -78,6 +79,7 @@ private:
|
||||||
static bool falseColorizeDistanceFromViewOperation(VoxelNode* node, void* extraData);
|
static bool falseColorizeDistanceFromViewOperation(VoxelNode* node, void* extraData);
|
||||||
static bool getDistanceFromViewRangeOperation(VoxelNode* node, void* extraData);
|
static bool getDistanceFromViewRangeOperation(VoxelNode* node, void* extraData);
|
||||||
static bool removeOutOfViewOperation(VoxelNode* node, void* extraData);
|
static bool removeOutOfViewOperation(VoxelNode* node, void* extraData);
|
||||||
|
static bool falseColorizeRandomEveryOtherOperation(VoxelNode* node, void* extraData);
|
||||||
|
|
||||||
int updateNodeInArraysAsFullVBO(VoxelNode* node);
|
int updateNodeInArraysAsFullVBO(VoxelNode* node);
|
||||||
int updateNodeInArraysAsPartialVBO(VoxelNode* node);
|
int updateNodeInArraysAsPartialVBO(VoxelNode* node);
|
||||||
|
@ -116,12 +118,15 @@ private:
|
||||||
ViewFrustum _lastKnowViewFrustum;
|
ViewFrustum _lastKnowViewFrustum;
|
||||||
|
|
||||||
int newTreeToArrays(VoxelNode *currentNode);
|
int newTreeToArrays(VoxelNode *currentNode);
|
||||||
|
void cleanupRemovedVoxels();
|
||||||
|
|
||||||
void setupNewVoxelsForDrawing();
|
void setupNewVoxelsForDrawing();
|
||||||
void copyWrittenDataToReadArrays();
|
void copyWrittenDataToReadArrays();
|
||||||
|
|
||||||
void updateVBOs();
|
void updateVBOs();
|
||||||
void updateFullVBOs();
|
void updateFullVBOs(); // all voxels in the VBO
|
||||||
void updatePartialVBOs();
|
void updatePartialVBOs(); // multiple segments, only dirty voxels
|
||||||
void cleanupRemovedVoxels();
|
void updateJustEnoughVBOs(); // single segment from first dirty, to last dirty, may include clean voxels
|
||||||
|
|
||||||
bool _voxelsDirty;
|
bool _voxelsDirty;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1331,6 +1331,13 @@ int doRandomizeVoxelColors(int state) {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int doFalseRandomizeEveryOtherVoxelColors(int state) {
|
||||||
|
if (state == MENU_ROW_PICKED) {
|
||||||
|
::voxels.falseColorizeRandomEveryOther();
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
int doFalseRandomizeVoxelColors(int state) {
|
int doFalseRandomizeVoxelColors(int state) {
|
||||||
if (state == MENU_ROW_PICKED) {
|
if (state == MENU_ROW_PICKED) {
|
||||||
::voxels.falseColorizeRandom();
|
::voxels.falseColorizeRandom();
|
||||||
|
@ -1427,6 +1434,7 @@ void initMenu() {
|
||||||
menuColumnDebug->addRow("Kill Local Voxels", doKillLocalVoxels);
|
menuColumnDebug->addRow("Kill Local Voxels", doKillLocalVoxels);
|
||||||
menuColumnDebug->addRow("Randomize Voxel TRUE Colors", doRandomizeVoxelColors);
|
menuColumnDebug->addRow("Randomize Voxel TRUE Colors", doRandomizeVoxelColors);
|
||||||
menuColumnDebug->addRow("FALSE Color Voxels Randomly", doFalseRandomizeVoxelColors);
|
menuColumnDebug->addRow("FALSE Color Voxels Randomly", doFalseRandomizeVoxelColors);
|
||||||
|
menuColumnDebug->addRow("FALSE Color Voxel Every Other Randomly", doFalseRandomizeEveryOtherVoxelColors);
|
||||||
menuColumnDebug->addRow("FALSE Color Voxels by Distance", doFalseColorizeByDistance);
|
menuColumnDebug->addRow("FALSE Color Voxels by Distance", doFalseColorizeByDistance);
|
||||||
menuColumnDebug->addRow("FALSE Color Voxel Out of View", doFalseColorizeInView);
|
menuColumnDebug->addRow("FALSE Color Voxel Out of View", doFalseColorizeInView);
|
||||||
menuColumnDebug->addRow("Show TRUE Colors", doTrueVoxelColors);
|
menuColumnDebug->addRow("Show TRUE Colors", doTrueVoxelColors);
|
||||||
|
|
Loading…
Reference in a new issue