求助,Direct 3D 里 为什么我用了坐标转换 显示出来的图形却仍然是以屏幕为坐标轴绘制的?

estein 2009-04-06 07:02:58
相关代码如下,望高手给予解答,感激不已。
my_vertex g_vertices[]={
{0.0f,300.0f,0.0f,0xFFFFFFFF},// x,y,z,COLOR
{0.0f,100.0f,0.0f,0xFFFFFFFF},
{100.0f,100.0f,0.0f,0xFFFFFFFF},


……
// 建立一个观察矩阵
D3DXVECTOR3 vEyePt(0.0f,0.0f,-1.0f);
D3DXVECTOR3 vLookatPt(0.0f,0.0f,0.0f);
D3DXVECTOR3 vUpVec(0.0f,1.0f,0.0f);
D3DXMATRIX matView;
D3DXMatrixLookAtLH(&matView,&vEyePt,&vLookatPt,&vUpVec);
p_D3DDevice->SetTransform(D3DTS_VIEW,&matView);

// 建立一个透视投影矩阵
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,1.0f,1.0f,100.0f);
p_D3DDevice->SetTransform(D3DTS_PROJECTION,&matProj);

// 设置视区
RECT rect;
GetClientRect(hWnd,&rect);
D3DVIEWPORT9 vp;
vp.X = 0;
vp.Y = 0;
vp.Width = rect.right;
vp.Height = rect.bottom;
vp.MinZ = 0.0f;
vp.MaxZ = 1.0f;
p_D3DDevice->SetViewport(&vp);
……
void Render(void)
{
D3DXMATRIX matWorld;
if(NULL== p_D3DDevice)
return ;
static unsigned char red=0,green=0,blue=0;

//清除缓冲区并设置为新颜色
p_D3DDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(red,green,blue),1.0f,0);

//向设备提示开始渲染
if(SUCCEEDED(p_D3DDevice->BeginScene()))
{
// 使用普通的顶点模式
p_D3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);

p_D3DDevice->SetStreamSource(0,g_vb,0,sizeof(my_vertex));
D3DXMatrixTranslation(&matWorld,10.0f,0.0f,0.0f);
p_D3DDevice->SetTransform(D3DTS_WORLD,&matWorld);
p_D3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1);



// 向设备提示渲染完成
p_D3DDevice->EndScene();
}
// 显示结果
p_D3DDevice->Present(NULL,NULL,NULL,NULL);
}
...全文
408 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
estein 2009-04-09
  • 打赏
  • 举报
回复
额 大概明白了 taxi 谢谢你了哦~~~
IONPhantom 2009-04-08
  • 打赏
  • 举报
回复
把代码贴出来吧,要不很难判断,FVF设置的不对确实会有影响
taxi 2009-04-08
  • 打赏
  • 举报
回复
struct my_vertex{
FLOAT x,y,z,rhw;
DWORD color;
};

把rhw这个成员去掉。
estein 2009-04-08
  • 打赏
  • 举报
回复
这是最开始的代码 这样就是直接空白 什么都显示不出来了
estein 2009-04-08
  • 打赏
  • 举报
回复
全部代码如下

#include <windows.h>
#include <d3dx9.h>


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


RECT rect;

int sw=640;
int sh=480;

bool FullScreen = 1;

struct my_vertex{
FLOAT x,y,z,rhw;
DWORD color;
};

//一个用来定义顶点的宏
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)


my_vertex g_vertices[]={
{0.0f,1.0f,0.0f,1.0f,0xFFFFFFFF},// x,y,z,COLOR
{0.0f,-1.0f,0.0f,1.0f,0xFFFFFFFF},
{-1.0f,-1.0f,0.0f,1.0f,0xFFFFFFFF},
{-1.0f,-1.0f,0.0f,1.0f,0x0000000},
{-1.0f,1.0f,0.0f,1.0f,0x0000000},
{1.0f,-1.0f,0.0f,1.0f,0x0000000},
{1.0f,1.0f,0.0f,1.0f,0x0000000},
};

//顶点缓冲区是用优化方法渲染存储的顶点的一种方法

IDirect3DVertexBuffer9 *g_vb = NULL;

