Exemple #1
0
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;
}