how draw multiple objects in DirectX 11

Started by
4 comments, last by x5reunion 9 years, 12 months ago

Hello Comrades. Im begginer in directx.

I'll write simple class to parse obj file to simple file with params to directX.

http://tinypic.com/view.php?pic=hsnfwz&s=8#.U1t94J8ru3k

As you can see i can download. every model from obj format. Now i have a question how to draw some difference models from files?

My Metod.

HRESULT InitGeometry()
{
SetShader();
int i;
//--------------------------------------------------------------------------------------------------------------------------------------------------------
// Code For Read Models Coord From File
vector <XMFLOAT3> vector_struct_vertex_one;
vector <XMFLOAT2> vector_struct_texture_one;
vector <XMFLOAT3> vector_struct_normals_one;
ObjParser ObjParser_one;
ObjParser_one.ReadFile("Sphere.txt", vector_struct_vertex_one,vector_struct_texture_one,vector_struct_normals_one);
Value_ONE = vector_struct_vertex_one.size();
//--------------------------------------------------------------------------------------------------------------------------------------------------------
SimpleVertex *vertices_one = new SimpleVertex[Value_ONE];
for (i = 0; i < vector_struct_vertex_one.size(); i++ )
{
vertices_one.Pos = vector_struct_vertex_one;
vertices_one.Color = XMFLOAT4(vector_struct_vertex_one.x, vector_struct_vertex_one.y, vector_struct_vertex_one.z, 1);
}
// Fill in a buffer description.
D3D11_BUFFER_DESC bufferDesc;
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
bufferDesc.ByteWidth = sizeof( SimpleVertex ) * Value_ONE;
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufferDesc.CPUAccessFlags = 0;
bufferDesc.MiscFlags = 0;
// Fill in the subresource data.
D3D11_SUBRESOURCE_DATA InitData;
InitData.pSysMem = vertices_one;
InitData.SysMemPitch = 0;
InitData.SysMemSlicePitch = 0;
hr = g_pd3dDevice->CreateBuffer( &bufferDesc, &InitData, &g_pVertexBuffer );
UINT stride = sizeof( SimpleVertex );
UINT offset = 0;
// Create the vertex buffer.
g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset );
g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
bufferDesc.ByteWidth = sizeof(ConstantBuffer);
bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bufferDesc.CPUAccessFlags = 0;
hr = g_pd3dDevice->CreateBuffer( &bufferDesc, NULL, &g_pConstantBuffer );
if (FAILED(hr)) return hr;
delete[] vertices_one;
return S_OK;
}
Render Method.

void Render()
{
float ClearColor[4] = { 0.0f, 0.0, 1.0f, 1.0f };
g_pImmediateContext->ClearRenderTargetView( g_pRenderTargetView, ClearColor );
g_pImmediateContext->ClearDepthStencilView( g_pDepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0 );
g_pImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 );
g_pImmediateContext->VSSetConstantBuffers( 0, 1, &g_pConstantBuffer );
g_pImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 );
SetMatrixes ( (XM_PI * 2) * 1 / 6 );
g_pImmediateContext->Draw( Value_ONE, 0 );
//SetMatrixes ( (XM_PI * 2));
//g_pImmediateContext_two->Draw( Value_TWO, 0 );
g_pSwapChain->Present( 0, 0 );
}

I'll try make difference ID3D11DeviceContext and ID3D11Buffer .

HRESULT InitGeometry_two()
{
SetShader();
int i;
//--------------------------------------------------------------------------------------------------------------------------------------------------------
// Code For Read Models Coord From File
........
//--------------------------------------------------------------------------------------------------------------------------------------------------------
Init Structure and buffers.
//
...
//
g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer_two, &stride_two, &offset_two );
g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
Constant Buffer
//
..
//
}
I'll try replace
g_pImmediateContext_two->IASetVertexBuffers( 0, 1, &g_pVertexBuffer_two, &stride_two, &offset_two );
and use in draw method
SetMatrixes ( (XM_PI * 2) * 1 / 6 );
g_pImmediateContext->Draw( Value_ONE, 0 );
//SetMatrixes ( (XM_PI * 2));
//g_pImmediateContext_two->Draw( Value_TWO, 0 );
But this not work every time i have error or only 1 model on window. Im understand what im wrong use
IASetVertexBuffers( 0, 1, &g_pVertexBuffer_two, &stride_two, &offset_two ); this func can save models Vertex in buffers. Im break my head, and you can kill me. I cant understand how use it.
Can you give me some examples or link what i must read?
Thanks. Sorry my bad engl.
P.S Sorry im only now look what im make wrong place Topic. Can Moderators replace him on general programming please. :)
Advertisement

