怎样在D3D中绘制一个立方体(带贴图)?

火云洞红孩儿
博客专家认证
2003-11-25 05:05:56
刚看完Direct3D9初级教程,虽然还算容易\但脑袋有点疼…


好了,我打算做一个立方体(带贴图),建立顶点缓冲后。我以为按照空间位置将每个定点位置计算过后写进顶点缓冲数组就行了。可是搞来搞去。立方体我只能贴出四个面。有两个相对应的面死活贴不出来。咋办的?
请高手指点一下下哟!

以下是部分代码:
void CD3DWnd::InitGeometry()
{

//从图片文件中直接创建纹理对象
::D3DXCreateTextureFromFile( m_pDevice, "1.jpg", &m_pTexture );

//建立圆锥曲面的数学模型
CUSTOMVERTEX1 vertices1[10];
vertices1[0].position=D3DXVECTOR3(-5.0f,5.0f,5.0f);
vertices1[0].normal=D3DXVECTOR3(-5.0f,5.0f,5.0f);
vertices1[0].tu=0.0;
vertices1[0].tv=0.0;
vertices1[1].position=D3DXVECTOR3(5.0f,5.0f,5.0f);
vertices1[1].normal=D3DXVECTOR3(5.0f,5.0f,5.0f);
vertices1[1].tu=1.0;
vertices1[1].tv=0.0;
vertices1[2].position=D3DXVECTOR3(-5.0f,-5.0f,5.0f);
vertices1[2].normal=D3DXVECTOR3(-5.0f,-5.0f,5.0f);
vertices1[2].tu=0.0;
vertices1[2].tv=1.0;
vertices1[3].position=D3DXVECTOR3(5.0f,-5.0f,5.0f);
vertices1[3].normal=D3DXVECTOR3(5.0f,-5.0f,5.0f);
vertices1[3].tu=1.0;
vertices1[3].tv=1.0;

vertices1[4].position=D3DXVECTOR3(-5.0f,-5.0f,-5.0f);
vertices1[4].normal=D3DXVECTOR3(-5.0f,-5.0f,-5.0f);
vertices1[4].tu=0.0;
vertices1[4].tv=0.0;
vertices1[5].position=D3DXVECTOR3(5.0f,-5.0f,-5.0f);
vertices1[5].normal=D3DXVECTOR3(5.0f,-5.0f,-5.0f);
vertices1[5].tu=1.0;
vertices1[5].tv=0.0;
vertices1[6].position=D3DXVECTOR3(-5.0f,5.0f,-5.0f);
vertices1[6].normal=D3DXVECTOR3(-5.0f,5.0f,-5.0f);
vertices1[6].tu=0.0;
vertices1[6].tv=1.0;
vertices1[7].position=D3DXVECTOR3(5.0f,5.0f,-5.0f);
vertices1[7].normal=D3DXVECTOR3(5.0f,5.0f,-5.0f);
vertices1[7].tu=1.0;
vertices1[7].tv=1.0;

vertices1[8].position=D3DXVECTOR3(-5.0f,5.0f,5.0f);
vertices1[8].normal=D3DXVECTOR3(-5.0f,5.0f,5.0f);
vertices1[8].tu=0.0;
vertices1[8].tv=0.0;
vertices1[9].position=D3DXVECTOR3(5.0f,5.0f,5.0f);
vertices1[9].normal=D3DXVECTOR3(5.0f,5.0f,5.0f);
vertices1[9].tu=1.0;
vertices1[9].tv=0.0;


//创建圆锥曲面的顶点缓存区,填入顶点数据
m_pDevice->CreateVertexBuffer(
sizeof(vertices1), 0, D3DFVF_CUSTOMVERTEX1,
D3DPOOL_DEFAULT, &m_pVB1, NULL );
void* pVertices;
m_pVB1->Lock( 0, sizeof(vertices1), (void**)&pVertices, 0 );
memcpy( pVertices, vertices1, sizeof(vertices1) );
m_pVB1->Unlock();

...全文
368 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
IONPhantom 2003-11-27
  • 打赏
  • 举报
回复
还有一点,就是如果用DP的D3DPT_TRIANGLESTRIP是不可能一次画完一个立方体的,需要画多次,至于原因请仔细阅读SDK关于三角形排列部分。
如果想用DP画立方体至少要画两次。DIP可以一次画完。
IONPhantom 2003-11-27
  • 打赏
  • 举报
回复
vertices1数组中第9个顶点和第10个顶点的坐标是相同的,这样不会画出一个三角形,而是一条线段
火云洞红孩儿 2003-11-27
  • 打赏
  • 举报
回复
对嘛!还是楼上讲得好,干嘛没事就告诉我"去看SDK!"至少把一些基本原理告诉我吧!
acceptspf 2003-11-26
  • 打赏
  • 举报
回复
有很多问题,第一个:
如果不是连续三角型构成的面,怎样才能让面贴出的图完整。
acceptspf 2003-11-26
  • 打赏
  • 举报
回复
关注中,建议:你为什么要用MFC,从WINMAIN开始不是更好。
火云洞红孩儿 2003-11-26
  • 打赏
  • 举报
回复
第二部分
………………………………………
void CD3DWnd::Render()
{
//用指定颜色清除后备缓存区
m_pDevice->Clear(
0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(0,0,255), //指定使用蓝色
1.0f, 0);

//Direct3D规定在渲染前必须调用方法IDirect3DDevice9::BeginScene,
//结束时要调用IDirect3DDevice9::EndScene。
m_pDevice->BeginScene();

SetupMatrices(); //设置变换矩阵

SetLight(); //设置灯光

//绘制圆锥曲面的图元
SetMaterial1(); //使用白色的材质

//把纹理加入场景,其中参数1为纹理的索引号,取值范围0-7,
//分别代表第一至第八层纹理。这里只用了一层纹理,因此索引号为0。
m_pDevice->SetTexture( 0, m_pTexture );

//设置纹理混合方式为"纹理 × 材质的漫反射"。
//其实可以不用设置,因为这是Direct3D缺省的混合方式。
m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
m_pDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );

m_pDevice->SetFVF( D3DFVF_CUSTOMVERTEX1 );
m_pDevice->SetStreamSource( 0, m_pVB1, 0, sizeof(CUSTOMVERTEX1) );
//
m_pDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0,10);
// m_pDevice->DrawPrimitive( D3DPT_LINESTRIP, 0,10);
//纹理用完后,应该从场景中移除
m_pDevice->SetTexture( 0, NULL );
m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_DISABLE );

