2014-12-09 7 views
0

저는 온라인에서 삼각 관계를 그리는 데 도움이되는 Directx 튜토리얼을 따라 왔으며 사각형으로 바꾸는 방법을 찾아 내려고했습니다. 추가 정점을 추가하여 사실상 4 개의 정점이있는 두 개의 삼각형을 결합 할 수 있다는 것을 이해합니다. 이제이 모든 작업을 수행 할 때 출력물에는 삼각형 만 표시됩니다. 오류가 어디에서 발생하는지 궁금합니다. 현재 내 코드는 다음과 같습니다.Direct3D 및 C++을 사용하여 사각형을 만드는 방법은 무엇입니까?

#include <Windows.h> 
#include <windowsx.h> 
#include <d3d9.h> 

#define SCREEN_WIDTH 800 
#define SCREEN_HEIGHT 600 

#pragma comment (lib, "d3d9.lib") 

LPDIRECT3D9 d3d; 

LPDIRECT3DDEVICE9 d3ddev; 

LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL; 

void initD3D(HWND hWnd); 

void render_frame(void); 

void cleanD3D(void); 

void init_graphics(void); 


struct CUSTOMVERTEX { FLOAT X, Y, Z, RHW; DWORD COLOR; }; 
#define CUSTOMFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE) 

LRESULT CALLBACK WindowProc(HWND hWnd, 
    UINT message, 
    WPARAM wParam, 
    LPARAM lParam); 

int WINAPI WinMain(HINSTANCE hInstance, 
    HINSTANCE hPrevInstance, 
    LPSTR lpCmdLine, 
    int nCmdShow) 
{ 
    HWND hWnd; 

    WNDCLASSEX wc; 

    ZeroMemory(&wc, sizeof(WNDCLASSEX)); 

    wc.cbSize = sizeof(WNDCLASSEX); 

    wc.style = CS_HREDRAW | CS_VREDRAW; 

    wc.lpfnWndProc = WindowProc; 

    wc.hInstance = hInstance; 

    wc.hCursor = LoadCursor(NULL, IDC_ARROW); 

    wc.lpszClassName = L"WindowClass1"; 

    RegisterClassEx(&wc); 

    hWnd = CreateWindowEx(NULL, 
     L"WindowClass1", 
     L"Pretty Triangle", 
     WS_OVERLAPPEDWINDOW, 
     0, 
     0, 
     SCREEN_WIDTH, 
     SCREEN_HEIGHT, 
     NULL, 
     NULL, 
     hInstance, 
     NULL); 

    ShowWindow(hWnd, nCmdShow); 

    initD3D(hWnd); 

    MSG msg; 

    while (TRUE) 
    { 
     while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
     { 
      TranslateMessage(&msg); 

      DispatchMessage(&msg); 
     } 

     if (msg.message == WM_QUIT) 
      break; 

     render_frame(); 
    } 

    cleanD3D(); 

    return msg.wParam; 
} 

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    switch (message) 
    { 
    case_WM_DESTROY: 
    { 
     PostQuitMessage(0); 
     return 0; 
    } 
     break; 
    } 
    return DefWindowProc(hWnd, message, wParam, lParam); 
} 

void initD3D(HWND hWnd) 
{ 
    d3d = Direct3DCreate9(D3D_SDK_VERSION); 

    D3DPRESENT_PARAMETERS d3dpp; 

    ZeroMemory(&d3dpp, sizeof(d3dpp)); 

    d3dpp.Windowed = TRUE; 

    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; 

    d3dpp.hDeviceWindow = hWnd; 

    d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; 

    d3dpp.BackBufferWidth = SCREEN_WIDTH; 

    d3dpp.BackBufferHeight = SCREEN_HEIGHT; 

    d3d->CreateDevice(D3DADAPTER_DEFAULT, 
     D3DDEVTYPE_HAL, 
     hWnd, 
     D3DCREATE_SOFTWARE_VERTEXPROCESSING, 
     &d3dpp, 
     &d3ddev); 

    init_graphics(); 
} 

void render_frame(void) 
{ 
    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); 

    d3ddev->BeginScene(); 

    d3ddev->SetFVF(CUSTOMFVF); 

    d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); 

    d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); 

    d3ddev->EndScene(); 

    d3ddev->Present(NULL, NULL, NULL, NULL); 
} 

void cleanD3D(void) 
{ 
    v_buffer->Release(); 
    d3ddev->Release(); 
    d3d->Release(); 
} 

void init_graphics(void) 
{ 
    CUSTOMVERTEX vertices[] = 
    { 
     { 100.0f, 100.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(255, 0, 0), }, 
     { 132.0f, 100.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(0, 255, 0), }, 
     { 100.0f, 132.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(0, 0, 255), }, 
     { 100.0f, 132.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(0, 0, 255), }, 
    }; 

    d3ddev->CreateVertexBuffer(4 * sizeof(CUSTOMVERTEX), 
     0, 
     CUSTOMFVF, 
     D3DPOOL_MANAGED, 
     &v_buffer, 
     NULL); 

    VOID*pVoid; 

    v_buffer->Lock(0, 0, (void**)&pVoid, 0); 
    memcpy(pVoid, vertices, sizeof(vertices)); 
    v_buffer->Unlock(); 
} 

모든 도움을 주시면 감사하겠습니다.

답변

0

저는 Direct3D에서 매우 녹슬었지만 DrawPrimative 메서드를 사용하고 있기 때문에 정사각형을 그리는 데 충분한 정점이 없다고 생각합니다. 이 방법은 배열에 2 개의 삼각형을 사용하여 사각형을 그리기위한 중복 된 정점이 배열에 4 개가 아닌 6 개의 정점이 정의되어 있어야 함을 의미합니다. DrawIndexedPrimitive을 호출하도록 코드를 변경하면 중복 정점을 정의 할 필요가 없으며 기존 정점 배열이 작동해야합니다. 여기

DrawIndexedPrimitive(D3DPT_TRIANGLELIST, // PrimitiveType 
       0,     // BaseVertexIndex 
       0,     // MinIndex 
       4,     // NumVertices 
       0,     // StartIndex 
       2);    // PrimitiveCount 

또한 인덱스 Veritces을 설명 Direct3D를에서 사각형 그리기에 좋은 기사입니다 : http://msdn.microsoft.com/en-us/library/windows/desktop/bb147325(v=vs.85).aspx

+0

그는 그림을 그리기 위해 D3DPT_TRIANGLESTRIP을 사용하므로 두 번째 삼각형을 그리기 전에 네 번째 꼭지점을 둘 다 결합합니다. 이것은 효과가있다. – Gnietschow

+0

@Gnietschow, 감사합니다. 당신 말이 맞아, 그는 내 대답이이 사건에 적용되지 않도록 D3DPT_TRIANGLESTRIP을 사용하고 있습니다. – Adrian

1

귀하의 마지막 정점은 세 번째와 같은 위치에있는, 그래서 두 번째 삼각형은 라인이 아니라 명백한. 난 당신의 정점 데이터에 오타가 있다고 생각하고 쓰려고했다.

{ 132.0f, 132.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(0, 0, 255), } 

을 쿼드 완료를위한 마지막 버텍스로 생각한다.

+0

와아, 내 잘못을 너무 과식했습니다. 도와 줘서 고마워요. – Arsenal11