Search code examples
c++directx-9

DirectX in C++ how to render a different texture on two objects


This may seem like a stupid Question but i have two cubes being rendered on screen. My assignment is to make them have different textures and spin at opposite rotation vectors. I can do the spinning but not the textures. Here is my code if that will help.

``

 //////////////////////////////////////////////////////////////////////////
// Name:    DirectXFramework.cpp
// Date:    April 2nd, 2010
// Author:  Kyle Lauing [klauing@devry.edu] or [kylelauing@gmail.com]
// Purpose: This file is used to create a very simple framework for using
//          DirectX 9 for the GSP 381 course for DeVry University.
// Disclaimer:  
//          Copyright © 2010 by DeVry Educational Development Corporation.
//          All rights reserved.  No part of this work may be reproduced 
//          or used in any form or by any means – graphic, electronic, or 
//          mechanical, including photocopying, recording, Web distribution 
//          or information storage and retrieval systems – without the 
//          prior consent of DeVry Educational Development Corporation.
//////////////////////////////////////////////////////////////////////////
#include "DirectXFramework.h"

CDirectXFramework::CDirectXFramework(void)
{
    // Init or NULL objects before use to avoid any undefined behavior
    m_bVsync        = false;
    m_pD3DObject    = 0;
    m_pD3DDevice    = 0;
    m_currTime      = 0;
    m_prevTime      = 0;
    m_bVideoPlaying = true;
    ZeroMemory(m_bKeyDown, sizeof(m_bKeyDown));//Matt K

    vertexBuffer = NULL;
    indexBuffer = NULL;
}

CDirectXFramework::~CDirectXFramework(void)
{
    // If Shutdown is not explicitly called correctly, call it when 
    // this class is destroyed or falls out of scope as an error check.
    Shutdown();
}

