void configure() { if (m_nested == NULL) Log(EError, "A nested volume data source is needed!"); m_aabb = m_nested->getAABB(); if (!m_aabb.isValid()) Log(EError, "Nested axis-aligned bounding box was invalid!"); if (m_voxelWidth == -1) m_voxelWidth = m_nested->getStepSize(); size_t memoryLimitPerCore = m_memoryLimit / std::max((size_t) 1, Scheduler::getInstance()->getLocalWorkerCount()); Vector totalCells = m_aabb.getExtents() / m_voxelWidth; for (int i=0; i<3; ++i) m_cellCount[i] = (int) std::ceil(totalCells[i]); if (m_nested->supportsFloatLookups()) m_channels = 1; else if (m_nested->supportsVectorLookups()) m_channels = 1; else if (m_nested->supportsSpectrumLookups()) m_channels = SPECTRUM_SAMPLES; else Log(EError, "Nested volume offers no access methods!"); m_blockRes = m_blockSize+1; int blockMemoryUsage = (int) std::pow((Float) m_blockRes, 3) * m_channels * sizeof(float); m_blocksPerCore = memoryLimitPerCore / blockMemoryUsage; m_worldToVolume = m_volumeToWorld.inverse(); m_worldToGrid = Transform::scale(Vector(1/m_voxelWidth)) * Transform::translate(-Vector(m_aabb.min)) * m_worldToVolume; m_voxelMask = m_blockSize-1; m_blockMask = ~(m_blockSize-1); m_blockShift = log2i((uint32_t) m_blockSize); Log(EInfo, "Volume cache configuration"); Log(EInfo, " Block size in voxels = %i", m_blockSize); Log(EInfo, " Voxel width = %f", m_voxelWidth); Log(EInfo, " Memory usage of one block = %s", memString(blockMemoryUsage).c_str()); Log(EInfo, " Memory limit = %s", memString(m_memoryLimit).c_str()); Log(EInfo, " Memory limit per core = %s", memString(memoryLimitPerCore).c_str()); Log(EInfo, " Max. blocks per core = %i", m_blocksPerCore); Log(EInfo, " Effective resolution = %s", totalCells.toString().c_str()); Log(EInfo, " Effective storage = %s", memString((size_t) (totalCells[0]*totalCells[1]*totalCells[2]*sizeof(float)*m_channels)).c_str()); }
void memStringRealloc(memChunk *chunk) { memCheckState (); memChunk *temp; temp = memString (chunk->address); //printf("Reallocating chunk size %d to size %d\n",chunk->size,temp->size); memCopy (chunk,temp); memFree (temp); }
void sreplace(char *s,char *orig,char *rep,char multi,long dsize) { char *p; memChunk *buffer,*string,*result; if(!(p=strstr(s, orig))) return; buffer=memReserve(dsize); string=memString(s); memCopy(buffer, string); snprintf(buffer->address+(p-s), buffer->size-(p-s),"%s%s", rep, p+strlen(orig)); result=memString(buffer->address); strcpy(s,result->address); //unsafe memFree(string); memFree(result); memFree(buffer); }
void memStrCat(memChunk *dest, char *string) { memChunk result,*temp; temp = memReserve (dest->size + strlen (string)+1); result.address = dest->address + strlen (dest->address); result.size = dest->size - strlen (dest->address) + 1; memCopy (temp, memString (string)); memCopy (&result, temp); memFree (temp); }
void GLGeometry::refresh() { Assert(m_id[0] != 0 && m_id[1] != 0); m_stride = 3; if (m_mesh->hasVertexNormals()) m_stride += 3; if (m_mesh->hasVertexTexcoords()) m_stride += 2; if (m_mesh->hasUVTangents()) m_stride += 3; if (m_mesh->hasVertexColors()) m_stride += 3; m_stride *= sizeof(GLfloat); size_t vertexCount = m_mesh->getVertexCount(), triCount = m_mesh->getTriangleCount(); m_size[EVertexID] = (GLuint) (vertexCount * m_stride); m_size[EIndexID] = (GLuint) (triCount * sizeof(GLuint) * 3); Log(ETrace, "Uploading a GPU geometry object (\"%s\", " SIZE_T_FMT " vertices, " SIZE_T_FMT " triangles, %s)", getName().c_str(), vertexCount, triCount, memString(m_size[EVertexID] + m_size[EIndexID]).c_str()); GLfloat *vertices = new GLfloat[vertexCount * m_stride/sizeof(GLfloat)]; GLuint *indices = (GLuint *) m_mesh->getTriangles(); const Point *sourcePositions = m_mesh->getVertexPositions(); const Normal *sourceNormals = m_mesh->getVertexNormals(); const Point2 *sourceTexcoords = m_mesh->getVertexTexcoords(); const Color3 *sourceColors = m_mesh->getVertexColors(); Vector *sourceTangents = NULL; if (m_mesh->hasUVTangents()) { /* Convert into per-vertex tangents */ const TangentSpace *triTangents = m_mesh->getUVTangents(); sourceTangents = new Vector[vertexCount]; uint32_t *count = new uint32_t[vertexCount]; memset(sourceTangents, 0, sizeof(Vector)*vertexCount); for (size_t i=0; i<triCount; ++i) { const Triangle &tri = m_mesh->getTriangles()[i]; const TangentSpace &tangents = triTangents[i]; for (int j=0; j<3; ++j) { sourceTangents[tri.idx[j]] += tangents.dpdu; ++count[tri.idx[j]]; } } for (size_t i=0; i<vertexCount; ++i) { if (count[i] == 0) continue; sourceTangents[i] /= (Float) count[i]; } delete[] count; } size_t pos = 0; for (size_t i=0; i<vertexCount; ++i) { vertices[pos++] = (GLfloat) sourcePositions[i].x; vertices[pos++] = (GLfloat) sourcePositions[i].y; vertices[pos++] = (GLfloat) sourcePositions[i].z; if (sourceNormals) { vertices[pos++] = (GLfloat) sourceNormals[i].x; vertices[pos++] = (GLfloat) sourceNormals[i].y; vertices[pos++] = (GLfloat) sourceNormals[i].z; } if (sourceTexcoords) { vertices[pos++] = (GLfloat) sourceTexcoords[i].x; vertices[pos++] = (GLfloat) sourceTexcoords[i].y; } if (sourceTangents) { vertices[pos++] = (GLfloat) sourceTangents[i].x; vertices[pos++] = (GLfloat) sourceTangents[i].y; vertices[pos++] = (GLfloat) sourceTangents[i].z; } if (sourceColors) { vertices[pos++] = (GLfloat) sourceColors[i][0]; vertices[pos++] = (GLfloat) sourceColors[i][1]; vertices[pos++] = (GLfloat) sourceColors[i][2]; } } Assert(pos * sizeof(GLfloat) == m_stride * vertexCount); bind(); glBufferData(GL_ARRAY_BUFFER, m_size[EVertexID], vertices, GL_STATIC_DRAW); if (GLEW_NV_vertex_buffer_unified_memory) { glGetBufferParameterui64vNV(GL_ARRAY_BUFFER, GL_BUFFER_GPU_ADDRESS_NV, &m_addr[EVertexID]); glMakeBufferResidentNV(GL_ARRAY_BUFFER, GL_READ_ONLY); } glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_size[EIndexID], indices, GL_STATIC_DRAW); if (GLEW_NV_vertex_buffer_unified_memory) { glGetBufferParameterui64vNV(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_GPU_ADDRESS_NV, &m_addr[EIndexID]); glMakeBufferResidentNV(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY); } unbind(); delete[] vertices; if (sourceTangents) delete[] sourceTangents; }
memChunk *memStringReserve(char *string, long nbytes) { static memChunk *buffer; buffer=memReserve (nbytes); memCopy (buffer, memString (string)); return buffer; }