Рендеринг отдельных текстур с использованием DirectX

Я уверен, что где-то есть простой ответ на этот вопрос. В настоящее время у меня есть программа, которая правильно отображает .png изображение в виде текстуры поверх прямоугольника вершин. Это все работает нормально и отображается правильно.

У меня вопрос, как мне сделать рендеринг второй текстуры на экране, используя отдельное изображение? Самый простой / оптимальный способ (я знаю, что они, вероятно, разные!) Второе изображение, которое я хочу добавить, будет служить фоновым изображением.
Я попытался продублировать структуру CUSTOMVERTEX, буфер вершин, отдельные данные вершин, матрицу перевода, настройки этапа текстуры и т. Д. Для второй текстуры, которую я хочу использовать, но я могу только успешно отрисовать одну на экране, что-то перезаписывается. К сожалению, я все еще учусь текстурированию и мне не хватает правильного подхода.
Требуется ли совершенно отдельная настройка вершины?

Код ниже отражает мой рабочий код, отображающий изображение в виде текстуры, наложенной на прямоугольник вершин. Что я должен добавить в настройку & сделать отдельную текстуру для моего фона?

    //////////////////////////////////////////////////////
// I N V A D E R S
//////////////////////////////////////////////////////#include <Windows.h>    // Windows library (for window functions, menus, dialog boxes, etc)
#include <d3dx9.h>      // Direct 3D library (for all Direct 3D functions).//-----START-----DEFINE GLOBAL ELEMENTS----------//
LPDIRECT3D9             D3D_Object           = NULL; // Name of the Direct3D Obeject. Used to create the D3DDevice
LPDIRECT3DDEVICE9       D3D_Device           = NULL; // Name of the rendering device
LPDIRECT3DVERTEXBUFFER9 g_pVertexBuffer      = NULL; // Buffer to hold vertices for the rectangle
LPDIRECT3DTEXTURE9      D3D_Tex_Background   = NULL; // The texture for the background
LPDIRECT3DTEXTURE9      D3D_Tex_Invader      = NULL; // The texture for the invader

float g_InvaderX = -50, g_InvaderY = 0, g_InvaderZ = 0;  // starting cooordinates of object

// A structure for our custom vertex type, containing the vertex & texture coordinates
struct CUSTOMVERTEX
{
D3DXVECTOR3 position;   // Vertex coordinates
FLOAT u, v;             // Texture coordinates
};

// The structure of a vertex in our vertex buffer...
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_TEX1)  // it will contain xyz coordinates & a texture//////////////////////////////////////////////////////
// Setup Direct3D
//////////////////////////////////////////////////////
HRESULT SetupD3D(HWND hWnd)
{
// Create the D3D object.
if (NULL == (D3D_Object = Direct3DCreate9(D3D_SDK_VERSION))) return E_FAIL;

// Set up the structure used to create the D3D Device
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;                      // application will be windowed
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;   // back to front buffer behavior - DISCARD = random data used for error checking
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;    // back buffer format - UNKNOWN = use current display resolution to retain consistency
d3dpp.EnableAutoDepthStencil = TRUE;        // D3D device to create and manage depth and stencil buffer automatically
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;  // format of the surfaces which hold the depth & stencil buffers - D16 = 16Bit colours// Create the D3D Device - on successful completion return a pointer to the created device D3D_Device
if (FAILED(D3D_Object->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &D3D_Device)))
{
return E_FAIL;      // return error if D3D Device creation has failed
}