Your post was a bit hard to follow but basically you just bind new vertex / index / instance buffers, textures, shaders, and whatver else you need to the input assembler and call Draw again. You obviously don't want to clear the render target etc. in between drawing multiple meshes that are supposed to end up on the screen together. If you think about the calls you use to draw one object it makes pretty good sense which ones you need to call again. The draw functions draw whatever is present in bound buffers and Present() basically flips the front and back buffer (assuming you have two).

Ok thanks Man i ll try reselve problem but nothing work. :(

A way to do what I think you're doing is - you want to load multiple meshes that are different? So for example: bigBird.obj and Kermit.obj? You're able to load which is good. Now the OBJ parse loads all the vertex information and the indice data dn places them inside your struct, right? For instance:


struct MeshVertexData {
XMFLOAT3 position;
XMFLOAT2 textureCoords;
XMFLOAT3 Normals;
};

If this is the case then what you could do is stuff the important information that is required for rending: IndiceBuffer, VertexBuffer, PixelShader, VertexShaders, InputLayouts including the vertexData structure you hold the information about the OBJ file. Anything that's important in one different structure; including a texture resource. For an example:


struct MySpecialModels {

MeshVertexData *meshData;
ID3D11Buffer *VertexBuffer, *IndiceBuffer;
ID3D11PixelShader *pixelShader;
ID3D11VertexShader *vertexShader;
ID3D11InputLayout *inputLayout;
XMMATRIX WorldMatrix, TransformMatrix,ScaleMatrix,RotationMatrix;
ID3D11ShaderResourceVIew *textureResource;

};

That's the important information about your mesh. When you parse your OBJ; you fill out your SpecialMeshStruct - once you filled the entire structure up then you have to put it inside a list or a vector or whatever stl collector.

My custom mesh structure goes inside a vector.


#include <vector>

std::vector<MySpecialMeshStruct> meshCollections;

So after you're done filling up your structure like I said before you have to place them inside the vector by declairing. meshCollections.push_back(myspecialStructureThatBeenFilled);

The "mysecialStructureThatBeenFilled" is just a temporary structure to fill up the mesh collection list.

When you are about to render you can ilerate through the mesh collection list by calling AND after you cleared the render target and depth stencil view.. I'm not sure if this is overwhelming you or not. But you should get the basic gist of how to render multiple meshes at once.

Game Engine's WIP Videos - http://www.youtube.com/sicgames88
SIC Games @ GitHub - https://github.com/SICGames?tab=repositories
Simple D2D1 Font Wrapper for D3D11 - https://github.com/SICGames/D2DFontX

Thank you man . YES you are RIGHT.

Im now Understand what this more harder than i think before,

I correctrly understand what i need do ?

understand . . . .understand ... . . .understand . . . . smile.png

1

Parse obj file

Read Vertex Coord, Text Coord and normals Coord.

2

Make my struct for Mesh

With Data what you say

Set all params in Struct What i need.

3

push_back all this struct in Vector.

4

Render everyone struct from vector.

Yes its realy hard i have only 1 question.

What metod i need use to draw Struct from vector?

How its working?

p.s now only need improve my C++ skill programming, and English.

Hello again i resolve problem!.

i make two struct like say SIC Games in previous post.

struct SimpleVertex
{
XMFLOAT3 Pos;
XMFLOAT4 Color;
};


struct MySpecialModels {

SimpleVertex meshData; // <<------------------------------- I dont have Idia, but i cant make it works with pointer like this SimpleVertex *meshData

int COORD_NUMS; // <<------------------------------- I think its low my C++ porgramming skill.
ID3D11Buffer *VertexBuffer;
};

Make Global Vector.

vector <MySpecialModels*> Models_Vector;

In Function called this metods

HRESULT InitGeometry()

{

HRESULT hr = S_OK;

SetShader();

//-----------------------------------------------------------------------------------------------------------------

// Here you must USE your code for download model.!!!

vector <XMFLOAT3> vector_vertex;
vector <XMFLOAT2> vector_texture;
vector <XMFLOAT3> vector_index;
vector <XMFLOAT3> vector_vertex_two;
vector <XMFLOAT2> vector_texture_two;
vector <XMFLOAT3> vector_index_two;
ObjParser objparser, objparser_two;
objparser.ReadFile( "Ship.txt", vector_vertex, vector_texture, vector_index);
objparser_two.ReadFile( "Sphere.txt", vector_vertex_two, vector_texture_two, vector_index_two );
int i;
MySpecialModels *MY_MODEL = new MySpecialModels[vector_vertex.size()];
MySpecialModels *MY_MODEL_TWO = new MySpecialModels[vector_vertex_two.size()];
for ( i = 0; i < vector_vertex_two.size(); i++ )
{
MY_MODEL_TWO.meshData.Pos = vector_vertex_two;
MY_MODEL_TWO.meshData.Color = XMFLOAT4(vector_vertex_two.x, vector_vertex_two.y, vector_vertex_two.z, 0.5f );
}
MY_MODEL_TWO->COORD_NUMS = vector_vertex_two.size();
for ( i = 0; i < vector_vertex.size(); i++ )
{
MY_MODEL.meshData.Pos = vector_vertex;
MY_MODEL.meshData.Color = XMFLOAT4(vector_vertex.x*0.2f*rand(), vector_vertex.y*1.3f*rand(), vector_vertex.z*07.f*rand(), 0.5f );
}
MY_MODEL->COORD_NUMS = vector_vertex.size();
Models_Vector.push_back( MY_MODEL );
Models_Vector.push_back( MY_MODEL_TWO);
// Here you must USE your code for download model.!!!

//-----------------------------------------------------------------------------------------------------------------

D3D11_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( MySpecialModels )* Models_Vector[0]->COORD_NUMS;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory( &InitData, sizeof(InitData) );
InitData.pSysMem = &Models_Vector[0]->meshData;
hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &Models_Vector[0]->VertexBuffer );
if (FAILED(hr)) return hr;
ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( MySpecialModels )* Models_Vector[1]->COORD_NUMS;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
ZeroMemory( &InitData, sizeof(InitData) );
InitData.pSysMem = &Models_Vector[1]->meshData;
hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &Models_Vector[1]->VertexBuffer );
if (FAILED(hr)) return hr;
g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

