求助,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);
}
...全文
409 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
  • 打赏
  • 举报
回复
屏幕坐标系与设备坐标系之间的转换吧。。
内容概要:本文系统研究了基于豪猪优化算法(CPO)的多无人机协同集群在三维空间中的避障路径规划问题,聚焦于实现以最低成本为目标的航迹优化,综合考虑路径长度、飞行高度、威胁规避及转弯角度等多个关键因素。通过构建精细化的三维环境模型与多无人机协同机制,采用Matlab平台实现CPO算法的仿真与验证,充分展示了该算法在复杂动态障碍环境下的高效搜索能力与全局优化性能。研究不仅涵盖了路径规划的数学建模与目标函数设计,还深入探讨了算法的收敛特性与鲁棒性,为智能群体系统在实际场景中的应用提供了理论依据与技术支撑。; 适合人群:具备一定编程基础和优化算法背景,从事无人机系统控制、智能路径规划、群体协同、人工智能与自动化等相关领域的科研人员、高校研究生及工程技术人员。; 使用场景及目标:①应用于多无人机协同执行侦察、灾害监测、应急救援、区域巡检等复杂任务中的自主路径规划;②为智能优化算法在三维动态环境下的路径决策问题提供可复现的技术范例;③支持研究人员对CPO算法与其他主流群智能算法(如PSO、GWO、WOA等)进行性能对比与改进研究,推动路径规划技术的发展。; 阅读建议:建议结合提供的Matlab代码进行实践操作,重点理解目标函数的多维度建模方式与CPO算法的迭代优化流程,可通过调整环境参数与约束条件进行仿真实验,对比不同算法在相同场景下的路径质量与收敛速度,从而深入掌握其优势与适用边界。
内容概要:本文围绕电动汽车参与电力系统运行备用的能力评估展开深入研究,利用Matlab代码实现对电动汽车集群提供运行备用服务的建模与仿真分析。研究重点在于量化电动汽车作为分布式灵活资源参与电网辅助服务的潜力,通过构建精细化的数学模型,分析其可调功率容量、响应速度、时空分布特性及聚合能力,并采用多面体聚合、内近似模型与闵可夫斯基和等先进方法精确刻画其可调度能力边界。研究进一步结合大规模电动汽车接入场景,探讨其在多时间尺度调度框架下参与调峰、调频等辅助服务的优化策略,评估其对提升高比例可再生能源电网灵活性与稳定性的贡献,最终通过仿真验证所提模型与方法的有效性与实用性。; 适合人群:具备电力系统分析、智能电网、新能源汽车或优化调度等相关专业背景,熟悉Matlab/Simulink仿真工具,从事科研、工程应用的高校研究生、科研人员及电力行业工程师。; 使用场景及目标:①精确评估大规模电动汽车集群在不同约束条件下可提供的运行备用容量;②研究电动汽车在日前、日内及实时调度中的动态响应能力与优化调度策略;③为高渗透率新能源电力系统提供基于移动储能的灵活性资源解决方案,支撑电网安全经济运行。; 阅读建议:建议结合Matlab代码与技术文档同步学习,重点关注多面体聚合建模、能力边界计算及优化调度算法的设计与实现,可进一步拓展至V2G(车辆到电网)、需求响应等互动场景进行二次开发与应用验证。

19,464

社区成员

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

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