mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 17:00:13 +02:00
Merge branch 'master' of https://github.com/worklist/hifi
This commit is contained in:
commit
d44961a175
5 changed files with 188 additions and 33 deletions
|
@ -26,14 +26,17 @@ const int VERTICES_PER_FACE = 4;
|
||||||
const int COORD_PER_VERTEX = 3;
|
const int COORD_PER_VERTEX = 3;
|
||||||
const int COORD_PER_FACE = COORD_PER_VERTEX * VERTICES_PER_FACE;
|
const int COORD_PER_FACE = COORD_PER_VERTEX * VERTICES_PER_FACE;
|
||||||
|
|
||||||
void faceOfVoxel(vec4 corner, float scale, float[COORD_PER_FACE] facePoints, vec4 color) {
|
void faceOfVoxel(vec4 corner, float scale, float[COORD_PER_FACE] facePoints, vec4 color, vec4 normal) {
|
||||||
for (int v = 0; v < VERTICES_PER_FACE; v++ ) {
|
for (int v = 0; v < VERTICES_PER_FACE; v++ ) {
|
||||||
vec4 vertex = corner;
|
vec4 vertex = corner;
|
||||||
for (int c = 0; c < COORD_PER_VERTEX; c++ ) {
|
for (int c = 0; c < COORD_PER_VERTEX; c++ ) {
|
||||||
int cIndex = c + (v * COORD_PER_VERTEX);
|
int cIndex = c + (v * COORD_PER_VERTEX);
|
||||||
vertex[c] += (facePoints[cIndex] * scale);
|
vertex[c] += (facePoints[cIndex] * scale);
|
||||||
}
|
}
|
||||||
gl_FrontColor = color;
|
|
||||||
|
gl_FrontColor = color * (gl_LightModel.ambient + gl_LightSource[0].ambient +
|
||||||
|
gl_LightSource[0].diffuse * max(0.0, dot(normal, gl_LightSource[0].position)));
|
||||||
|
|
||||||
gl_Position = gl_ModelViewProjectionMatrix * vertex;
|
gl_Position = gl_ModelViewProjectionMatrix * vertex;
|
||||||
EmitVertex();
|
EmitVertex();
|
||||||
}
|
}
|
||||||
|
@ -54,14 +57,21 @@ void main() {
|
||||||
float frontFace[COORD_PER_FACE] = float[COORD_PER_FACE]( 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0 );
|
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 );
|
float backFace[COORD_PER_FACE] = float[COORD_PER_FACE]( 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1 );
|
||||||
|
|
||||||
|
vec4 bottomNormal = vec4(0.0, -1, 0.0, 0.0);
|
||||||
|
vec4 topNormal = vec4(0.0, 1, 0.0, 0.0);
|
||||||
|
vec4 rightNormal = vec4( -1, 0.0, 0.0, 0.0);
|
||||||
|
vec4 leftNormal = vec4( 1, 0.0, 0.0, 0.0);
|
||||||
|
vec4 frontNormal = vec4(0.0, 0.0, -1, 0.0);
|
||||||
|
vec4 backNormal = vec4(0.0, 0.0, 1, 0.0);
|
||||||
|
|
||||||
for(i = 0; i < gl_VerticesIn; i++) {
|
for(i = 0; i < gl_VerticesIn; i++) {
|
||||||
corner = gl_PositionIn[i];
|
corner = gl_PositionIn[i];
|
||||||
scale = voxelSize[i];
|
scale = voxelSize[i];
|
||||||
faceOfVoxel(corner, scale, bottomFace, gl_FrontColorIn[i]);
|
faceOfVoxel(corner, scale, bottomFace, gl_FrontColorIn[i], bottomNormal);
|
||||||
faceOfVoxel(corner, scale, topFace, gl_FrontColorIn[i]);
|
faceOfVoxel(corner, scale, topFace, gl_FrontColorIn[i], topNormal );
|
||||||
faceOfVoxel(corner, scale, rightFace, gl_FrontColorIn[i]);
|
faceOfVoxel(corner, scale, rightFace, gl_FrontColorIn[i], rightNormal );
|
||||||
faceOfVoxel(corner, scale, leftFace, gl_FrontColorIn[i]);
|
faceOfVoxel(corner, scale, leftFace, gl_FrontColorIn[i], leftNormal );
|
||||||
faceOfVoxel(corner, scale, frontFace, gl_FrontColorIn[i]);
|
faceOfVoxel(corner, scale, frontFace, gl_FrontColorIn[i], frontNormal );
|
||||||
faceOfVoxel(corner, scale, backFace, gl_FrontColorIn[i]);
|
faceOfVoxel(corner, scale, backFace, gl_FrontColorIn[i], backNormal );
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2827,28 +2827,36 @@ void Application::displayStats() {
|
||||||
voxelStats << "Voxels Rendered: " << _voxels.getVoxelsRendered() / 1000.f << "K " <<
|
voxelStats << "Voxels Rendered: " << _voxels.getVoxelsRendered() / 1000.f << "K " <<
|
||||||
"Updated: " << _voxels.getVoxelsUpdated()/1000.f << "K " <<
|
"Updated: " << _voxels.getVoxelsUpdated()/1000.f << "K " <<
|
||||||
"Max: " << _voxels.getMaxVoxels()/1000.f << "K ";
|
"Max: " << _voxels.getMaxVoxels()/1000.f << "K ";
|
||||||
|
|
||||||
drawtext(10, statsVerticalOffset + 230, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
|
drawtext(10, statsVerticalOffset + 230, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
|
||||||
|
|
||||||
|
voxelStats.str("");
|
||||||
|
voxelStats << "Voxels Memory RAM: " << _voxels.getVoxelMemoryUsageRAM() / 1000000.f << "MB " <<
|
||||||
|
"VBO: " << _voxels.getVoxelMemoryUsageVBO() / 1000000.f << "MB ";
|
||||||
|
if (_voxels.hasVoxelMemoryUsageGPU()) {
|
||||||
|
voxelStats << "GPU: " << _voxels.getVoxelMemoryUsageGPU() / 1000000.f << "MB ";
|
||||||
|
}
|
||||||
|
|
||||||
|
drawtext(10, statsVerticalOffset + 250, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
|
||||||
|
|
||||||
voxelStats.str("");
|
voxelStats.str("");
|
||||||
char* voxelDetails = _voxelSceneStats.getItemValue(VoxelSceneStats::ITEM_VOXELS);
|
char* voxelDetails = _voxelSceneStats.getItemValue(VoxelSceneStats::ITEM_VOXELS);
|
||||||
voxelStats << "Voxels Sent from Server: " << voxelDetails;
|
voxelStats << "Voxels Sent from Server: " << voxelDetails;
|
||||||
drawtext(10, statsVerticalOffset + 250, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
|
drawtext(10, statsVerticalOffset + 270, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
|
||||||
|
|
||||||
voxelStats.str("");
|
voxelStats.str("");
|
||||||
voxelDetails = _voxelSceneStats.getItemValue(VoxelSceneStats::ITEM_ELAPSED);
|
voxelDetails = _voxelSceneStats.getItemValue(VoxelSceneStats::ITEM_ELAPSED);
|
||||||
voxelStats << "Scene Send Time from Server: " << voxelDetails;
|
voxelStats << "Scene Send Time from Server: " << voxelDetails;
|
||||||
drawtext(10, statsVerticalOffset + 270, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
|
drawtext(10, statsVerticalOffset + 290, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
|
||||||
|
|
||||||
voxelStats.str("");
|
voxelStats.str("");
|
||||||
voxelDetails = _voxelSceneStats.getItemValue(VoxelSceneStats::ITEM_ENCODE);
|
voxelDetails = _voxelSceneStats.getItemValue(VoxelSceneStats::ITEM_ENCODE);
|
||||||
voxelStats << "Encode Time on Server: " << voxelDetails;
|
voxelStats << "Encode Time on Server: " << voxelDetails;
|
||||||
drawtext(10, statsVerticalOffset + 290, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
|
drawtext(10, statsVerticalOffset + 310, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
|
||||||
|
|
||||||
voxelStats.str("");
|
voxelStats.str("");
|
||||||
voxelDetails = _voxelSceneStats.getItemValue(VoxelSceneStats::ITEM_MODE);
|
voxelDetails = _voxelSceneStats.getItemValue(VoxelSceneStats::ITEM_MODE);
|
||||||
voxelStats << "Sending Mode: " << voxelDetails;
|
voxelStats << "Sending Mode: " << voxelDetails;
|
||||||
drawtext(10, statsVerticalOffset + 310, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
|
drawtext(10, statsVerticalOffset + 330, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
|
||||||
|
|
||||||
Node *avatarMixer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
|
Node *avatarMixer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
|
||||||
char avatarMixerStats[200];
|
char avatarMixerStats[200];
|
||||||
|
@ -2861,7 +2869,7 @@ void Application::displayStats() {
|
||||||
sprintf(avatarMixerStats, "No Avatar Mixer");
|
sprintf(avatarMixerStats, "No Avatar Mixer");
|
||||||
}
|
}
|
||||||
|
|
||||||
drawtext(10, statsVerticalOffset + 330, 0.10f, 0, 1.0, 0, avatarMixerStats);
|
drawtext(10, statsVerticalOffset + 350, 0.10f, 0, 1.0, 0, avatarMixerStats);
|
||||||
drawtext(10, statsVerticalOffset + 450, 0.10f, 0, 1.0, 0, (char *)LeapManager::statusString().c_str());
|
drawtext(10, statsVerticalOffset + 450, 0.10f, 0, 1.0, 0, (char *)LeapManager::statusString().c_str());
|
||||||
|
|
||||||
if (_perfStatsOn) {
|
if (_perfStatsOn) {
|
||||||
|
|
|
@ -37,7 +37,7 @@ float identityVertices[] = { 0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0,
|
||||||
0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0,1,1,
|
0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0,1,1,
|
||||||
0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0,1,1 };
|
0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0,1,1 };
|
||||||
|
|
||||||
GLbyte identityNormals[] = { 0,0,-1, 0,0,-1, 0,0,-1, 0,0,-1,
|
GLfloat identityNormals[] = { 0,0,-1, 0,0,-1, 0,0,-1, 0,0,-1,
|
||||||
0,0,+1, 0,0,+1, 0,0,+1, 0,0,+1,
|
0,0,+1, 0,0,+1, 0,0,+1, 0,0,+1,
|
||||||
0,-1,0, 0,-1,0, 0,+1,0, 0,+1,0,
|
0,-1,0, 0,-1,0, 0,+1,0, 0,+1,0,
|
||||||
0,-1,0, 0,-1,0, 0,+1,0, 0,+1,0,
|
0,-1,0, 0,-1,0, 0,+1,0, 0,+1,0,
|
||||||
|
@ -152,6 +152,10 @@ void VoxelSystem::setUseByteNormals(bool useByteNormals) {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&_bufferWriteLock);
|
pthread_mutex_unlock(&_bufferWriteLock);
|
||||||
|
|
||||||
|
if (wasInitialized) {
|
||||||
|
forceRedrawEntireTree();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -166,12 +170,17 @@ void VoxelSystem::setMaxVoxels(int maxVoxels) {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&_bufferWriteLock);
|
pthread_mutex_unlock(&_bufferWriteLock);
|
||||||
|
|
||||||
|
if (wasInitialized) {
|
||||||
|
forceRedrawEntireTree();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelSystem::setUseVoxelShader(bool useVoxelShader) {
|
void VoxelSystem::setUseVoxelShader(bool useVoxelShader) {
|
||||||
pthread_mutex_lock(&_bufferWriteLock);
|
pthread_mutex_lock(&_bufferWriteLock);
|
||||||
bool wasInitialized = _initialized;
|
bool wasInitialized = _initialized;
|
||||||
if (wasInitialized) {
|
if (wasInitialized) {
|
||||||
|
clearAllNodesBufferIndex();
|
||||||
cleanupVoxelMemory();
|
cleanupVoxelMemory();
|
||||||
}
|
}
|
||||||
_useVoxelShader = useVoxelShader;
|
_useVoxelShader = useVoxelShader;
|
||||||
|
@ -179,6 +188,10 @@ void VoxelSystem::setUseVoxelShader(bool useVoxelShader) {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&_bufferWriteLock);
|
pthread_mutex_unlock(&_bufferWriteLock);
|
||||||
|
|
||||||
|
if (wasInitialized) {
|
||||||
|
forceRedrawEntireTree();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelSystem::cleanupVoxelMemory() {
|
void VoxelSystem::cleanupVoxelMemory() {
|
||||||
|
@ -201,14 +214,17 @@ void VoxelSystem::cleanupVoxelMemory() {
|
||||||
delete[] _writeVerticesArray;
|
delete[] _writeVerticesArray;
|
||||||
delete[] _readColorsArray;
|
delete[] _readColorsArray;
|
||||||
delete[] _writeColorsArray;
|
delete[] _writeColorsArray;
|
||||||
delete[] _writeVoxelDirtyArray;
|
|
||||||
delete[] _readVoxelDirtyArray;
|
|
||||||
}
|
}
|
||||||
|
delete[] _writeVoxelDirtyArray;
|
||||||
|
delete[] _readVoxelDirtyArray;
|
||||||
}
|
}
|
||||||
_initialized = false; // no longer initialized
|
_initialized = false; // no longer initialized
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelSystem::initVoxelMemory() {
|
void VoxelSystem::initVoxelMemory() {
|
||||||
|
_initialMemoryUsageGPU = getFreeMemoryGPU();
|
||||||
|
_memoryUsageRAM = 0;
|
||||||
|
_memoryUsageVBO = 0; // our VBO allocations as we know them
|
||||||
if (_useVoxelShader) {
|
if (_useVoxelShader) {
|
||||||
qDebug("Using Voxel Shader...\n");
|
qDebug("Using Voxel Shader...\n");
|
||||||
GLuint* indicesArray = new GLuint[_maxVoxels];
|
GLuint* indicesArray = new GLuint[_maxVoxels];
|
||||||
|
@ -222,12 +238,13 @@ void VoxelSystem::initVoxelMemory() {
|
||||||
// bind the indices VBO to the actual indices array
|
// bind the indices VBO to the actual indices array
|
||||||
glGenBuffers(1, &_vboVoxelsIndicesID);
|
glGenBuffers(1, &_vboVoxelsIndicesID);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboVoxelsIndicesID);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboVoxelsIndicesID);
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, _maxVoxels, indicesArray, GL_STATIC_DRAW);
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * _maxVoxels, indicesArray, GL_STATIC_DRAW);
|
||||||
|
_memoryUsageVBO += sizeof(GLuint) * _maxVoxels;
|
||||||
|
|
||||||
glGenBuffers(1, &_vboVoxelsID);
|
glGenBuffers(1, &_vboVoxelsID);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _vboVoxelsID);
|
glBindBuffer(GL_ARRAY_BUFFER, _vboVoxelsID);
|
||||||
glBufferData(GL_ARRAY_BUFFER, _maxVoxels * sizeof(VoxelShaderVBOData), NULL, GL_DYNAMIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, _maxVoxels * sizeof(VoxelShaderVBOData), NULL, GL_DYNAMIC_DRAW);
|
||||||
|
_memoryUsageVBO += _maxVoxels * sizeof(VoxelShaderVBOData);
|
||||||
|
|
||||||
// delete the indices and normals arrays that are no longer needed
|
// delete the indices and normals arrays that are no longer needed
|
||||||
delete[] indicesArray;
|
delete[] indicesArray;
|
||||||
|
@ -235,12 +252,18 @@ void VoxelSystem::initVoxelMemory() {
|
||||||
// we will track individual dirty sections with these arrays of bools
|
// we will track individual dirty sections with these arrays of bools
|
||||||
_writeVoxelDirtyArray = new bool[_maxVoxels];
|
_writeVoxelDirtyArray = new bool[_maxVoxels];
|
||||||
memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
|
memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
|
||||||
|
_memoryUsageRAM += (_maxVoxels * sizeof(bool));
|
||||||
|
|
||||||
_readVoxelDirtyArray = new bool[_maxVoxels];
|
_readVoxelDirtyArray = new bool[_maxVoxels];
|
||||||
memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
|
memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
|
||||||
|
_memoryUsageRAM += (_maxVoxels * sizeof(bool));
|
||||||
|
|
||||||
// prep the data structures for incoming voxel data
|
// prep the data structures for incoming voxel data
|
||||||
_writeVoxelShaderData = new VoxelShaderVBOData[_maxVoxels];
|
_writeVoxelShaderData = new VoxelShaderVBOData[_maxVoxels];
|
||||||
|
_memoryUsageRAM += (sizeof(VoxelShaderVBOData) * _maxVoxels);
|
||||||
|
|
||||||
_readVoxelShaderData = new VoxelShaderVBOData[_maxVoxels];
|
_readVoxelShaderData = new VoxelShaderVBOData[_maxVoxels];
|
||||||
|
_memoryUsageRAM += (sizeof(VoxelShaderVBOData) * _maxVoxels);
|
||||||
} else {
|
} else {
|
||||||
GLuint* indicesArray = new GLuint[INDICES_PER_VOXEL * _maxVoxels];
|
GLuint* indicesArray = new GLuint[INDICES_PER_VOXEL * _maxVoxels];
|
||||||
|
|
||||||
|
@ -266,7 +289,7 @@ void VoxelSystem::initVoxelMemory() {
|
||||||
// populate the normalsArray
|
// populate the normalsArray
|
||||||
for (int n = 0; n < _maxVoxels; n++) {
|
for (int n = 0; n < _maxVoxels; n++) {
|
||||||
for (int i = 0; i < VERTEX_POINTS_PER_VOXEL; i++) {
|
for (int i = 0; i < VERTEX_POINTS_PER_VOXEL; i++) {
|
||||||
*(normalsArrayEndPointer++) = identityNormals[i];
|
*(normalsArrayEndPointer++) = (identityNormals[i] * CHAR_MAX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,6 +299,7 @@ void VoxelSystem::initVoxelMemory() {
|
||||||
glBufferData(GL_ARRAY_BUFFER,
|
glBufferData(GL_ARRAY_BUFFER,
|
||||||
VERTEX_POINTS_PER_VOXEL * sizeof(GLbyte) * _maxVoxels,
|
VERTEX_POINTS_PER_VOXEL * sizeof(GLbyte) * _maxVoxels,
|
||||||
normalsArray, GL_STATIC_DRAW);
|
normalsArray, GL_STATIC_DRAW);
|
||||||
|
_memoryUsageVBO += VERTEX_POINTS_PER_VOXEL * sizeof(GLbyte) * _maxVoxels;
|
||||||
|
|
||||||
// delete the indices and normals arrays that are no longer needed
|
// delete the indices and normals arrays that are no longer needed
|
||||||
delete[] normalsArray;
|
delete[] normalsArray;
|
||||||
|
@ -297,6 +321,7 @@ void VoxelSystem::initVoxelMemory() {
|
||||||
glBufferData(GL_ARRAY_BUFFER,
|
glBufferData(GL_ARRAY_BUFFER,
|
||||||
VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels,
|
VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels,
|
||||||
normalsArray, GL_STATIC_DRAW);
|
normalsArray, GL_STATIC_DRAW);
|
||||||
|
_memoryUsageVBO += VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels;
|
||||||
|
|
||||||
// delete the indices and normals arrays that are no longer needed
|
// delete the indices and normals arrays that are no longer needed
|
||||||
delete[] normalsArray;
|
delete[] normalsArray;
|
||||||
|
@ -306,11 +331,13 @@ void VoxelSystem::initVoxelMemory() {
|
||||||
glGenBuffers(1, &_vboVerticesID);
|
glGenBuffers(1, &_vboVerticesID);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
|
glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
|
||||||
glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, NULL, GL_DYNAMIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, NULL, GL_DYNAMIC_DRAW);
|
||||||
|
_memoryUsageVBO += VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels;
|
||||||
|
|
||||||
// VBO for colorsArray
|
// VBO for colorsArray
|
||||||
glGenBuffers(1, &_vboColorsID);
|
glGenBuffers(1, &_vboColorsID);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
|
glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
|
||||||
glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * _maxVoxels, NULL, GL_DYNAMIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * _maxVoxels, NULL, GL_DYNAMIC_DRAW);
|
||||||
|
_memoryUsageVBO += VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * _maxVoxels;
|
||||||
|
|
||||||
// VBO for the indicesArray
|
// VBO for the indicesArray
|
||||||
glGenBuffers(1, &_vboIndicesID);
|
glGenBuffers(1, &_vboIndicesID);
|
||||||
|
@ -318,6 +345,7 @@ void VoxelSystem::initVoxelMemory() {
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
||||||
INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels,
|
INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels,
|
||||||
indicesArray, GL_STATIC_DRAW);
|
indicesArray, GL_STATIC_DRAW);
|
||||||
|
_memoryUsageVBO += INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels;
|
||||||
|
|
||||||
// delete the indices and normals arrays that are no longer needed
|
// delete the indices and normals arrays that are no longer needed
|
||||||
delete[] indicesArray;
|
delete[] indicesArray;
|
||||||
|
@ -326,15 +354,22 @@ void VoxelSystem::initVoxelMemory() {
|
||||||
// we will track individual dirty sections with these arrays of bools
|
// we will track individual dirty sections with these arrays of bools
|
||||||
_writeVoxelDirtyArray = new bool[_maxVoxels];
|
_writeVoxelDirtyArray = new bool[_maxVoxels];
|
||||||
memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
|
memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
|
||||||
|
_memoryUsageRAM += (sizeof(bool) * _maxVoxels);
|
||||||
|
|
||||||
_readVoxelDirtyArray = new bool[_maxVoxels];
|
_readVoxelDirtyArray = new bool[_maxVoxels];
|
||||||
memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
|
memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool));
|
||||||
|
_memoryUsageRAM += (sizeof(bool) * _maxVoxels);
|
||||||
|
|
||||||
// prep the data structures for incoming voxel data
|
// prep the data structures for incoming voxel data
|
||||||
_writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
|
_writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
|
||||||
|
_memoryUsageRAM += (sizeof(GLfloat) * VERTEX_POINTS_PER_VOXEL * _maxVoxels);
|
||||||
_readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
|
_readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
|
||||||
|
_memoryUsageRAM += (sizeof(GLfloat) * VERTEX_POINTS_PER_VOXEL * _maxVoxels);
|
||||||
|
|
||||||
_writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
|
_writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
|
||||||
|
_memoryUsageRAM += (sizeof(GLubyte) * VERTEX_POINTS_PER_VOXEL * _maxVoxels);
|
||||||
_readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
|
_readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels];
|
||||||
|
_memoryUsageRAM += (sizeof(GLubyte) * VERTEX_POINTS_PER_VOXEL * _maxVoxels);
|
||||||
|
|
||||||
|
|
||||||
// create our simple fragment shader if we're the first system to init
|
// create our simple fragment shader if we're the first system to init
|
||||||
|
@ -750,20 +785,24 @@ void VoxelSystem::updateNodeInArrays(glBufferIndex nodeIndex, const glm::vec3& s
|
||||||
float voxelScale, const nodeColor& color) {
|
float voxelScale, const nodeColor& color) {
|
||||||
|
|
||||||
if (_useVoxelShader) {
|
if (_useVoxelShader) {
|
||||||
VoxelShaderVBOData* writeVerticesAt = &_writeVoxelShaderData[nodeIndex];
|
if (_writeVoxelShaderData) {
|
||||||
writeVerticesAt->x = startVertex.x * TREE_SCALE;
|
VoxelShaderVBOData* writeVerticesAt = &_writeVoxelShaderData[nodeIndex];
|
||||||
writeVerticesAt->y = startVertex.y * TREE_SCALE;
|
writeVerticesAt->x = startVertex.x * TREE_SCALE;
|
||||||
writeVerticesAt->z = startVertex.z * TREE_SCALE;
|
writeVerticesAt->y = startVertex.y * TREE_SCALE;
|
||||||
writeVerticesAt->s = voxelScale * TREE_SCALE;
|
writeVerticesAt->z = startVertex.z * TREE_SCALE;
|
||||||
writeVerticesAt->r = color[RED_INDEX];
|
writeVerticesAt->s = voxelScale * TREE_SCALE;
|
||||||
writeVerticesAt->g = color[GREEN_INDEX];
|
writeVerticesAt->r = color[RED_INDEX];
|
||||||
writeVerticesAt->b = color[BLUE_INDEX];
|
writeVerticesAt->g = color[GREEN_INDEX];
|
||||||
|
writeVerticesAt->b = color[BLUE_INDEX];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) {
|
if (_writeVerticesArray && _writeColorsArray) {
|
||||||
GLfloat* writeVerticesAt = _writeVerticesArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL);
|
for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) {
|
||||||
GLubyte* writeColorsAt = _writeColorsArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL);
|
GLfloat* writeVerticesAt = _writeVerticesArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL);
|
||||||
*(writeVerticesAt+j) = startVertex[j % 3] + (identityVertices[j] * voxelScale);
|
GLubyte* writeColorsAt = _writeColorsArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL);
|
||||||
*(writeColorsAt +j) = color[j % 3];
|
*(writeVerticesAt+j) = startVertex[j % 3] + (identityVertices[j] * voxelScale);
|
||||||
|
*(writeColorsAt +j) = color[j % 3];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -995,6 +1034,34 @@ void VoxelSystem::killLocalVoxels() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool VoxelSystem::clearAllNodesBufferIndexOperation(VoxelNode* node, void* extraData) {
|
||||||
|
_nodeCount++;
|
||||||
|
node->setBufferIndex(GLBUFFER_INDEX_UNKNOWN);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelSystem::clearAllNodesBufferIndex() {
|
||||||
|
_nodeCount = 0;
|
||||||
|
_tree->recurseTreeWithOperation(clearAllNodesBufferIndexOperation);
|
||||||
|
qDebug("clearing buffer index of %d nodes\n", _nodeCount);
|
||||||
|
_tree->setDirtyBit();
|
||||||
|
setupNewVoxelsForDrawing();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VoxelSystem::forceRedrawEntireTreeOperation(VoxelNode* node, void* extraData) {
|
||||||
|
_nodeCount++;
|
||||||
|
node->setDirtyBit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelSystem::forceRedrawEntireTree() {
|
||||||
|
_nodeCount = 0;
|
||||||
|
_tree->recurseTreeWithOperation(forceRedrawEntireTreeOperation);
|
||||||
|
qDebug("forcing redraw of %d nodes\n", _nodeCount);
|
||||||
|
_tree->setDirtyBit();
|
||||||
|
setupNewVoxelsForDrawing();
|
||||||
|
}
|
||||||
|
|
||||||
bool VoxelSystem::randomColorOperation(VoxelNode* node, void* extraData) {
|
bool VoxelSystem::randomColorOperation(VoxelNode* node, void* extraData) {
|
||||||
_nodeCount++;
|
_nodeCount++;
|
||||||
if (node->isColored()) {
|
if (node->isColored()) {
|
||||||
|
@ -1852,3 +1919,58 @@ void VoxelSystem::nodeKilled(Node* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned long VoxelSystem::getFreeMemoryGPU() {
|
||||||
|
// We can't ask all GPUs how much memory they have in use, but we can ask them about how much is free.
|
||||||
|
// So, we can record the free memory before we create our VBOs and the free memory after, and get a basic
|
||||||
|
// idea how how much we're using.
|
||||||
|
|
||||||
|
_hasMemoryUsageGPU = false; // assume the worst
|
||||||
|
unsigned long freeMemory = 0;
|
||||||
|
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]);
|
||||||
|
GLenum errorATI = glGetError();
|
||||||
|
|
||||||
|
if (errorATI == GL_NO_ERROR) {
|
||||||
|
_hasMemoryUsageGPU = true;
|
||||||
|
freeMemory = results[0];
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// NVIDIA
|
||||||
|
// http://developer.download.nvidia.com/opengl/specs/GL_NVX_gpu_memory_info.txt
|
||||||
|
//
|
||||||
|
//const GLenum GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX = 0x9047;
|
||||||
|
//const GLenum GPU_MEMORY_INFO_EVICTION_COUNT_NVX = 0x904A;
|
||||||
|
//const GLenum GPU_MEMORY_INFO_EVICTED_MEMORY_NVX = 0x904B;
|
||||||
|
//const GLenum GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX = 0x9048;
|
||||||
|
|
||||||
|
const GLenum GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX = 0x9049;
|
||||||
|
results[0] = 0;
|
||||||
|
glGetIntegerv(GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &results[0]);
|
||||||
|
freeMemory += results[0];
|
||||||
|
GLenum errorNVIDIA = glGetError();
|
||||||
|
|
||||||
|
if (errorNVIDIA == GL_NO_ERROR) {
|
||||||
|
_hasMemoryUsageGPU = true;
|
||||||
|
freeMemory = results[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned long BYTES_PER_KBYTE = 1024;
|
||||||
|
return freeMemory * BYTES_PER_KBYTE; // API results in KB, we want it in bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long VoxelSystem::getVoxelMemoryUsageGPU() {
|
||||||
|
unsigned long currentFreeMemory = getFreeMemoryGPU();
|
||||||
|
return (_initialMemoryUsageGPU - currentFreeMemory);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,10 @@ public:
|
||||||
|
|
||||||
void setMaxVoxels(int maxVoxels);
|
void setMaxVoxels(int maxVoxels);
|
||||||
long int getMaxVoxels() const { return _maxVoxels; }
|
long int getMaxVoxels() const { return _maxVoxels; }
|
||||||
|
unsigned long getVoxelMemoryUsageRAM() const { return _memoryUsageRAM; }
|
||||||
|
unsigned long getVoxelMemoryUsageVBO() const { return _memoryUsageVBO; }
|
||||||
|
bool hasVoxelMemoryUsageGPU() const { return _hasMemoryUsageGPU; }
|
||||||
|
unsigned long getVoxelMemoryUsageGPU();
|
||||||
long int getVoxelsCreated();
|
long int getVoxelsCreated();
|
||||||
long int getVoxelsColored();
|
long int getVoxelsColored();
|
||||||
long int getVoxelsBytesRead();
|
long int getVoxelsBytesRead();
|
||||||
|
@ -126,6 +130,8 @@ public slots:
|
||||||
void falseColorizeOccluded();
|
void falseColorizeOccluded();
|
||||||
void falseColorizeOccludedV2();
|
void falseColorizeOccludedV2();
|
||||||
void falseColorizeBySource();
|
void falseColorizeBySource();
|
||||||
|
void forceRedrawEntireTree();
|
||||||
|
void clearAllNodesBufferIndex();
|
||||||
|
|
||||||
void cancelImport();
|
void cancelImport();
|
||||||
void setUseByteNormals(bool useByteNormals);
|
void setUseByteNormals(bool useByteNormals);
|
||||||
|
@ -172,6 +178,8 @@ private:
|
||||||
static bool falseColorizeOccludedV2Operation(VoxelNode* node, void* extraData);
|
static bool falseColorizeOccludedV2Operation(VoxelNode* node, void* extraData);
|
||||||
static bool falseColorizeBySourceOperation(VoxelNode* node, void* extraData);
|
static bool falseColorizeBySourceOperation(VoxelNode* node, void* extraData);
|
||||||
static bool killSourceVoxelsOperation(VoxelNode* node, void* extraData);
|
static bool killSourceVoxelsOperation(VoxelNode* node, void* extraData);
|
||||||
|
static bool forceRedrawEntireTreeOperation(VoxelNode* node, void* extraData);
|
||||||
|
static bool clearAllNodesBufferIndexOperation(VoxelNode* node, void* extraData);
|
||||||
|
|
||||||
int updateNodeInArraysAsFullVBO(VoxelNode* node);
|
int updateNodeInArraysAsFullVBO(VoxelNode* node);
|
||||||
int updateNodeInArraysAsPartialVBO(VoxelNode* node);
|
int updateNodeInArraysAsPartialVBO(VoxelNode* node);
|
||||||
|
@ -181,6 +189,8 @@ private:
|
||||||
|
|
||||||
void updateVBOs();
|
void updateVBOs();
|
||||||
|
|
||||||
|
unsigned long getFreeMemoryGPU();
|
||||||
|
|
||||||
// these are kinda hacks, used by getDistanceFromViewRangeOperation() probably shouldn't be here
|
// these are kinda hacks, used by getDistanceFromViewRangeOperation() probably shouldn't be here
|
||||||
static float _maxDistance;
|
static float _maxDistance;
|
||||||
static float _minDistance;
|
static float _minDistance;
|
||||||
|
@ -249,6 +259,10 @@ private:
|
||||||
int _dataSourceID;
|
int _dataSourceID;
|
||||||
|
|
||||||
int _voxelServerCount;
|
int _voxelServerCount;
|
||||||
|
unsigned long _memoryUsageRAM;
|
||||||
|
unsigned long _memoryUsageVBO;
|
||||||
|
unsigned long _initialMemoryUsageGPU;
|
||||||
|
bool _hasMemoryUsageGPU;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -70,6 +70,7 @@ public:
|
||||||
void printDebugDetails(const char* label) const;
|
void printDebugDetails(const char* label) const;
|
||||||
bool isDirty() const { return _isDirty; }
|
bool isDirty() const { return _isDirty; }
|
||||||
void clearDirtyBit() { _isDirty = false; }
|
void clearDirtyBit() { _isDirty = false; }
|
||||||
|
void setDirtyBit() { _isDirty = true; }
|
||||||
bool hasChangedSince(uint64_t time) const { return (_lastChanged > time); }
|
bool hasChangedSince(uint64_t time) const { return (_lastChanged > time); }
|
||||||
void markWithChangedTime() { _lastChanged = usecTimestampNow(); }
|
void markWithChangedTime() { _lastChanged = usecTimestampNow(); }
|
||||||
uint64_t getLastChanged() const { return _lastChanged; }
|
uint64_t getLastChanged() const { return _lastChanged; }
|
||||||
|
|
Loading…
Reference in a new issue