LPDIRECT3D9 p_D3D = NULL; //Direct3D对象指针
IDirect3DDevice9 *p_D3DDevice = NULL; //Direct3D设备指针


HWND hWnd;
HDC hDc;

HINSTANCE hInstance;


int D3DInit(void)
{
HRESULT hr;
void *vb_vertices;

D3DXMATRIX view_matrix;
D3DXMATRIX matProj;

p_D3DDevice->SetRenderState(D3DRS_LIGHTING,FALSE);


hr = p_D3DDevice->CreateVertexBuffer(7*sizeof(my_vertex),
D3DUSAGE_WRITEONLY,
D3DFVF_CUSTOMVERTEX,
D3DPOOL_MANAGED,
&g_vb,NULL);

hr = g_vb->Lock(0,0,&vb_vertices,0);
if(FAILED(hr))
{
MessageBox(NULL,"Error Locking Buffer","fd",MB_ICONHAND);
}

memcpy(vb_vertices,g_vertices,sizeof(g_vertices));
g_vb->Unlock();

D3DXMatrixLookAtLH(&view_matrix,&D3DXVECTOR3(0.0f,0.0f,-1.0f),
&D3DXVECTOR3(0.0f,0.0f,0.0f),
&D3DXVECTOR3(0.0f,1.0f,0.0f));
p_D3DDevice->SetTransform(D3DTS_VIEW,&view_matrix);

D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,(float)sw/(float)sh,1.0f,100.0f);
p_D3DDevice->SetTransform(D3DTS_PROJECTION,&matProj);

return S_OK;
}

D3DFORMAT find_16bit_mode(void)
{
HRESULT hr;
//首先测试(16位色模式)R5G6B5
hr=p_D3D->CheckDeviceType(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
D3DFMT_R5G6B5,
D3DFMT_R5G6B5,
FALSE);
if(SUCCEEDED(hr))
{
return D3DFMT_R5G6B5;
}
// 接下来测试X1R5G5B5
hr=p_D3D->CheckDeviceType(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
D3DFMT_X1R5G5B5,
D3DFMT_X1R5G5B5,
FALSE);
if(SUCCEEDED(hr))
{
return D3DFMT_X1R5G5B5;
}
return (D3DFORMAT)NULL;
}

BOOL D3DEnable()
{
// HRESULT hr;
D3DPRESENT_PARAMETERS d3dpp;
D3DDISPLAYMODE display_mode;
// 创建Direct3D9 ,这是任何D3D9程序里必须做的事情
// 返回D3D版本值
if(NULL==(p_D3D = Direct3DCreate9(D3D_SDK_VERSION)))
return E_FAIL;

//查询当前(桌面)的显示模式,仅运行在窗口模式
if(FAILED(p_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&display_mode)))
return E_FAIL;


//设置传递给LPDIRECT3D9::CreateDevice 的参数,将D3DPRESENT_PARAMETERS结构清零
ZeroMemory(&d3dpp,sizeof(d3dpp));

// 在全屏和窗口模式下均相同
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

// 由于不再有用,所以要释放以前的帧

d3dpp.hDeviceWindow = hWnd;// 主窗口
d3dpp.BackBufferCount = 1;// 仅需要一个备份缓冲区

// 在全屏模式下设置后备缓冲区的宽/高
if(FullScreen)
{
d3dpp.Windowed = FALSE;
d3dpp.BackBufferWidth = sw;
d3dpp.BackBufferHeight = sh;
d3dpp.BackBufferFormat = find_16bit_mode();
}
else
{
d3dpp.Windowed = TRUE;
d3dpp.BackBufferFormat = display_mode.Format;
}
if(FAILED(p_D3D->CreateDevice(D3DADAPTER_DEFAULT,//在多显示器系统中默认的接口可以超过一个
D3DDEVTYPE_HAL,//尽量选择硬件加速而不是软件渲染
hWnd,// 当前窗口
D3DCREATE_SOFTWARE_VERTEXPROCESSING,// 用软件处理矢量,要比硬件方式慢,但兼容所有图形卡
&d3dpp,// D3DPRESENT_PARAMETERS结构
&p_D3DDevice)))// 指向新的设备
return E_FAIL;
return TRUE;
}

