当前位置: 动力学知识库 > 问答 > 编程问答 >

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 [[email protected]] or [[email protected]]

// 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.

网友答案:

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();
....
网友答案:

You're calling SetTexture only once, during setup. You need to call it once before you draw the first object and then again, with a different texture, when you draw the second.

网友答案:

Looks like the DirectXFramework from DeVry University. So I would say that you should have passed delta time into your Update function, do rotations there and multiply by delta time. Delta time can be found by using queries for the performance timer in the main message loop. Doesn't answer this but is better than the whole /9000 that would have to be altered for different hardware configurations.

分享给朋友:
您可能感兴趣的文章:
随机阅读: