2013-03-20 1 views
2

) 관리되지 않는 DirectX 11로 처음으로 탐구하고 (저와 품으십시오), 문제는, 질문이있는 나.(동적 인 정점/일정한 장면 내용 변경을 % s 가진 완충기 실시

개체가 시간이 지남에 따라 장면에 추가되는 앱으로 개발 중입니다. 각 렌더 루프에서 장면의 모든 정점을 수집하여 성능 및 모범 사례를 위해 단일 정점 및 인덱스 버퍼를 다시 사용하여 렌더링합니다. 내 질문은 동적 버텍스 및 인덱스 버퍼의 사용에 관한 것입니다. 장면 내용이 바뀌면 정확한 사용법을 완전히 이해할 수 없었습니다.

vertexBufferDescription.Usage    = D3D11_USAGE_DYNAMIC; 
vertexBufferDescription.BindFlags   = D3D11_BIND_VERTEX_BUFFER; 
vertexBufferDescription.CPUAccessFlags  = D3D11_CPU_ACCESS_WRITE; 
vertexBufferDescription.MiscFlags   = 0; 
vertexBufferDescription.StructureByteStride = 0; 

장면이 초기화 될 때 버퍼를 만들어야하고 모든 프레임에서 어떻게 내용을 업데이트해야합니까? 그렇다면 버퍼 설명에 어떤 ByteSize를 설정해야합니까? 그리고 그것으로 무엇을 초기화합니까?

또는 현재 버텍스 수를 크기로 사용하여 장면이 처음 렌더링 될 때 (프레임 1) 생성해야합니까? 그렇다면 장면에 다른 객체를 추가 할 때 버퍼를 다시 만들고 버퍼 설명의 ByteWidth를 새 버텍스 수로 변경하지 않아도됩니까? 내 장면이 각 프레임의 꼭지점을 계속 업데이트하면 단일 동적 버퍼의 사용은 다음과 같이 목적을 잃어 버릴 수 있습니다 ...

장면을 렌더링 할 때 처음 버퍼를 테스트하고 거기에 각 프레임에 Map/Unmap을 사용합니다. 각 개체의 정점의 버퍼 위치를 추적 유지하면서, 렌더링 루프의 끝에서

void Scene::Render() 
{ 
    (...) 

    std::vector<VERTEX> totalVertices; 
    std::vector<int> totalIndices; 
    int totalVertexCount = 0; 
    int totalIndexCount = 0; 

    for (shapeIterator = models.begin(); shapeIterator != models.end(); ++shapeIterator) 
    { 
      Model* currentModel = (*shapeIterator); 

      // totalVertices gets filled here... 
    } 

    // At this point totalVertices and totalIndices have all scene data 

    if (isVertexBufferSet) 
    { 
     // This is where it copies the new vertices to the buffer. 
     // but it's causing flickering in the entire screen... 
     D3D11_MAPPED_SUBRESOURCE resource; 
     context->Map(vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource); 
     memcpy(resource.pData, &totalVertices[0], sizeof(totalVertices)); 
     context->Unmap(vertexBuffer, 0); 
    } 
    else 
    { 
     // This is run in the first frame. But what if new vertices are added to the scene? 
     vertexBufferDescription.ByteWidth = sizeof(VERTEX) * totalVertexCount; 
     UINT stride = sizeof(VERTEX); 
     UINT offset = 0; 

     D3D11_SUBRESOURCE_DATA resourceData; 
     ZeroMemory(&resourceData, sizeof(resourceData)); 
     resourceData.pSysMem = &totalVertices[0]; 

     device->CreateBuffer(&vertexBufferDescription, &resourceData, &vertexBuffer); 
     context->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset); 
     isVertexBufferSet = true; 
    } 

: 나는 모든 장면 객체와 벡터 목록을 작성하여 시작하고 다음과 같이 리소스를 업데이트 마침내 Draw()를 호출합니다.

context->Draw(objectVertexCount, currentVertexOffset); 
} 

현재 구현으로 인해 전체 화면이 깜박입니다. 그러나 메모리 누출은 없습니다. Map/Unmap API를 사용하는 것과 관련이 있다면 궁금하십니까?

또한이 시나리오에서 buffer-> Release()를 호출하는 것이 이상적일까요? 팁이나 코드 샘플이 좋습니다! 미리 감사드립니다! 다음을 수행 정점 버퍼에 방어 적이기에서

+1

버텍스를 버텍스 버퍼에 복사하는 것은 각 버텍스가 모든 프레임을 변경하지 않는 한 대단히 비효율적 인 것처럼 보입니다. 한 번 버퍼를 만드는 것이 훨씬 더 정상입니다. – jcoder

+0

그동안 나는 깜빡 거리는 문제를 해결할 수있었습니다. memcpy가 잘못되어 복사 할 바이트 양이 잘못 전달되었습니다. sizeof (VERTEX) * totalVertices.size()가되어야합니다. – VOliveira

+0

@jcoder 맞습니다. 나는 장면의 더티 상태를 정확하게 제어하여 버퍼를 그대로두고 있다고 언급하는 것을 잊었다.vertex/index 버퍼 생성이 코드 샘플과 같이 첫 번째 프레임보다는 init()에서 수행 될 수 있는지 확실하지 않습니다. – VOliveira

답변

3

:

memcpy(resource.pData, &totalVertices[0], sizeof(totalVertices)); 

sizeof(totalVertices)

그냥 표준의 크기 : 벡터 < VERTEX> 당신이 원하는 것이 아닙니다 요구된다.
memcpy(resource.pData, &totalVertices[0], sizeof(VERTEX) * totalVertices.size()); 

은 또한 당신이 isVertexBufferSet에 해당하는 경우 IASetVertexBuffers 전화에 표시되지 않습니다 :

다음 코드를 사용해보십시오. 그렇게했는지 확인하십시오.