///////////////////////////////////////////////
// 释放D3D系统资源
//
void D3DDisable()
{
if(p_D3DDevice)
{
p_D3DDevice->Release();
p_D3DDevice = NULL;
}
if(p_D3D)
{
p_D3D->Release();
p_D3D = NULL;
}
if(g_vb)
{
g_vb->Release();
g_vb = NULL;
}

}

////////////////////////////////////////
// 绘制D3D画面
//
void Render(void)
{
D3DXMATRIX matWorld;
if(NULL== p_D3DDevice)
return ;
static unsigned char red=0,green=0,blue=0;

//清除缓冲区并设置为新颜色
p_D3DDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(red,green,blue),1.0f,0);

//向设备提示开始渲染
if(SUCCEEDED(p_D3DDevice->BeginScene()))
{
// 使用普通的顶点模式
p_D3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);

p_D3DDevice->SetStreamSource(0,g_vb,0,sizeof(my_vertex));
D3DXMatrixTranslation(&matWorld,-1.0f,0.0f,0.0f);
p_D3DDevice->SetTransform(D3DTS_WORLD,&matWorld);
p_D3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1);

D3DXMatrixTranslation(&matWorld,1.0f,0.0f,0.0f);
p_D3DDevice->SetTransform(D3DTS_WORLD,&matWorld);
p_D3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,3,2);

// 向设备提示渲染完成
p_D3DDevice->EndScene();
}
// 显示结果
p_D3DDevice->Present(NULL,NULL,NULL,NULL);
}


////////////////////////////////////////
// 窗口过程函数
//
LRESULT CALLBACK WndProc(HWND hWnd,UINT Message,
WPARAM wParam,LPARAM lParam)
{
switch(Message)
{
case WM_CREATE:
GetWindowRect(hWnd,&rect);
sw=rect.right-rect.left;
sh=rect.bottom-rect.top;
return 0;
case WM_SIZE:
return 0;
case WM_CLOSE:
PostQuitMessage(0);
return 0;
case WM_DESTROY:
return 0;
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
PostMessage(hWnd,WM_CLOSE,0,0);
break;
}
return 0;
default:
return DefWindowProc(hWnd,Message,wParam,lParam);
}
}


//////////////////////////////////////////
// 注册窗口
//
BOOL Register(HINSTANCE hInst)
{
WNDCLASS WndClass;

WndClass.style = CS_OWNDC;
WndClass.lpfnWndProc = WndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInst;
WndClass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
WndClass.hCursor = LoadCursor(NULL,IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = "Name";

return (RegisterClass(&WndClass)!=0);

}

/////////////////////////////////////////
// 建立窗口
//
HWND Create(HINSTANCE hInst,int nCmdShow)
{
hInstance = hInst;
HWND hWnd;
if(FullScreen)
{
hWnd = CreateWindow("Name","Lesson 1",WS_POPUP|WS_CLIPSIBLINGS|WS_VISIBLE,
0,0,
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN),
NULL,NULL,
hInstance,NULL);
}
else
{
hWnd = CreateWindow("Name","Lesson 1",WS_TILEDWINDOW|WS_VISIBLE,
GetSystemMetrics(SM_CXSCREEN)/2-sw/2,
GetSystemMetrics(SM_CYSCREEN)/2-sh/2,
sw,sh,
NULL,NULL,
hInstance,NULL);
ChangeDisplaySettings(NULL,0);
}
if(hWnd==NULL)
return FALSE;

ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);

return hWnd;
}


