Jump to content
  • Advertisement
Sign in to follow this  
Ubermeowmix

DirectX rendering procedure

This topic is 1640 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm having trouble understanding how directX deals with the objects being called and when it renders each one.

 

In a nutshell is it like this?:

 

1. set render states

2. set vertex format

3. load vertex buffers

         3.1. create vertex buffer (lock buffer)

         3.2. fill the buffer with array data

         3.3. Copy array data and then unlock buffer.

4. Draw to scene

5. Present data

 

So do I create classes to load multiple models at step 3 before step 4?

Or does each model have to go through the process up to draw before present is called at step 5?

 

Help would be greatly appreciated!

 

 

Share this post


Link to post
Share on other sites
Advertisement

Not quite. You can think of DX11 application has having 3 distinct stages:

 

  • Load - in this stage you create all your state objects. Shaders, render states, resources, resource-views, vertex buffers, index buffers, constant buffers, etc.
    • This is stage where you load all you models and materials.
  • Rendering - the main rendering loop. this is the stage where you use the objects created in the load stage. In this stage you usually:
    • Set render states(depth state, rasterizer state, blend state).
    • Set viewport
    • Set and clear the render-target-view and depth-stencil-view.
    • Set shaders and shaders state
      • Samplers
      • Shader resource views
      • Constant buffer. In most cases, you map the CBs, fill them with data, unmap and bind them.
    • Set vertex and index buffer, input element layout, topology. Note that there's usually no reason to change the content of your VB/IB.
    • Draw.
  • Cleanup stage - release all the objects you created during load.

As you can see, the main rendering loop doesn't create anything, and besides the CBs doesn't use any dynamic buffers (there are exceptions, of course). This reduces API overhead and allows the driver to be more clever about optimizations it makes.

And unless I forgot something, this is DX11 in a nutshell.

Edited by satanir

Share this post


Link to post
Share on other sites

Is short, you setup rendering states: render targets, render states, textures, buffers, other things, and then draw. After that you need to change only what changed.

So lets say if you have 100 different models that use same textures/everything your loop would look like (pseudocode):

context->SetShader()
context->SetIndexBuffer() // assuming index buffer is identical
context->SetVertexFormat()
context->SetRenderTarget()
for(...) {
    context->SetVertexBuffer()
    context->Draw()
}

Share this post


Link to post
Share on other sites

Okay one more lol, getting lost in how to implement what I need using derived classes.

 

So I can lay it out like this then:

 

WinMain -> calls AssetsClass;

     during windows message check:

         calls AssetsClass->Update();

                 AssetsClass->Render();

 

DirectxBaseInitialization (class)

     virtual Render();

     virtual Update();

AssetsClass : public DirectxBaseInitialization

     virtual Update();

 

Then I can wrap all my code in the following classes Sprites, Font's & 3Dmodels. All 'public DirectxBaseInitialization'.

Then it all waterfalls back down the pipeline to the render call that is called by AssetsClass.

 

Or is that barking up the wrong tree?

Share this post


Link to post
Share on other sites

Okay I've gone away and RTFM a bit more,

 

I'm to the point where:

  • I've tied object creation down to the Vertex buffer & Index buffer in initialization
  • Declaration of the objects world Scale * rotation * translation in updating your scene
  • And drawing the object using the loaded textures, texture samplers & the vertex shader buffer in the DrawScene stage

I'm currently trying to encapsulate object creation (cubes) into a vector, problem is it's failing at runtime due to the CubesClass containing XMMATRIX variables.

 

How do I get round this? and why wont Vector allow a class containing them?

Share this post


Link to post
Share on other sites

problem is it's failing at runtime due to the CubesClass containing XMMATRIX variables.

No it’s not.

why wont Vector allow a class containing them?

It does.

How do I get round this?

Better show some code and provide more information.


L. Spiro

Share this post


Link to post
Share on other sites

#ifndef _C_MY_OBJECT_H_
#define _C_MY_OBJECT_H_

#include <xnamath.h>

class cMyObject
{
public:
    cMyObject() :    posX(0.0f),
                    posY(0.0f),
                    posZ(0.0f),
                    rot(0.0f),
                    scaleMod(0.3f),
                    scaleFull(false) {};
    ~cMyObject() {};

    //void DeclareMyObject(float rotPassed, float posXnew, float posYnew, float posZnew)
    void DeclareMyObject(    float newScale,
                            float rotIn,
                            float posXnew,
                            float posYnew,
                            float posZnew )
    {
        currCubeWorldMat = XMMatrixIdentity();                                            //Reset current cubes coords

        Scale = XMMatrixScaling( newScale, newScale, newScale );

        XMVECTOR rotaxis = XMVectorSet( 0.0f, 0.0f, 1.0f, 0.0f );                    //Define objects world space matrix
        Rotation = XMMatrixRotationAxis( rotaxis, rotIn );
        Translation = XMMatrixTranslation( posXnew, posYnew, posZnew );

        //SRT scale, rot, translation
        currCubeWorldMat = Scale * Rotation * Translation;                                //Set cube1's world space using the transformations
    }