return S_OK;
}//////////////////////////////////////////////////////
// DIRECT3D CLEANUP
//
// Release (delete) all the resources used by this program.
// Only release things if they are valid (i.e. have a valid pointer).
// If not, the program will crash at this point.
//////////////////////////////////////////////////////
void CleanUp()
{
// Delete the textures
if (D3D_Tex_Background != NULL)  D3D_Tex_Background -> Release();
if (D3D_Tex_Invader != NULL)     D3D_Tex_Invader -> Release();

// Release other D3D Device resources
if (g_pVertexBuffer != NULL) g_pVertexBuffer -> Release();
if (D3D_Device != NULL)      D3D_Device -> Release();
if (D3D_Object != NULL)      D3D_Object  -> Release();
}//////////////////////////////////////////////////////
// Setup the camera
//////////////////////////////////////////////////////
void SetupMatrices()
{
// Setup View Matrix
D3DXVECTOR3 vCamera(5.0f, 5.0f, -100.0f);
D3DXVECTOR3 vLookat(5.0f, 5.0f, 0.0f);
D3DXVECTOR3 vUpVector(0.0f, 1.0f, 0.0f);
D3DXMATRIX matrixView;
D3DXMatrixLookAtLH(&matrixView, &vCamera, &vLookat, &vUpVector);
D3D_Device -> SetTransform(D3DTS_VIEW, &matrixView);

// Setup Projection Matrix
// This transforms 2D geometry into a 3D space
D3DXMATRIX matrixProjection;
D3DXMatrixPerspectiveFovLH(&matrixProjection, D3DX_PI/4, 1.0f, 1.0f, 800.0f);
D3D_Device -> SetTransform(D3DTS_PROJECTION, &matrixProjection);
}//////////////////////////////////////////////////////
// SETUP GEOMETRY -
// Define a square using the required verticies
//////////////////////////////////////////////////////
HRESULT SetupGeometry()
{
// Calculate the number of vertices required for the desired graphic
int Vertices = 2 * 3;   // Six vertices required for the 2 triangles which make up the square.

// Calculate the size in bytes of the buffer which will hold the vertex information
// based on the number of verticies required and the elements contained within the CUSTOMVERTEX structure
int BufferSize = Vertices * sizeof(CUSTOMVERTEX);

// Create the vertex buffer which will store the vertex data to render
// (buffer size, special instructions, vertex buffer format, target memory location for buffer,pointer to vertex buffer, future use only)
if (FAILED(D3D_Device -> CreateVertexBuffer(BufferSize, 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVertexBuffer, NULL)))
{
return E_FAIL; // if the vertex buffer could not be created.
}

//////////////////////////////////////////////////////
// Fill vertex buffer with required vertex & texture info
//////////////////////////////////////////////////////
CUSTOMVERTEX *pVertices;            // Create a pointer to the first vertex in the buffer.
if (FAILED(g_pVertexBuffer -> Lock(0, 0, (void**)&pVertices, 0)))  // lock the buffer to prevent interference, allow access using the
{                                                                  // &pVerticies pointer

return E_FAIL;  // if the pointer to the vertex buffer could not be established.
}

// Fill the vertex buffers with data concerning both vertex and texture locations

// Triangle 1
// Vertex 0
pVertices[0].position.x = 0;    // Vertex coordinates
pVertices[0].position.y = 0;
pVertices[0].position.z = 0;
pVertices[0].u        = 0;      // texture coordinates
pVertices[0].v        = 1;

// Vertex 1
pVertices[1].position.x = 0;
pVertices[1].position.y = 10;
pVertices[1].position.z = 0;
pVertices[1].u        = 0;
pVertices[1].v        = 0;

// Vertex 2
pVertices[2].position.x = 10;
pVertices[2].position.y = 0;
pVertices[2].position.z = 0;
pVertices[2].u        = 1;
pVertices[2].v        = 1;

// Triangle 2
// Vertex 3
pVertices[3].position.x = 10;
pVertices[3].position.y = 0;
pVertices[3].position.z = 0;
pVertices[3].u        = 1;
pVertices[3].v        = 1;

// Vertex 4
pVertices[4].position.x = 0;
pVertices[4].position.y = 10;
pVertices[4].position.z = 0;
pVertices[4].u        = 0;
pVertices[4].v        = 0;

// Vertex 5
pVertices[5].position.x = 10;
pVertices[5].position.y = 10;
pVertices[5].position.z = 0;
pVertices[5].u        = 1;
pVertices[5].v        = 0;

// Unlock the vertex buffer...
g_pVertexBuffer -> Unlock();

return S_OK;
}//////////////////////////////////////////////////////
// Load the textures for the invaders and background
//////////////////////////////////////////////////////
void LoadTextures()
{
//D3DXCreateTextureFromFile(D3D_Device,         // Direct3D Device name
//                        "background.jpg",     // Source file in program folder
//                        &D3D_Tex_Background);     // address of target texture objectD3DXCreateTextureFromFile(D3D_Device,
"invader300x300.png",
&D3D_Tex_Invader);
}//////////////////////////////////////////////////////
// Render
//////////////////////////////////////////////////////
void Render()
{
// Clearing the current frame & Z buffers
// (rectangles to clear, rectangle coords, clear current buffer & Z buffer, RGB background colour of screen, initial z buffer value, initial
// stencil buffer value)
D3D_Device -> Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

// Once current frame has been cleared, begin drawing new frame
// lock is created at this point to prevent anything else drawing on the frame
if (SUCCEEDED(D3D_Device -> BeginScene()))
{

// Construct a translation matrix to move the Invader
D3DXMATRIX TranslateMatrix;
D3DXMatrixTranslation(&TranslateMatrix, g_InvaderX, g_InvaderY, g_InvaderZ);
D3D_Device -> SetTransform(D3DTS_WORLD, &TranslateMatrix);// Render the contents of the vertex buffer.
D3D_Device -> SetStreamSource(0, g_pVertexBuffer, 0, sizeof(CUSTOMVERTEX));
D3D_Device -> SetFVF(D3DFVF_CUSTOMVERTEX);
D3D_Device -> DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);// Select the invader texture, and initialise the texture stage state...
D3D_Device -> SetTexture(0,                 // the texture stage being set
D3D_Tex_Invader);  // the object associated with the texture image
D3D_Device -> SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
D3D_Device -> SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);// Update the invader's x co-ordinate.
//if (g_RectX <=14.5)
g_InvaderX += 0.5f;