//绘制圆锥底面的图元
//SetMaterial2(); //使用黄色的材质
//m_pDevice->SetFVF( D3DFVF_CUSTOMVERTEX2 );
//m_pDevice->SetStreamSource( 0, m_pVB2, 0, sizeof(CUSTOMVERTEX2) );
//m_pDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 30 );

m_pDevice->EndScene();

//交换当前/后备缓存区,刷新窗口
m_pDevice->Present(NULL, NULL, NULL, NULL);
}

void CD3DWnd::Cleanup()
{
m_pVB1->Release(); //释放圆锥曲面的顶点缓存区
m_pVB2->Release(); //释放圆锥底面的顶点缓存区
m_pTexture->Release(); //释放纹理对象
m_pDevice->Release(); //释放设备对象
m_pD3D->Release(); //释放Direct3D对象
}

void CD3DWnd::OnDestroy()
{
CWnd::OnDestroy();

Cleanup(); //释放接口
}

void CD3DWnd::InitGeometry()
{

//从图片文件中直接创建纹理对象
::D3DXCreateTextureFromFile( m_pDevice, "1.jpg", &m_pTexture );

//建立圆锥曲面的数学模型
CUSTOMVERTEX1 vertices1[15];
vertices1[0].position=D3DXVECTOR3(-10.0f,10.0f,10.0f);
vertices1[0].normal=D3DXVECTOR3(-10.0f,10.0f,10.0f);
vertices1[0].tu=0.0;
vertices1[0].tv=0.0;
vertices1[1].position=D3DXVECTOR3(10.0f,10.0f,10.0f);
vertices1[1].normal=D3DXVECTOR3(10.0f,10.0f,10.0f);
vertices1[1].tu=1.0;
vertices1[1].tv=0.0;
vertices1[2].position=D3DXVECTOR3(-10.0f,-10.0f,10.0f);
vertices1[2].normal=D3DXVECTOR3(-10.0f,-10.0f,10.0f);
vertices1[2].tu=0.0;
vertices1[2].tv=1.0;
vertices1[3].position=D3DXVECTOR3(10.0f,-10.0f,10.0f);
vertices1[3].normal=D3DXVECTOR3(10.0f,-10.0f,10.0f);
vertices1[3].tu=1.0;
vertices1[3].tv=1.0;

vertices1[4].position=D3DXVECTOR3(-10.0f,-10.0f,-10.0f);
vertices1[4].normal=D3DXVECTOR3(-10.0f,-10.0f,-10.0f);
vertices1[4].tu=0.0;
vertices1[4].tv=0.0;
vertices1[5].position=D3DXVECTOR3(10.0f,-10.0f,-10.0f);
vertices1[5].normal=D3DXVECTOR3(10.0f,-10.0f,-10.0f);
vertices1[5].tu=1.0;
vertices1[5].tv=0.0;
vertices1[6].position=D3DXVECTOR3(-10.0f,10.0f,-10.0f);
vertices1[6].normal=D3DXVECTOR3(-10.0f,10.0f,-10.0f);
vertices1[6].tu=0.0;
vertices1[6].tv=1.0;
vertices1[7].position=D3DXVECTOR3(10.0f,10.0f,-10.0f);
vertices1[7].normal=D3DXVECTOR3(10.0f,10.0f,-10.0f);
vertices1[7].tu=1.0;
vertices1[7].tv=1.0;

vertices1[8].position=D3DXVECTOR3(-10.0f,10.0f,10.0f);
vertices1[8].normal=D3DXVECTOR3(-10.0f,10.0f,10.0f);
vertices1[8].tu=0.0;
vertices1[8].tv=0.0;
vertices1[9].position=D3DXVECTOR3(10.0f,10.0f,10.0f);
vertices1[9].normal=D3DXVECTOR3(10.0f,10.0f,10.0f);
vertices1[9].tu=1.0;
vertices1[9].tv=0.0;

vertices1[10].position=D3DXVECTOR3(10.0f,10.0f,10.0f);
vertices1[10].normal=D3DXVECTOR3(10.0f,10.0f,10.0f);
vertices1[10].tu=1.0;
vertices1[10].tv=0.0;

vertices1[11].position=D3DXVECTOR3(10.0f,-10.0f,10.0f);
vertices1[11].normal=D3DXVECTOR3(10.0f,-10.0f,10.0f);
vertices1[11].tu=1.0;
vertices1[11].tv=1.0;
vertices1[12].position=D3DXVECTOR3(10.0f,10.0f,-10.0f);
vertices1[12].normal=D3DXVECTOR3(10.0f,10.0f,-10.0f);
vertices1[12].tu=0.0;
vertices1[12].tv=0.0;
vertices1[13].position=D3DXVECTOR3(10.0f,-10.0f,-10.0f);
vertices1[13].normal=D3DXVECTOR3(10.0f,-10.0f,-10.0f);
vertices1[13].tu=0.0;
vertices1[13].tv=1.0;
vertices1[14].position=D3DXVECTOR3(10.0f,10.0f,10.0f);
vertices1[14].normal=D3DXVECTOR3(10.0f,10.0f,10.0f);
vertices1[14].tu=1.0;
vertices1[14].tv=1.0;
/*for(int j=0;j<5;j++)
{
vertices1[2*j].position=D3DXVECTOR3(0,(4-j)*7,0.0f);
vertices1[2*j].normal=D3DXVECTOR3(0,(4-j)*7,0.0f);
vertices1[2*j].tu=0.0;
vertices1[2*j].tv=(float)j/4;
vertices1[2*j+1].position=D3DXVECTOR3(30,(4-j)*7,0.0f);
vertices1[2*j+1].normal=D3DXVECTOR3(30,(4-j)*7,0.0f);
vertices1[2*j+1].tu=1.0;
vertices1[2*j+1].tv=(float)j/4;
}
*/
//!
//@}
//创建圆锥曲面的顶点缓存区,填入顶点数据
m_pDevice->CreateVertexBuffer(
sizeof(vertices1), 0, D3DFVF_CUSTOMVERTEX1,
D3DPOOL_DEFAULT, &m_pVB1, NULL );
void* pVertices;
m_pVB1->Lock( 0, sizeof(vertices1), (void**)&pVertices, 0 );
memcpy( pVertices, vertices1, sizeof(vertices1) );
m_pVB1->Unlock();

//建立圆锥底面的数学模型
CUSTOMVERTEX2 vertices2[32];
for (int i = 0; i < 16; i++)
{ //计算顶点序列C1、C30、C29 ... ... C1的坐标和法线
vertices2[i*2].position = D3DXVECTOR3(0,0.0f,-i);
vertices2[i*2].normal = D3DXVECTOR3(0,0.0f,-i);
vertices2[i*2+1].position = D3DXVECTOR3(30,0.0f,-i);
vertices2[i*2+1].normal = D3DXVECTOR3(30,0.0f,-i);

}

//创建圆锥底面的顶点缓存区,填入顶点数据
m_pDevice->CreateVertexBuffer(
sizeof(vertices2), 0, D3DFVF_CUSTOMVERTEX2,
D3DPOOL_DEFAULT, &m_pVB2, NULL );
m_pVB2->Lock( 0, sizeof(vertices2), (void**)&pVertices, 0 );
memcpy( pVertices, vertices2, sizeof(vertices2) );
m_pVB2->Unlock();
if(mypos>1)mypos=mypos-1.0;
}
火云洞红孩儿 2003-11-26
  • 打赏
  • 举报