///////////////////////////////////////////
// 应用程序入口
//
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nCmdShow)
{
MSG Msg;
bool bQuit = FALSE;

if(MessageBox(NULL,"是否选择全屏模式?","FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO)
{
FullScreen = 0;
}
if(!hPrevInst)
{
if(!Register(hInst))
return FALSE;
}
hWnd=Create(hInst,nCmdShow);

if(SUCCEEDED(D3DEnable()))
{
D3DInit();

if(!FullScreen)
{
GetWindowRect(hWnd,&rect);
sw=rect.right-rect.left;
sh=rect.bottom-rect.top;
}

while(!bQuit)
{
if(PeekMessage(&Msg,NULL,0,0,PM_REMOVE))
{
if(Msg.message==WM_QUIT)
bQuit = TRUE;
else
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
else
{
Render();
}
}
}
D3DDisable();
ShowWindow(hWnd,SW_HIDE);
DestroyWindow(hWnd);

ChangeDisplaySettings(NULL,0);
return Msg.wParam;
return 0;
}
estein 2009-04-08
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 taxi 的回复:]
D3DFVF_CUSTOMVERTEX是如何组合的,应该是D3DFVF_XYZ | D3DFVF_DIFFUSE
[/Quote]

是这样组合的
taxi 2009-04-08
  • 打赏
  • 举报
回复
你将照相机位置的Z坐标设大一点,另外确保你的顶点顺序是正确的或关闭了背面剔除,另外,你的顶点没有法线,因此照明需要光掉,Direct3D默认好像是打开的。
taxi 2009-04-08
  • 打赏
  • 举报
回复
你现在的问题是什么,窗口是黑的还是说你的3D坐标被解释成窗口坐标。
estein 2009-04-08
  • 打赏
  • 举报
回复
恩 去掉了 图像还是出不来~
estein 2009-04-08
  • 打赏
  • 举报
回复
发错了,顶点数据是这样的
my_vertex g_vertices[]={
{0.0f,1.0f,0.0f,0xFFFFFFFF},// x,y,z,COLOR
{0.0f,-1.0f,0.0f,0xFFFFFFFF},
{-1.0f,-1.0f,0.0f,0xFFFFFFFF},
{-1.0f,-1.0f,0.0f,0x0000000},
{-1.0f,1.0f,0.0f,0x0000000},
{1.0f,-1.0f,0.0f,0x0000000},
{1.0f,1.0f,0.0f,0x0000000},
};
estein 2009-04-07
  • 打赏
  • 举报
回复
我使用的开发环境是VC6.0 会不会是这个的原因?
taxi 2009-04-07
  • 打赏
  • 举报
回复
D3DFVF_CUSTOMVERTEX是如何组合的,应该是D3DFVF_XYZ | D3DFVF_DIFFUSE
estein 2009-04-07
  • 打赏
  • 举报
回复
就是建立观察矩阵,透视投影矩阵,然后将相对坐标转换为世界坐标,但是貌似没有效果
小弟刚开始学Direct 3D
ieihqqqq 2009-04-06
  • 打赏
  • 举报
回复
屏幕坐标系与设备坐标系之间的转换吧。。
内容概要:本文档聚焦于通信系统中的调制解调技术与Turbo码的结合应用,系统研究了GMSK调制的二比特差分解调方法,以及Turbo码分别与BPSK、GMSK调制方式联合使用的系统性能。通过Matlab平台实现了完整的通信链路仿真,涵盖信号调制、信道编码、解调解码及误码率分析等关键环节,深入探讨了不同调制体制下Turbo编码系统的抗干扰能力与频谱效率表现。研究不仅提供了算法实现代码,还包含了详细的性能对比分析,有助于理解现代数字通信中高效编码调制技术的设计原理与工程实现。此外,文档附带多个相关科研方向的仿真案例,展现出广泛的技术延展性与实际应用价值。; 适合人群:具备通信原理、数字信号处理等相关基础知识,熟悉Matlab编程环境,正在从事无线通信系统仿真、信道编码理论研究或相关领域科研工作的研究生、高校教师及工程技术研究人员。; 使用场景及目标:①深入掌握GMSK调制与Turbo码相结合的技术机制,理解其在提高通信可靠性与频谱利用率方面的优势;②熟练运用Matlab构建完整的数字通信仿真系统,完成从调制编码到解调译码的全流程建模与性能评估;③为无人机通信、卫星通信、移动通信等实际应用场景下的高可靠传输系统设计提供理论支持与算法参考。; 阅读建议:建议结合所提供的Matlab代码逐模块运行与调试,重点关注GMSK差分解调过程与Turbo译码的迭代收敛特性,同时可参考文档中列出的其他研究课题拓展仿真范围,提升综合科研与工程实践能力。

19,464

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