    XMMATRIX ReturnWorldMatrix() { return currCubeWorldMat; }

    /*
    void DrawMyObject(    ID3D11DeviceContext* d3d11DevCon,
                            XMMATRIX& WVP,
                            cbPerObject& cbPerObjectBuffer,
                            cbPerObject& cbPerObj,
                            ID3D11ShaderResourceView* TextureRef,
                            ID3D11SamplerState* TexSamplerRef,
                            XMMATRIX& camView,
                            XMMATRIX& camProjection)
    {
        WVP = currCubeWorldMat * camView * camProjection;
        cbPerObj.WVP = XMMatrixTranspose(WVP);
        d3d11DevCon->UpdateSubresource( cbPerObjectBuffer, 0, NULL, &cbPerObj, 0, 0 );
        d3d11DevCon->VSSetConstantBuffers( 0, 1, &cbPerObjectBuffer );
        d3d11DevCon->PSSetShaderResources( 0, 1, &TextureRef );
        d3d11DevCon->PSSetSamplers( 0, 1, &TexSamplerRef );
    
        //Draw the cube
        d3d11DevCon->DrawIndexed( 36, 0, 0 );
    }
    */

private:
    XMMATRIX    currCubeWorldMat;

    XMMATRIX    Scale,
                Rotation,
                Translation;

    float        posX,
                posY,
                posZ,
                rot,
                scaleMod;

    bool        scaleFull;
};

#endif

 

//declarations at the top of main.cpp

std::vector<cMyObject> vCubes;

 

 

in the main update function

void UpdateScene()
{
    float newX = 0.0f;

    for(int i = 0; i < 3; i++)
    {
        vCubes.push_back( cMyObject( ) );
        vCubes[i].DeclareMyObject( newX, 0.0f, 0.0f );
        newX += 0.3f;
    }
}

 

in the drawscene function when I swap to this function i get the following error:

1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\vector(870): error C2719: '_Val': formal parameter with __declspec(align('16')) won't be aligned
1>          main.cpp(103) : see reference to class template instantiation 'std::vector<_Ty>' being compiled

 

for(int i = 0; i < 3; i++)
    {
        WVP = vCubes[i].ReturnWorldMatrix() * camView * camProjection;
        cbPerObj.WVP = XMMatrixTranspose(WVP);
        d3d11DevCon->UpdateSubresource( cbPerObjectBuffer, 0, NULL, &cbPerObj, 0, 0 );
        d3d11DevCon->VSSetConstantBuffers( 0, 1, &cbPerObjectBuffer );
        d3d11DevCon->PSSetShaderResources( 0, 1, &CubesTexture );
        d3d11DevCon->PSSetSamplers( 0, 1, &CubesTexSamplerState );

        //Draw the cube
        d3d11DevCon->DrawIndexed( 36, 0, 0 );
    }

 

 

The code works fine if I split up the variables into seperate calls eg:

//initial declarations
cMyObject object1;
cMyObject object2;
cMyObject object3;
 
//in the update scene
object1.DeclareMyObject( scaleMod, rot, -2.0f, 0.0f, 0.0f );
object2.DeclareMyObject( scaleMod, rot, 0.0f, 3.0f, 2.0f );
object3.DeclareMyObject( scaleMod, rot, 4.0f, 1.0f, 0.0f );
 
//in the draw call
WVP = object1.ReturnWorldMatrix() * camView * camProjection;
    cbPerObj.WVP = XMMatrixTranspose(WVP);
    d3d11DevCon->UpdateSubresource( cbPerObjectBuffer, 0, NULL, &cbPerObj, 0, 0 );
    d3d11DevCon->VSSetConstantBuffers( 0, 1, &cbPerObjectBuffer );
    d3d11DevCon->PSSetShaderResources( 0, 1, &CubesTexture2 );
    d3d11DevCon->PSSetSamplers( 0, 1, &CubesTexSamplerState2 );
   
    //Draw the cube
    d3d11DevCon->DrawIndexed( 36, 0, 0 );
//code repeated with 2/3 etc

Share this post


Link to post
Share on other sites

I was trying to implement:

 

object1.DrawMyObject( d3d11DevCon, WVP, cbPerObjectBuffer, cbPerObj, CubesTexture2, CubesTexSamplerState2, camView, camProjection );

 

But that does the same so I seperated it from the class to try identify where the error was.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!