回复
主文件第一部分
……………
// D3DWnd.cpp : implementation file
//

#include "stdafx.h"
#include "d3d001.h"
#include "D3DWnd.h"
float myx=0.0f,myy=20.0f,myz=-20.0f;
float mypos=0.0;
//圆锥曲面的FVF格式:坐标、顶点法线、纹理坐标
struct CUSTOMVERTEX1
{
D3DXVECTOR3 position; //顶点坐标
D3DXVECTOR3 normal; //顶点法线
float tu, tv; //纹理坐标
};
//D3DFVF_TEX1表示只使用一层纹理
#define D3DFVF_CUSTOMVERTEX1 (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)

//圆锥底面的FVF格式:坐标、顶点法线
struct CUSTOMVERTEX2
{
D3DXVECTOR3 position; //顶点坐标
D3DXVECTOR3 normal; //顶点法线
};
#define D3DFVF_CUSTOMVERTEX2 (D3DFVF_XYZ | D3DFVF_NORMAL)

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CD3DWnd

CD3DWnd::CD3DWnd()
{
}

CD3DWnd::~CD3DWnd()
{
}


BEGIN_MESSAGE_MAP(CD3DWnd, CWnd)
//{{AFX_MSG_MAP(CD3DWnd)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_TIMER()
//}}AFX_MSG_MAP
ON_WM_KEYDOWN()
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CD3DWnd message handlers