// Drawing of the scene has finished
D3D_Device -> EndScene();
}

// Present the back frame buffer contents to the screen (front frame buffer swaped with back fram buffer)
D3D_Device -> Present(NULL, NULL, NULL, NULL);
}//////////////////////////////////////////////////////
// Windows Message Handling
//////////////////////////////////////////////////////
LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
}

return DefWindowProc(hWnd, msg, wParam, lParam);
}//////////////////////////////////////////////////////
// Create the application window
//////////////////////////////////////////////////////
int WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, int)
{
// Register the window class
WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
"Invaders", NULL};
RegisterClassEx(&wc);

// Create the application window
HWND hWnd = CreateWindow( "Invaders",           // Window class's name
"I N V A D E R S",    // Title bar text
WS_OVERLAPPEDWINDOW,  // The window style
100,                  // window horizontal position
500,                  // window vertical position
800,                  // window width
800,                  // window height
GetDesktopWindow(),   // the parent window's module
NULL,                 // the window's menu handle
wc.hInstance,         // the instance handle
NULL);// Initialize Direct3D
if (SUCCEEDED(SetupD3D(hWnd)))
{
// Create the scene geometry
if (SUCCEEDED(SetupGeometry()))
{
// Load the required texture(s) from files into memeory
LoadTextures();

// Display the window onscreen
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);

// Initialse the Viewpoint / Camera based on defined settings
SetupMatrices();

// Enter message loop to handle any messages MS Windows sends to the application
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
Render();
}
}
}

CleanUp(); // release resources used ( delete all dynamically allocated objects)

UnregisterClass("Server", wc.hInstance);

return 0;
}   // end WinMain

0

Решение

Похоже, вам нужно более глубокое понимание программирования с DirectX. Попробуйте сделать несколько уроков, таких как этот или же этот, они тихо полезны.

На ваш конкретный вопрос: кажется, что вы хотите сделать 2D-игру с изображениями, которые нарисованы на экране. Поэтому проще использовать D3DFVF_XYZRHW (доктор), потому что вы можете визуализировать нетрансформированные вершины с помощью 2D-координат. Для рендеринга фона сначала нарисуйте полноэкранный квадратор с приложенным изображением. После этого вы визуализируете свои корабли перед этим. Если ваш корабль не нарисован, Мэйби Z-Buffering определил, что ваш фон перед ним и обрезал его. Для 2D-игр либо отключите ZBuffering, либо установите глубину в вершинах.

2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector