Autor Wątek: Problem z rysowanie quadów  (Przeczytany 1225 razy)

Offline MofC

  • Użytkownik

# Marzec 01, 2014, 15:54:41
Cześć, postanowiłem sobie napisać prosty moduł do generowania grafiki 2D w DirectX 11, używając  quadów. Wzorowałem się na tym tutorialu http://www.braynzarsoft.net/index.php?p=DX11Lessons z tym że w nim do rysowania prymitywów używany jest statyczny bufor wierzchołków, natomiast Ja używam dynamicznego. Mam zamiar zrobić tak jak w tutorialu Xionahttp://xion.org.pl/productions/texts/coding/game-programming/gfx2d/ tzn. skopiować kilka quadów mających przypisaną tą samą teksturę do bufora i dopiero gdy pojawi się obrazek z inną teksturą, rysować. Na razie umieszczam w buforze dwa obrazki i chce je narysować. I pojawia się problem taki że pierwszy obrazek się nie rysuje :(



Trochę z metody inicjalizującej


Init()
{
        //jakiś kod

QuadIndices[0] = 0;
QuadIndices[1] = 1;
QuadIndices[2] = 2;
QuadIndices[3] = 0;
QuadIndices[4] = 2;
QuadIndices[5] = 3;

QuadIndices[6] = 0;
QuadIndices[7] = 1;
QuadIndices[8] = 2;
QuadIndices[9] = 0;
QuadIndices[10] = 2;
QuadIndices[11] = 3;

inuseTexture=0;
QuadCount=0;

MapType=D3D11_MAP_WRITE_DISCARD;

        D3D11_BUFFER_DESC indexBufferDesc;
ZeroMemory( &indexBufferDesc, sizeof(indexBufferDesc) );

indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
indexBufferDesc.ByteWidth = sizeof(DWORD) * 12;
indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
indexBufferDesc.CPUAccessFlags = 0;
indexBufferDesc.MiscFlags = 0;

D3D11_SUBRESOURCE_DATA iinitData;

iinitData.pSysMem = QuadIndices;

hr = pd3d11Device->CreateBuffer(&indexBufferDesc, &iinitData, &IndexBuffer);
CheckError(hr,"Create indexBuffer");

pd3d11DevCon->IASetIndexBuffer( IndexBuffer, DXGI_FORMAT_R32_UINT, 0);

//BUFOR WIERZCHOLKOW


ZeroMemory( &vertexBufferDesc, sizeof(vertexBufferDesc) );

vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
vertexBufferDesc.ByteWidth = sizeof( Vertex ) * 40;
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
vertexBufferDesc.MiscFlags = 0;

hr = pd3d11Device->CreateBuffer( &vertexBufferDesc, 0, &VertBuffer);
CheckError(hr,"Create vertexBuffer");

        //jakis kod

Metoda dodająca obrazek do bufora
Vertex quad[4];

quad[0]=Vertex( posx, posy-image->texHeight,0.5f, 0.0f, 1.0f);
quad[1]=Vertex( posx, posy,0.5f, 0.0f, 0.0f);
quad[2]=Vertex(  posx + image->texWidth,posy, 0.5f, 1.0f, 0.0f);
quad[3]=Vertex(  posx + image->texWidth, posy-image->texHeight,0.5f, 1.0f, 1.0f);

D3D11_MAPPED_SUBRESOURCE resource;
ZeroMemory(&resource,sizeof(resource));

hr= pd3d11DevCon->Map(VertBuffer, 0, MapType, 0, &resource);
CheckError(hr,"Map");
memcpy(resource.pData, &quad, sizeof(quad));
    pd3d11DevCon->Unmap(VertBuffer, 0);

inuseTexture = image->Texture;

QuadCount++;
MapType=D3D11_MAP_WRITE_NO_OVERWRITE;

Metoda rysująca
UINT stride = sizeof( Vertex );
UINT offset = 0;
pd3d11DevCon->IASetVertexBuffers( 0, 1, &VertBuffer, &stride, &offset );


float blendFactor[] = {0.5f, 0.5f, 0.5f, 1.0f};

//Set the default blend state (no blending) for opaque objects
pd3d11DevCon->OMSetBlendState(0, 0, 0xffffffff);

//Create the Input Layout
hr = pd3d11Device->CreateInputLayout( layout, numElements, VertexShader->ReturnVSBuffer()->GetBufferPointer(), VertexShader->ReturnVSBuffer()->GetBufferSize(), &VertLayout );
CheckError(hr,"CreateInputLayout");

//set Renderstate
pd3d11DevCon->RSSetState(WireFrame);

//Set the Input Layout
pd3d11DevCon->IASetInputLayout( VertLayout );

//Set Primitive Topology
pd3d11DevCon->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

//Clear our backbuffer to the updated color
D3DXCOLOR bgColor( red, green, blue, 1.0f );

World = XMMatrixIdentity();

WVP = World * camView * camProjection;

cbPerObj.WVP = XMMatrixTranspose(WVP);

pd3d11DevCon->UpdateSubresource( cbPerObjectBuffer, 0, NULL, &cbPerObj, 0, 0 );

pd3d11DevCon->VSSetConstantBuffers( 0, 1, &cbPerObjectBuffer );

pd3d11DevCon->PSSetShaderResources( 0, 1, &inuseTexture );
pd3d11DevCon->PSSetSamplers( 0, 1, &CubesTexSamplerState );

pd3d11DevCon->ClearRenderTargetView(prenderTargetView, bgColor);
pd3d11DevCon->ClearDepthStencilView(pdepthStencilView, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0);

pd3d11DevCon->DrawIndexed( 6*QuadCount , 0, 0 );
//Present the backbuffer to the screen
pSwapChain->Present(0, 0);

MapType=D3D11_MAP_WRITE_DISCARD;
QuadCount=0;
inuseTexture = 0;

Bardzo proszę o pomoc
« Ostatnia zmiana: Marzec 01, 2014, 16:06:21 wysłana przez MofC »

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline MatlertheGreat

  • Użytkownik

# Marzec 01, 2014, 19:23:33
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, a pisałeś coś o quadach.

EDIT:
Sorry, głupotę napisałem, nie czytaj nawet.
« Ostatnia zmiana: Marzec 01, 2014, 19:25:45 wysłana przez MatlertheGreat »

Offline MofC

  • Użytkownik

# Marzec 02, 2014, 16:47:27
Po wielu godzinach spędzonych nad kompilatorem i przeczesywaniu internetu w poszukiwaniu kodów z przykładami DirectX, znalazłem taki który mi pomógł. Długo mi to zajęło bo okazuje się że większość osób przy rysowaniu spriteów używa statycznego bufora.

Po pierwsze, nadawałem złe wartości Indeksom. Powinno być:
QuadIndices[0] = 0;
QuadIndices[1] = 1;
QuadIndices[2] = 2;
QuadIndices[3] = 0;
QuadIndices[4] = 2;
QuadIndices[5] = 3;

QuadIndices[6] = 4;
QuadIndices[7] = 5;
QuadIndices[8] = 6;
QuadIndices[9] = 4;
QuadIndices[10] = 6;
QuadIndices[11] = 7;

Po drugie, w funkcji Memcpy trzeba przesunąć miejsce docelowe do wolnej pozycji w buforze. Z dokumentacji
msdn zrozumiałem że DirectX sam to robi, no ale tak nie jest.

D3D11_MAPPED_SUBRESOURCE resource;
ZeroMemory(&resource,sizeof(resource));

hr= pd3d11DevCon->Map(VertBuffer, 0, MapType, 0, &resource);
CheckError(hr,"Map");

char* bufferData = static_cast<char*>(resource.pData);
memcpy(bufferData+QuadCount*sizeof(quad), &quad, sizeof(quad));
    pd3d11DevCon->Unmap(VertBuffer, 0);

Teraz wszystko działa tak jak być powinno :D