void CD3DWnd::InitD3D()
{
//创建Direct3D对象,并获取接口IDirect3D9的指针,
//我们将通过该指针操作Direct3D对象。
m_pD3D = ::Direct3DCreate9(D3D_SDK_VERSION);

D3DPRESENT_PARAMETERS d3dpp;
::ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE; //创建窗口模式的Direct3D程序
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16; //生成16 bit的Z缓存

//调用方法IDirect3D9::CreateDevice创建设备对象,并获取
//接口IDirect3DDevice9的指针,我们将通过该指针操作设备对象
m_pD3D->CreateDevice(
D3DADAPTER_DEFAULT, //使用缺省的显卡
D3DDEVTYPE_HAL, //指定设备类型为HAL
m_hWnd, //Direct3D窗口的句柄
D3DCREATE_SOFTWARE_VERTEXPROCESSING,//软件顶点处理
&d3dpp, &m_pDevice);

//启用Z缓存,允许消隐处理
m_pDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE );

//打开光照处理
m_pDevice->SetRenderState( D3DRS_LIGHTING, TRUE );

//自动对法线矢量进行归一化处理
m_pDevice->SetRenderState( D3DRS_NORMALIZENORMALS, TRUE );
m_pDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);

}

int CD3DWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;

InitD3D(); //初始化Direct3D
InitGeometry(); //进行建模
m_nRotateY = 0;
m_nLightvalue=0.0;
SetTimer( 1, 40 ,NULL ); //定时间隔设为40毫秒