void CDirectXFramework::Init(HWND& hWnd, HINSTANCE& hInst, bool bWindowed)
{
    m_hWnd = hWnd;
    //////////////////////////////////////////////////////////////////////////
    // Direct3D Foundations - D3D Object, Present Parameters, and D3D Device
    //////////////////////////////////////////////////////////////////////////

    // Create the D3D Object
    m_pD3DObject = Direct3DCreate9(D3D_SDK_VERSION);

    // Find the width and height of window using hWnd and GetWindowRect()
    RECT rect;
    GetWindowRect(hWnd, &rect);
    int width = rect.right - rect.left;
    int height = rect.bottom - rect.top;

    // Set D3D Device presentation parameters before creating the device
    ZeroMemory(&D3Dpp, sizeof(D3Dpp));  // NULL the structure's memory//Matt K

    D3Dpp.hDeviceWindow                 = hWnd;                                     // Handle to the focus window
    D3Dpp.Windowed                      = bWindowed;                                // Windowed or Full-screen boolean
    D3Dpp.AutoDepthStencilFormat        = D3DFMT_D24S8;                             // Format of depth/stencil buffer, 24 bit depth, 8 bit stencil
    D3Dpp.EnableAutoDepthStencil        = TRUE;                                     // Enables Z-Buffer (Depth Buffer)
    D3Dpp.BackBufferCount               = 1;                                        // Change if need of > 1 is required at a later date
    D3Dpp.BackBufferFormat              = D3DFMT_X8R8G8B8;                          // Back-buffer format, 8 bits for each pixel
    D3Dpp.BackBufferHeight              = height;                                   // Make sure resolution is supported, use adapter modes
    D3Dpp.BackBufferWidth               = width;                                    // (Same as above)
    D3Dpp.SwapEffect                    = D3DSWAPEFFECT_DISCARD;                    // Discard back-buffer, must stay discard to support multi-sample
    D3Dpp.PresentationInterval          = m_bVsync ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_INTERVAL_IMMEDIATE; // Present back-buffer immediately, unless V-Sync is on                               
    D3Dpp.Flags                         = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;      // This flag should improve performance, if not set to NULL.
    D3Dpp.FullScreen_RefreshRateInHz    = bWindowed ? 0 : D3DPRESENT_RATE_DEFAULT;  // Full-screen refresh rate, use adapter modes or default
    D3Dpp.MultiSampleQuality            = 0;                                        // MSAA currently off, check documentation for support.
    D3Dpp.MultiSampleType               = D3DMULTISAMPLE_NONE;                      // MSAA currently off, check documentation for support.
    D3Dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
    D3Dpp.EnableAutoDepthStencil = TRUE;

    // Check device capabilities
    DWORD deviceBehaviorFlags = 0;
    m_pD3DObject->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &m_D3DCaps);

    // Determine vertex processing mode
    if(m_D3DCaps.DevCaps & D3DCREATE_HARDWARE_VERTEXPROCESSING)
    {
        // Hardware vertex processing supported? (Video Card)
        deviceBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING; 
    }
    else
    {
        // If not, use software (CPU)
        deviceBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; 
    }

    // If hardware vertex processing is on, check pure device support
    if(m_D3DCaps.DevCaps & D3DDEVCAPS_PUREDEVICE && deviceBehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING)
    {
        deviceBehaviorFlags |= D3DCREATE_PUREDEVICE;    
    }

    // Create the D3D Device with the present parameters and device flags above
    m_pD3DObject->CreateDevice(
        D3DADAPTER_DEFAULT,     // which adapter to use, set to primary
        D3DDEVTYPE_HAL,         // device type to use, set to hardware rasterization
        hWnd,                   // handle to the focus window
        deviceBehaviorFlags,    // behavior flags
        &D3Dpp,                 // presentation parameters
        &m_pD3DDevice);         // returned device pointer

    //*************************************************************************

    //////////////////////////////////////////////////////////////////////////
    // Create a Font Object
    //////////////////////////////////////////////////////////////////////////

    // Load a font for private use for this process
    AddFontResourceEx(L"Delicious-Roman.otf", FR_PRIVATE, 0); //Matt K

    // Load D3DXFont, each font style you want to support will need an ID3DXFont
    D3DXCreateFont(m_pD3DDevice, 30, 0, FW_BOLD, 0, false, DEFAULT_CHARSET,
                    OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH |
                    FF_DONTCARE, TEXT("Delicious-Roman"), &m_pD3DFont); //Matt K


    //////////////////////////////////////////////////////////////////////////
    // Create Sprite Object and Textures
    //////////////////////////////////////////////////////////////////////////

    // Create a sprite object, note you will only need one for all 2D sprites
    D3DXCreateSprite(m_pD3DDevice, &m_pD3DSprite); //Matt K


    // Create a texture, each different 2D sprite to display to the screen
    // will need a new texture object.  If drawing the same sprite texture
    // multiple times, just call that sprite's Draw() with different 
    // transformation values.
     D3DXCreateTextureFromFileEx(m_pD3DDevice, L"floor.bmp", 0, 0, 0, 0, 
                                D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT,
                                D3DX_DEFAULT, D3DCOLOR_XRGB(255, 0, 0), 
                                &m_imageInfo, 0, &m_pTexturefloor); //Matt K

      D3DXCreateTextureFromFileEx(m_pD3DDevice, L"ground2.bmp", 0, 0, 0, 0, 
                                D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT,
                                D3DX_DEFAULT, D3DCOLOR_XRGB(0, 255, 0), 
                                &m_imageInfo, 0, &m_pTextureground); //Matt K

      D3DXCreateTextureFromFileEx(m_pD3DDevice, L"seafloor.bmp", 0, 0, 0, 0, 
                                D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT,
                                D3DX_DEFAULT, D3DCOLOR_XRGB(0, 0, 255), 
                                &m_imageInfo, 0, &m_pTextureseafloor); //Matt K

      // Create the DI Object
    DirectInput8Create(hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&m_pDIObject, NULL);//Matt K
    // Initialize Keyboard
    m_pDIObject->CreateDevice(GUID_SysKeyboard, &m_pDIKeyboard, NULL);//Matt K

    // Initialize Mouse
    m_pDIObject->CreateDevice(GUID_SysMouse, &m_pDIMouse, NULL);//Matt K

      // Set up Keyboard
    m_pDIKeyboard->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); //Matt k
    m_pDIKeyboard->SetDataFormat(&c_dfDIKeyboard); // Matt k

    // Set up Mouse (c_dfDIMouse2 = 8 button mouse)
    m_pDIMouse->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); //Matt k
    m_pDIMouse->SetDataFormat(&c_dfDIMouse2); //Matt k

    //Cube shit
    rotation1 = 0.0f;
    rotation2 = 0.0f;
    rotation3 = 0.0f;

    D3DXVECTOR3 viewVectors[3] = {
        D3DXVECTOR3(0.0f, 0.0f, -11.0f),
        D3DXVECTOR3(0.0f, 0.0f, 0.0f),
        D3DXVECTOR3(0.0f, 1.0f, 0.0f)
    };
    setViewMatrix(viewVectors);

    // The default projection matrix is just fine.
    setProjectionMatrix();

    // And don't forget to disable lighting!
    m_pD3DDevice->SetRenderState(D3DRS_SPECULARENABLE, TRUE);
    m_pD3DDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(60, 60, 60));

    m_pD3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
    m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

    ZeroMemory(&light, sizeof(light));
    light.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
    light.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
    light.Specular = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
    light.Type = D3DLIGHT_POINT;
    light.Position = D3DXVECTOR3(30.0f, 10.0f, -10.0f);
    light.Range = 100.0f;
    light.Attenuation0 = 0.0f;
    light.Attenuation1 = 0.05f;
    light.Attenuation2 = 0.0f;

    m_pD3DDevice->SetLight(0, &light);
    m_pD3DDevice->LightEnable(0, TRUE);

    Vertex_UTx vertices[] = {
        // Front Face (1-2-3-4)
        { -1.0f, 1.0f, -1.0f, 0.0f, 0.0f },
        { 1.0f, 1.0f, -1.0f, 1.0f, 0.0f },
        { -1.0f, -1.0f, -1.0f, 0.0f, 1.0f },
        { 1.0f, -1.0f, -1.0f, 1.0f, 1.0f },

        // Right Face (2-6-4-8)
        { 1.0f, 1.0f, -1.0f, 0.0f, 0.0f },
        { 1.0f, 1.0f, 1.0f, 1.0f, 0.0f },
        { 1.0f, -1.0f, -1.0f, 0.0f, 1.0f },
        { 1.0f, -1.0f, 1.0f, 1.0f, 1.0f },

        // Top Face (5-6-1-2)
        { -1.0f, 1.0f, 1.0f, 0.0f, 0.0f },
        { 1.0f, 1.0f, 1.0f, 1.0f, 0.0f },
        { -1.0f, 1.0f, -1.0f, 0.0f, 1.0f },
        { 1.0f, 1.0f, -1.0f, 1.0f, 1.0f },

        // Back Face (6-5-8-7)
        { 1.0f, 1.0f, 1.0f, 0.0f, 0.0f },
        { -1.0f, 1.0f, 1.0f, 1.0f, 0.0f },
        { 1.0f, -1.0f, 1.0f, 0.0f, 1.0f },
        { -1.0f, -1.0f, 1.0f, 1.0f, 1.0f },

        // Left Face (5-1-7-3)
        { -1.0f, 1.0f, 1.0f, 0.0f, 0.0f },
        { -1.0f, 1.0f, -1.0f, 1.0f, 0.0f },
        { -1.0f, -1.0f, 1.0f, 0.0f, 1.0f },
        { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f },

        // Bottom Face (3-4-7-8)
        { -1.0f, -1.0f, -1.0f, 0.0f, 0.0f },
        { 1.0f, -1.0f, -1.0f, 1.0f, 0.0f },
        { -1.0f, -1.0f, 1.0f, 0.0f, 1.0f },
        { 1.0f, -1.0f, 1.0f, 1.0f, 1.0f }
    };

        // Create the vertex buffer.
    HRESULT result = m_pD3DDevice->CreateVertexBuffer(sizeof(vertices),
        D3DUSAGE_WRITEONLY, vertices[0].FORMAT, D3DPOOL_DEFAULT, &vertexBuffer, NULL);

    // Move vertices into the buffer.
    void* bufferMemory;
    result = vertexBuffer->Lock(0, sizeof(vertices), &bufferMemory, NULL);
    memcpy(bufferMemory, vertices, sizeof(vertices));
    vertexBuffer->Unlock();

    // Tell D3D what vertex format we're using, and to use our new buffer as the stream source.
    m_pD3DDevice->SetFVF(vertices[0].FORMAT);
    m_pD3DDevice->SetStreamSource(0, vertexBuffer, 0, vertices[0].STRIDE_SIZE);


    ZeroMemory(&lightMat, sizeof(lightMat));
    lightMat.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
    lightMat.Diffuse = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f);
    lightMat.Specular = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
    lightMat.Power = 30.0f;

    m_pD3DDevice->SetMaterial(&lightMat);
    m_pD3DDevice->SetSamplerState(D3DVERTEXTEXTURESAMPLER0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    m_pD3DDevice->SetSamplerState(D3DVERTEXTEXTURESAMPLER0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    m_pD3DDevice->SetSamplerState(D3DVERTEXTEXTURESAMPLER0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
    m_pD3DDevice->SetTexture(0, m_pTexturefloor);
}

void CDirectXFramework::Update()
{
    // buffer - Stores our keyboard device state
    char buffer[256]; //Matt k
    ZeroMemory(buffer, sizeof(buffer)); //Matt k

    // Get the input device state
    HRESULT hr; //Matt k
    hr = m_pDIKeyboard->GetDeviceState( sizeof(buffer), (LPVOID)&buffer ); //Matt k

    if(FAILED(hr)) //Matt k
    {
        hr = m_pDIKeyboard->Acquire(); //Matt k

        // Device has probably been lost if failed, if so keep trying to get it until it’s found.
        while( hr == DIERR_INPUTLOST) //Matt k
        {
            hr = m_pDIKeyboard->Acquire(); //Matt k
        }

        // If we failed for some other reason
        if(FAILED(hr)) //Matt k
            return; //Matt k

        // Read the device state again
        m_pDIKeyboard->GetDeviceState(sizeof(buffer), buffer); //Matt k


    }

    // Stores our mouse state for an 8 button mouse.
    DIMOUSESTATE2 mouseState; //Matt k
    ZeroMemory(&mouseState, sizeof(mouseState)); //Matt k

    // Get the input device state
    hr = m_pDIMouse->GetDeviceState( sizeof(DIMOUSESTATE2), &mouseState ); //Matt k
    if(FAILED(hr)) //Matt k
    {
        hr = m_pDIMouse->Acquire(); //Matt k

        // Device has probably been lost if failed, if so keep trying to get it until it’s found.
        while( hr == DIERR_INPUTLOST) //Matt k
        {
            hr = m_pDIMouse->Acquire(); //Matt k
        }

        // If we failed for some other reason
        if(FAILED(hr)) //Matt k
            return; //Matt k
        // Read the device state again
        m_pDIMouse->GetDeviceState(sizeof(DIMOUSESTATE2), &mouseState); //Matt k
    }
}

void CDirectXFramework::Render()
{
    //y rotation set
    rotation2 += D3DX_PI / 9000.0f; //Professor.... my PC runs this program at almost 8K FPS.... this 7K rot divisor
                                    //Makes the cube rotate at a decent speed ON MY MACHINE.  I recommend between 90 and 360 on slower machines
                                    //Larger numbers rotate slower

    // If the device was not created successfully, return
    if(!m_pD3DDevice)
        return;
    //*************************************************************************

    //////////////////////////////////////////////////////////////////////////
    // All draw calls between swap chain's functions, and pre-render and post- 
    // render functions (Clear and Present, BeginScene and EndScene)
    //////////////////////////////////////////////////////////////////////////

    // Clear the back buffer, call BeginScene()
    m_pD3DDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f), 1.0f, 0);
    m_pD3DDevice->BeginScene(); //Matt K

            //////////////////////////////////////////////////////////////////////////
            // Draw 3D Objects (for future labs - not used in Week #1)
            //////////////////////////////////////////////////////////////////////////
            // Then, we create Rotation matrices for each.
            D3DXMATRIXA16 baseMatrix, worldMatrix, rotationMatrix1, rotationMatrix2, rotationMatrix3, translateMatrix;
            m_pD3DDevice->GetTransform(D3DTS_WORLD, &baseMatrix);

            //Cube 1
            worldMatrix = baseMatrix * *D3DXMatrixRotationX(&rotationMatrix1, rotation1) *
                *D3DXMatrixRotationY(&rotationMatrix2, rotation2) *
                *D3DXMatrixTranslation(&translateMatrix, 4.0f, 0.0f, 0.0f);
            m_pD3DDevice->SetTransform(D3DTS_WORLD, &worldMatrix);
            renderCube();

            // #2
            worldMatrix = baseMatrix * *D3DXMatrixRotationX(&rotationMatrix1, rotation1) *
                *D3DXMatrixRotationY(&rotationMatrix2, -rotation2) *
                *D3DXMatrixTranslation(&translateMatrix, -4.0f, 0.0f, 0.0f);
            m_pD3DDevice->SetTransform(D3DTS_WORLD, &worldMatrix);
            renderCube();

            m_pD3DDevice->SetTransform(D3DTS_WORLD, &baseMatrix);
            /////////
            // Draw 2D sprites
            //////////////////////////////////////////////////////////////////////////
            // Note: You should only be calling the sprite object's begin and end once, 
            // with all draw calls of sprites between them

            // Call Sprite's Begin to start rendering 2D sprite objects
            if (SUCCEEDED(m_pD3DSprite->Begin(D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_DEPTH_FRONTTOBACK))) //Matt K
            {
            // End drawing 2D sprites
            m_pD3DSprite->End();
            }
            //////////////////////////////////////////////////////////////////////////
            // Draw Text
            //////////////////////////////////////////////////////////////////////////

            // Calculate RECT structure for text drawing placement, using whole screen
            RECT rect;
            GetWindowRect(m_hWnd, &rect);

            rect.right = rect.right - rect.left;
            rect.bottom = rect.bottom - rect.top;
            rect.top = 0;
            rect.left = 0;

            // Draw Text, using DT_TOP, DT_RIGHT for placement in the top right of the
            // screen.  DT_NOCLIP can improve speed of text rendering, but allows text
            // to be drawn outside of the rect specified to draw text in.
            // Draw FPS
            wchar_t buffer[64];
            swprintf_s(buffer, 64, L"FPS: %d", m_FPS);
            m_pD3DFont->DrawText(0, buffer, -1, &rect, DT_TOP | DT_NOCLIP, D3DCOLOR_ARGB(255, 0, 0, 0));

            // EndScene, and Present the back buffer to the display buffer
    m_pD3DDevice->EndScene(); //Matt K
    m_pD3DDevice->Present(0, 0, 0, 0); //Matt K

    // Calculate Frames per Second
    m_currTime = (float)timeGetTime();
    static int fpsCounter = 0;
    if(m_currTime - m_prevTime >= 1000.0f)
    {
    m_prevTime = m_currTime;
    m_FPS = fpsCounter;
    fpsCounter = 0;  
    }
    else
    {
    ++fpsCounter;
    }
}

