void Buffer::copySubData(glow::Buffer* buffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) { assert(buffer != nullptr); if (m_directStateAccess) { glNamedCopyBufferSubDataEXT(m_id, buffer->id(), readOffset, writeOffset, size); CheckGLError(); } else { glBindBuffer(GL_COPY_WRITE_BUFFER, buffer->id()); CheckGLError(); copySubData(GL_COPY_WRITE_BUFFER, readOffset, writeOffset, size); glBindBuffer(GL_COPY_WRITE_BUFFER, 0); CheckGLError(); } }
void BufferImplementation_DirectStateAccessEXT::copySubData(const Buffer * buffer, Buffer * other, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) const { glNamedCopyBufferSubDataEXT(buffer->id(), other->id(), readOffset, writeOffset, size); }
void CadScene::resetMatrices() { glNamedCopyBufferSubDataEXT(m_matricesOrigGL, m_matricesGL, 0, 0, sizeof(CadScene::MatrixNode) * m_matrices.size()); }
bool CadScene::loadCSF( const char* filename, int clones, int cloneaxis) { CSFile* csf; CSFileMemoryPTR mem = CSFileMemory_new(); if (CSFile_loadExt(&csf,filename,mem) != CADSCENEFILE_NOERROR || !(csf->fileFlags & CADSCENEFILE_FLAG_UNIQUENODES)){ CSFileMemory_delete(mem); return false; } int copies = clones + 1; CSFile_transform(csf); srand(234525); // materials m_materials.resize( csf->numMaterials ); for (int n = 0; n < csf->numMaterials; n++ ) { CSFMaterial* csfmaterial = &csf->materials[n]; Material& material = m_materials[n]; for (int i = 0; i < 2; i++){ material.sides[i].ambient = randomVector(0.0f,0.1f); material.sides[i].diffuse = nv_math::vec4f(csf->materials[n].color) + randomVector(0.0f,0.07f); material.sides[i].specular = randomVector(0.25f,0.55f); material.sides[i].emissive = randomVector(0.0f,0.05f); } } glGenBuffers(1,&m_materialsGL); glNamedBufferStorageEXT(m_materialsGL, sizeof(Material) * m_materials.size(), &m_materials[0], 0); //glMapNamedBufferRange(m_materialsGL, 0, sizeof(Material) * m_materials.size(), GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT); // geometry int numGeoms = csf->numGeometries; m_geometry.resize( csf->numGeometries * copies ); m_geometryBboxes.resize( csf->numGeometries * copies ); for (int n = 0; n < csf->numGeometries; n++ ) { CSFGeometry* csfgeom = &csf->geometries[n]; Geometry& geom = m_geometry[n]; geom.cloneIdx = -1; geom.numVertices = csfgeom->numVertices; geom.numIndexSolid = csfgeom->numIndexSolid; geom.numIndexWire = csfgeom->numIndexWire; std::vector<Vertex> vertices( csfgeom->numVertices ); for (int i = 0; i < csfgeom->numVertices; i++){ vertices[i].position[0] = csfgeom->vertex[3*i + 0]; vertices[i].position[1] = csfgeom->vertex[3*i + 1]; vertices[i].position[2] = csfgeom->vertex[3*i + 2]; vertices[i].position[3] = 1.0f; if (csfgeom->normal){ vertices[i].normal[0] = csfgeom->normal[3*i + 0]; vertices[i].normal[1] = csfgeom->normal[3*i + 1]; vertices[i].normal[2] = csfgeom->normal[3*i + 2]; vertices[i].normal[3] = 0.0f; } else{ vertices[i].normal = normalize(nv_math::vec3f(vertices[i].position)); } m_geometryBboxes[n].merge( vertices[i].position ); } geom.vboSize = sizeof(Vertex) * vertices.size(); glGenBuffers(1,&geom.vboGL); glNamedBufferStorageEXT(geom.vboGL,geom.vboSize, &vertices[0], 0); std::vector<GLuint> indices(csfgeom->numIndexSolid + csfgeom->numIndexWire); memcpy(&indices[0],csfgeom->indexSolid, sizeof(GLuint) * csfgeom->numIndexSolid); if (csfgeom->indexWire){ memcpy(&indices[csfgeom->numIndexSolid],csfgeom->indexWire, sizeof(GLuint) * csfgeom->numIndexWire); } geom.iboSize = sizeof(GLuint) * indices.size(); glGenBuffers(1,&geom.iboGL); glNamedBufferStorageEXT(geom.iboGL, geom.iboSize, &indices[0], 0); if (GLEW_NV_vertex_buffer_unified_memory){ glGetNamedBufferParameterui64vNV(geom.vboGL, GL_BUFFER_GPU_ADDRESS_NV, &geom.vboADDR); glMakeNamedBufferResidentNV(geom.vboGL, GL_READ_ONLY); glGetNamedBufferParameterui64vNV(geom.iboGL, GL_BUFFER_GPU_ADDRESS_NV, &geom.iboADDR); glMakeNamedBufferResidentNV(geom.iboGL, GL_READ_ONLY); } geom.parts.resize( csfgeom->numParts ); size_t offsetSolid = 0; size_t offsetWire = csfgeom->numIndexSolid * sizeof(GLuint); for (int i = 0; i < csfgeom->numParts; i++){ geom.parts[i].indexWire.count = csfgeom->parts[i].indexWire; geom.parts[i].indexSolid.count = csfgeom->parts[i].indexSolid; geom.parts[i].indexWire.offset = offsetWire; geom.parts[i].indexSolid.offset = offsetSolid; offsetWire += csfgeom->parts[i].indexWire * sizeof(GLuint); offsetSolid += csfgeom->parts[i].indexSolid * sizeof(GLuint); } } for (int c = 1; c <= clones; c++){ for (int n = 0; n < numGeoms; n++ ) { m_geometryBboxes[n + numGeoms * c] = m_geometryBboxes[n]; const Geometry& geomorig = m_geometry[n]; Geometry& geom = m_geometry[n + numGeoms * c]; geom = geomorig; #if 1 geom.cloneIdx = n; #else geom.cloneIdx = -1; glGenBuffers(1,&geom.vboGL); glNamedBufferStorageEXT(geom.vboGL,geom.vboSize, 0, 0); glGenBuffers(1,&geom.iboGL); glNamedBufferStorageEXT(geom.iboGL,geom.iboSize, 0, 0); if (GLEW_NV_vertex_buffer_unified_memory){ glGetNamedBufferParameterui64vNV(geom.vboGL, GL_BUFFER_GPU_ADDRESS_NV, &geom.vboADDR); glMakeNamedBufferResidentNV(geom.vboGL, GL_READ_ONLY); glGetNamedBufferParameterui64vNV(geom.iboGL, GL_BUFFER_GPU_ADDRESS_NV, &geom.iboADDR); glMakeNamedBufferResidentNV(geom.iboGL, GL_READ_ONLY); } glNamedCopyBufferSubDataEXT(geomorig.vboGL, geom.vboGL, 0, 0, geom.vboSize); glNamedCopyBufferSubDataEXT(geomorig.iboGL, geom.iboGL, 0, 0, geom.iboSize); #endif } } glGenBuffers(1,&m_geometryBboxesGL); glNamedBufferStorageEXT(m_geometryBboxesGL,sizeof(BBox) * m_geometryBboxes.size(), &m_geometryBboxes[0], 0); glGenTextures(1, &m_geometryBboxesTexGL); glTextureBufferEXT(m_geometryBboxesTexGL, GL_TEXTURE_BUFFER, GL_RGBA32F, m_geometryBboxesGL); // nodes int numObjects = 0; m_matrices.resize( csf->numNodes * copies ); for (int n = 0; n < csf->numNodes; n++){ CSFNode* csfnode = &csf->nodes[n]; memcpy( m_matrices[n].objectMatrix.get_value(), csfnode->objectTM, sizeof(float)*16 ); memcpy( m_matrices[n].worldMatrix.get_value(), csfnode->worldTM, sizeof(float)*16 ); m_matrices[n].objectMatrixIT = nv_math::transpose( nv_math::invert(m_matrices[n].objectMatrix) ); m_matrices[n].worldMatrixIT = nv_math::transpose( nv_math::invert(m_matrices[n].worldMatrix) ); if (csfnode->geometryIDX < 0) continue; numObjects++; } // objects m_objects.resize( numObjects * copies ); m_objectAssigns.resize( numObjects * copies ); numObjects = 0; for (int n = 0; n < csf->numNodes; n++){ CSFNode* csfnode = &csf->nodes[n]; if (csfnode->geometryIDX < 0) continue; Object& object = m_objects[numObjects]; object.matrixIndex = n; object.geometryIndex = csfnode->geometryIDX; m_objectAssigns[numObjects] = nv_math::vec2i( object.matrixIndex, object.geometryIndex ); object.parts.resize( csfnode->numParts ); for (int i = 0; i < csfnode->numParts; i++){ object.parts[i].active = 1; object.parts[i].matrixIndex = csfnode->parts[i].nodeIDX < 0 ? object.matrixIndex : csfnode->parts[i].nodeIDX; object.parts[i].materialIndex = csfnode->parts[i].materialIDX; } BBox bbox = m_geometryBboxes[object.geometryIndex].transformed( m_matrices[n].worldMatrix ); m_bbox.merge( bbox ); updateObjectDrawCache(object); numObjects++; } // compute clone move delta based on m_bbox; nv_math::vec4f dim = m_bbox.max - m_bbox.min; int sq = 1; int numAxis = 0; for (int i = 0; i < 3; i++){ numAxis += (cloneaxis & (1<<i)) ? 1 : 0; } assert(numAxis); switch (numAxis) { case 1: sq = copies; break; case 2: while (sq * sq < copies){ sq++; } break; case 3: while (sq * sq * sq < copies){ sq++; } break; } for (int c = 1; c <= clones; c++){ int numNodes = csf->numNodes; nv_math::vec4f shift = dim * 1.05f; float u = 0; float v = 0; float w = 0; switch (numAxis) { case 1: u = float(c); break; case 2: u = float(c % sq); v = float(c / sq); break; case 3: u = float(c % sq); v = float((c / sq) % sq); w = float( c / (sq*sq)); break; } float use = u; if (cloneaxis & (1<<0)){ shift.x *= -use; if (numAxis > 1 ) use = v; } else { shift.x = 0; } if (cloneaxis & (1<<1)){ shift.y *= use; if (numAxis > 2 ) use = w; else if (numAxis > 1 ) use = v; } else { shift.y = 0; } if (cloneaxis & (1<<2)){ shift.z *= -use; } else { shift.z = 0; } shift.w = 0; // move all world matrices for (int n = 0; n < numNodes; n++ ) { MatrixNode &node = m_matrices[n + numNodes * c]; MatrixNode &nodeOrig = m_matrices[n]; node = nodeOrig; node.worldMatrix.set_col(3,node.worldMatrix.col(3) + shift); node.worldMatrixIT = nv_math::transpose( nv_math::invert(node.worldMatrix) ); } { // patch object matrix of root MatrixNode &node = m_matrices[csf->rootIDX + numNodes * c]; node.objectMatrix.set_col(3,node.objectMatrix.col(3) + shift); node.objectMatrixIT = nv_math::transpose( nv_math::invert(node.objectMatrix) ); } // clone objects for (int n = 0; n < numObjects; n++ ) { const Object& objectorig = m_objects[n]; Object& object = m_objects[ n + numObjects * c]; object = objectorig; object.geometryIndex += c * numGeoms; object.matrixIndex += c * numNodes; for (size_t i = 0; i < object.parts.size(); i++){ object.parts[i].matrixIndex += c * numNodes; } for (size_t i = 0; i < object.cacheSolid.state.size(); i++){ object.cacheSolid.state[i].matrixIndex += c * numNodes; } for (size_t i = 0; i < object.cacheWire.state.size(); i++){ object.cacheWire.state[i].matrixIndex += c * numNodes; } m_objectAssigns[n + numObjects * c] = nv_math::vec2i( object.matrixIndex, object.geometryIndex ); } } glGenBuffers(1,&m_matricesGL); glNamedBufferStorageEXT(m_matricesGL, sizeof(MatrixNode) * m_matrices.size(), &m_matrices[0], 0); //glMapNamedBufferRange(m_matricesGL, 0, sizeof(MatrixNode) * m_matrices.size(), GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT); glGenTextures(1,&m_matricesTexGL); glTextureBufferEXT(m_matricesTexGL, GL_TEXTURE_BUFFER, GL_RGBA32F, m_matricesGL); glGenBuffers(1,&m_objectAssignsGL); glNamedBufferStorageEXT(m_objectAssignsGL,sizeof(nv_math::vec2i) * m_objectAssigns.size(), &m_objectAssigns[0], 0); if (GLEW_NV_vertex_buffer_unified_memory){ glGetNamedBufferParameterui64vNV(m_materialsGL, GL_BUFFER_GPU_ADDRESS_NV, &m_materialsADDR); glMakeNamedBufferResidentNV(m_materialsGL, GL_READ_ONLY); glGetNamedBufferParameterui64vNV(m_matricesGL, GL_BUFFER_GPU_ADDRESS_NV, &m_matricesADDR); glMakeNamedBufferResidentNV(m_matricesGL, GL_READ_ONLY); if (GLEW_NV_bindless_texture){ m_matricesTexGLADDR = glGetTextureHandleNV(m_matricesTexGL); glMakeTextureHandleResidentNV(m_matricesTexGLADDR); } } m_nodeTree.create(copies * csf->numNodes); for (int i = 0; i < copies; i++){ int cloneoffset = (csf->numNodes) * i; int root = csf->rootIDX+cloneoffset; recursiveHierarchy(m_nodeTree,csf,csf->rootIDX,cloneoffset); m_nodeTree.setNodeParent( (NodeTree::nodeID)root, m_nodeTree.getTreeRoot() ); m_nodeTree.addToTree( (NodeTree::nodeID)root ); } glGenBuffers(1,&m_parentIDsGL); glNamedBufferStorageEXT(m_parentIDsGL, m_nodeTree.getTreeCompactNodes().size() * sizeof(GLuint), &m_nodeTree.getTreeCompactNodes()[0], 0); glGenBuffers(1,&m_matricesOrigGL); glNamedBufferStorageEXT(m_matricesOrigGL, sizeof(MatrixNode) * m_matrices.size(), &m_matrices[0], 0); glGenTextures(1,&m_matricesOrigTexGL); glTextureBufferEXT(m_matricesOrigTexGL, GL_TEXTURE_BUFFER, GL_RGBA32F, m_matricesOrigGL); CSFileMemory_delete(mem); return true; }