return 0;
}
火云洞红孩儿 2003-11-26
  • 打赏
  • 举报
回复
头文件
……………………………

#if !defined(AFX_D3DWND_H__07BB53E9_5299_4FCB_AC74_EA2898F95D93__INCLUDED_)
#define AFX_D3DWND_H__07BB53E9_5299_4FCB_AC74_EA2898F95D93__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// D3DWnd.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CD3DWnd window

#include <d3d9.h>
#include <d3dx9math.h>

class CD3DWnd : public CWnd
{
protected:

LPDIRECT3D9 m_pD3D; //Direct3D对象的接口指针
LPDIRECT3DDEVICE9 m_pDevice; //设备对象的接口指针
void InitD3D(); //该函数用于初始化Direct3D
void Render(); //该函数用于渲染
void Cleanup(); //该函数用于释放接口

void InitGeometry(); //该函数用于建模

int m_nRotateY; //实体的旋转角度(单位:度)
int m_nLightvalue;
void SetupMatrices(); //该函数用于设置三个变换矩阵

LPDIRECT3DVERTEXBUFFER9 m_pVB1; //圆锥曲面的顶点缓存区接口指针
LPDIRECT3DVERTEXBUFFER9 m_pVB2; //圆锥底面的顶点缓存区接口指针
void SetLight(); //该函数用于设置灯光
void SetMaterial1(); //该函数用于设置圆锥曲面的材质
void SetMaterial2(); //该函数用于设置圆锥底面的材质

LPDIRECT3DTEXTURE9 m_pTexture; //纹理对象的接口指针

// Construction
public:
CD3DWnd();

// Attributes
public:

// Operations
public:

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CD3DWnd)
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~CD3DWnd();

// Generated message map functions
protected:
//{{AFX_MSG(CD3DWnd)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnDestroy();
afx_msg void OnTimer(UINT nIDEvent);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_D3DWND_H__07BB53E9_5299_4FCB_AC74_EA2898F95D93__INCLUDED_)
火云洞红孩儿 2003-11-26
  • 打赏
  • 举报
回复
楼上的:那你给我讲讲呗!
dfwdfw 2003-11-26
  • 打赏
  • 举报
回复
directx自带的例子就有一个是立方体几面都有贴图的,看下源代码比在这等好多了。
IONPhantom 2003-11-26
  • 打赏
  • 举报
回复
你的条件给的不足,还要把你怎么画的函数写出来,估计你是用的 DP ,不过从你上面的程序来看,顶点好象不够数哦
火云洞红孩儿 2003-11-26
  • 打赏
  • 举报
回复
我本来想发完的。但太多了。不过主要的应该也有了。

TO 飞虾:

1.为什么用MFC。呵呵,没什么原因。
就因为是看了。
http://www.gdiy.com/bookcool/Direct3D9.rar
//
2。我也在想这个问题。
但是我现在感觉,如果不是连续的三角型。就要通过对贴图坐标的计算和顶点的位置安排来贴图。
这样有可能某些平面其实被贴了两次图。但是只要你的贴图坐标和顶点坐标安排的巧妙。就能贴出完整的图。
可是我发现。我在贴出连续的四个面之后。剩下的两个相对的面就是死活贴不出来…


火云洞红孩儿 2003-11-25
  • 打赏
  • 举报
回复
等这么久了,都没人回答?

8,303

社区成员

发帖
与我相关
我的任务
社区描述
游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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