void CDirectXFramework::Shutdown()
{
    //*************************************************************************
    // Release COM objects in the opposite order they were created in

    // Texture
    SAFE_RELEASE(m_pTexturefloor); //Matt K
    SAFE_RELEASE(m_pTextureground); //Matt K
    SAFE_RELEASE(m_pTextureseafloor); //Matt K

    // Sprite
    SAFE_RELEASE(m_pD3DSprite); //Matt K

    // Font
    SAFE_RELEASE(m_pD3DFont); //Matt K

    // 3DDevice
    SAFE_RELEASE(m_pD3DDevice); //Matt K

    // 3DObject
    SAFE_RELEASE(m_pD3DObject); //Matt K

    if (vertexBuffer != NULL) { vertexBuffer->Release(); vertexBuffer = NULL; }

    //*************************************************************************
}

// -------------------------------------------------
/* public setViewMatrix */
// Sets the view matrix.
// -------------------------------------------------
void CDirectXFramework::setViewMatrix(const D3DXVECTOR3& eye, const D3DXVECTOR3& lookAt, const D3DXVECTOR3& up) {
    D3DXMATRIXA16 viewMatrix;
    D3DXMatrixLookAtLH(&viewMatrix, &eye, &lookAt, &up);
    m_pD3DDevice->SetTransform(D3DTS_VIEW, &viewMatrix);
}

