gpt4 book ai didi

c++ - Direct X 9 - 三角形没有出现

转载 作者:行者123 更新时间:2023-12-04 05:24:12 28 4
gpt4 key购买 nike

目前,在开始编写程序之前,我正在用 DirectX 做一些测试用例。而现在,我已经弄乱了下面的代码一天左右。我在互联网上查看类似问题时修改了代码。但最终,它也没有按照我想要的方式工作。有人能告诉我我到底做错了什么吗?也许其他人可以解决这个问题。

// TetrisClone.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "TetrisClone.h"
#include <d3d9.h>
#include <d3dx9.h>


#define MAX_LOADSTRING 100
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)

//for testing purposes
struct CUSTOMVERTEX
{
FLOAT x, y, z; //position
DWORD color; //Color
};

// global declarations for Direct3d
LPDIRECT3D9 d3d; // the pointer to our Direct3D interface
LPDIRECT3DDEVICE9 d3ddev; // the pointer to the device class
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;

// function prototypes
void initD3D(HWND hWnd); // sets up and initializes Direct3D
void render_frame(void); // renders a single frame
void cleanD3D(void); // closes Direct3D and releases memory
void init_graphics(void); // 3D declarations

// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name

// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);

// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;

// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_TETRISCLONE, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);

// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}

hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TETRISCLONE));

// Main message loop:
while(TRUE)
{
// Check to see if any messages are waiting in the queue
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// Translate the message and dispatch it to WindowProc()
TranslateMessage(&msg);
DispatchMessage(&msg);
}

// If the message is WM_QUIT, exit the while loop
if(msg.message == WM_QUIT)
break;

render_frame();
}

cleanD3D();
return (int) msg.wParam;
}



//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage are only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TETRISCLONE));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_GRAYTEXT);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_TETRISCLONE);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

return RegisterClassEx(&wcex);
}

//
// FUNCTION: InitInstance(HINSTANCE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;

hInst = hInstance; // Store instance handle in our global variable

hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, hInstance, NULL);

if (!hWnd)
{
return FALSE;
}

ShowWindow(hWnd, nCmdShow);

// set up and initialize Direct3D
initD3D(hWnd);

UpdateWindow(hWnd);

return TRUE;
}

//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;

switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;

case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}

/***
Direct3d functions

***/

// this function initializes and prepares Direct3D for use
void initD3D(HWND hWnd)
{
d3d = Direct3DCreate9(D3D_SDK_VERSION); // create the Direct3D interface

D3DPRESENT_PARAMETERS d3dpp; // create a struct to hold various device information

ZeroMemory(&d3dpp, sizeof(d3dpp)); // clear out the struct for use
d3dpp.Windowed = TRUE; // program windowed, not fullscreen
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // discard old frames
d3dpp.hDeviceWindow = hWnd; // set the window to be used by Direct3D

// create a device class using this information and information from the d3dpp stuct
d3d->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&d3ddev);

init_graphics();
}

// this is the function used to render a single frame
void render_frame(void)
{

// clear the window to a deep blue
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);

d3ddev->BeginScene(); // begins the 3D scene

//set FVF
d3ddev->SetFVF(D3DFVF_CUSTOMVERTEX);

//setting stream source
d3ddev->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));

// do 3D rendering on the back buffer here

//drawing triangle
d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);

d3ddev->EndScene(); // ends the 3D scene

d3ddev->Present(NULL, NULL, NULL, NULL); // displays the created frame
}

// this is the function that puts the 3D models into video RAM
void init_graphics(void)
{
// create the vertices using the CUSTOMVERTEX struct
CUSTOMVERTEX vertices[] =
{
{ 400.0f, 62.5f, 0.0f, D3DCOLOR_XRGB(0, 0, 255), },
{ 650.0f, 500.0f, 0.0f, D3DCOLOR_XRGB(0, 255, 0), },
{ 150.0f, 500.0f, 0.0f, D3DCOLOR_XRGB(255, 0, 0), },
};

// create a vertex buffer interface called v_buffer
d3ddev->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX),
0,
D3DFVF_CUSTOMVERTEX,
D3DPOOL_MANAGED,
&g_pVB,
NULL);

VOID* pVoid; // a void pointer

// lock v_buffer and load the vertices into it
g_pVB->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, vertices, sizeof(vertices));
g_pVB->Unlock();
}

// this is the function that cleans up Direct3D and COM
void cleanD3D(void)
{
g_pVB->Release();
d3ddev->Release(); // close and release the 3D device
d3d->Release(); // close and release Direct3D
}

最佳答案

由于您没有设置相机并且没有对您的顶点进行任何变换,因此,您应该将您的顶点设置在长方体的范围内(透视投影变换后),即

-1 << 1 << 1
-1 << y << 1
0 << z << 1

以下更改将使您的三角形可见。
  CUSTOMVERTEX vertices[] =
{
{ 0.0f, 0.0, 0.0f, D3DCOLOR_XRGB(0, 0, 255), },
{ 0.0f, 1.0f, 0.0f, D3DCOLOR_XRGB(0, 255, 0), },
{ 1.0f, 0.0f, 0.0f, D3DCOLOR_XRGB(255, 0, 0), },
};

有很多原因会导致 Direct3D 程序中的几何体/模型不可见,我在下面列出了一些。
  • 禁用/启用照明

  • 通常,我们需要在渲染过程中启用照明,但是如果您使用 LT(Lit and Transformed) 顶点格式,这意味着您定义了顶点的颜色并为其使用屏幕坐标,这告诉 Direct3D 引擎:“嘿,做不光照和变换我的顶点,我会做的!”,在你的代码中你没有使用 LT 格式,这意味着你应该变换和光照你的顶点,但你没有任何光照设置,所以你会得到一个黑色三角形,事实上,你什么也没得到,因为顶点坐标不在视野范围内。
  • 顶点坐标

  • 我们通常在物体空间指定顶点坐标,然后将它们变换到世界空间-> View 空间->投影空间->屏幕空间,在你上面的代码中,你没有做任何传递,但是你的顶点坐标太大了,透视变换后超出长方体范围,范围为-1 << x << 1, -1 << y << 1, 0 << z << 1。
  • 背面剔除模式

  • 这也是一个非常重要的考虑因素,默认情况下,Direct3D 使用将剔除所有逆时针定义的面,请参阅此线程 Odd behaviour when trying to create triangle using TriangleStrip Topologu详情。
  • 相机设置

  • 首先,确保您的相机面向您正在绘制的内容,然后设置正确的距离。您为顶点使用大坐标,因此,您应该将相机设置为远离您正在渲染的几何体,否则您将什么也看不到。
  • 你什么都没画

  • 这个项目看起来有点搞笑,但确实发生了,当我们要测试渲染是否有效时,我们总是在渲染函数中注释掉一些代码并绘制其他东西,我们也可以测试程序是否在没有任何绘图的情况下工作代码,然后我们忘记了取消注释绘图代码,这导致屏幕上没有任何显示。刚开始学习D3D的时候就遇到过这个问题。

    关于c++ - Direct X 9 - 三角形没有出现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13392021/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com