//----------------------------------------------

Constant Buffers etc. . . . . .

}

I make mistake when i'll try

Put metod g_pImmediateContext->IASetVertexBuffers( 0, 1, &Models_Vector[0]->VertexBuffer, &stride, &offset ); in init geometry i called him

on Render Function and all works fine now.

P.S if you wanna render difference primitive you need call IASetVertexBuffers in render function.

void Render()
{
float ClearColor[4] = { 0.0f, 0.0f, 1.0f, 1.0f };
g_pImmediateContext->ClearRenderTargetView( g_pRenderTargetView, ClearColor );
// Dept Buffer for correctly rendering
g_pImmediateContext->ClearDepthStencilView( g_pDepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0 );
g_pImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 );
g_pImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 );
g_pImmediateContext->VSSetConstantBuffers( 0, 1, &g_pConstantBuffer );
UINT stride = sizeof( MySpecialModels );
UINT offset = 0;
//--------------------------------------------------------------------------------------
g_pImmediateContext->IASetVertexBuffers( 0, 1, &Models_Vector[0]->VertexBuffer, &stride, &offset );
SetMatrixes(0,0,1);
g_pImmediateContext->Draw( Models_Vector[0]->COORD_NUMS, 0 );
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
g_pImmediateContext->IASetVertexBuffers( 0, 1, &Models_Vector[1]->VertexBuffer, &stride, &offset );
//SetMatrixes(0,0,2);
//g_pImmediateContext->Draw( Models_Vector[1]->COORD_NUMS, 0 );
SetMatrixes(2,0,0);
g_pImmediateContext->Draw( Models_Vector[1]->COORD_NUMS, 0 );
//--------------------------------------------------------------------------------------
//-----------------------------------------------------------------
// WireFrame
g_pImmediateContext->RSSetState(mWireframeRS);
// WireFrame
//-----------------------------------------------------------------
g_pSwapChain->Present( 0, 0 );
}

I render ship, he includes 108760 Vert 109240 Norm 53979 Tvert and 219248 Triangles. And simple sphere.

Now only need make class for automate this metods.

My example is very simple i dont use in structure texture coord, position scaling etc.

But now i have pointer to continue research DirectX smile.png

Thanks all for help.

http://postimg.org/image/6jvwrsob3/ Ship Image. Big.

This topic is closed to new replies.

Advertisement