// -------------------------------------------------
/* public setProjectionMatrix */
// Sets the projection matrix.
// -------------------------------------------------
void CDirectXFramework::setProjectionMatrix(float fov, float aspectRatio, float zClose, float zFar) {
    D3DXMATRIXA16 projectionMatrix;
    D3DXMatrixPerspectiveFovLH(&projectionMatrix, fov, aspectRatio, zClose, zFar);
    m_pD3DDevice->SetTransform(D3DTS_PROJECTION, &projectionMatrix);
}

// -------------------------------------------------
/* renderCube */
// This will draw a cube at the current world location.
// -------------------------------------------------
void CDirectXFramework::renderCube() {
    for (int i = 0; i < 6; i++)
        m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, i * 4, 2);
}

Any help is appreciated.


Solution

  • The problem is that you do not change your texture.
    m_pD3DDevice->SetTexture(0, m_pTexturefloor);
    Now the texture being used is the floor texture. If you want one cube to use this and the other cube use the other one. Change the current texture between your render calls. I guess what you want is something like this:

    ...
    m_pD3DDevice->SetTexture(0, m_pTexturefloor);
    worldMatrix = baseMatrix * *D3DXMatrixRotationX(&rotationMatrix1, rotation1) *
    *D3DXMatrixRotationY(&rotationMatrix2, rotation2) *
    *D3DXMatrixTranslation(&translateMatrix, 4.0f, 0.0f, 0.0f);
    m_pD3DDevice->SetTransform(D3DTS_WORLD, &worldMatrix);
    renderCube();
    
    // #2
    m_pD3DDevice->SetTexture(0, m_pTextureground);
    worldMatrix = baseMatrix * *D3DXMatrixRotationX(&rotationMatrix1, rotation1) *
    *D3DXMatrixRotationY(&rotationMatrix2, -rotation2) *
    *D3DXMatrixTranslation(&translateMatrix, -4.0f, 0.0f, 0.0f);
    m_pD3DDevice->SetTransform(D3DTS_WORLD, &worldMatrix);
    renderCube();
    ....