d3d.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 819 行 · 第 1/2 页

C
819
字号

    // Here let's check if we can use dynamic textures
	textures_dynamic = FALSE;
    if (caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES)
		textures_dynamic = TRUE;

	if (init_cube() == 0)
		return 0;

	init_textures();

	return 1;
}

//---------------------------------------------------------------------------------------
// Create a vertexbuffer and put some cube data in it
//---------------------------------------------------------------------------------------
#define V_LEFT   -0.5f
#define V_RIGHT   0.5f
#define V_TOP     0.5f
#define V_BOTTOM -0.5f
#define V_FRONT  -0.5f
#define V_BACK    0.5f

static const CUSTOMVERTEX cube[24]=
{
	{{V_LEFT,  V_TOP,    V_FRONT},	0xffffffff,0.0f,0.0f},
	{{V_LEFT,  V_BOTTOM, V_FRONT},	0xffffffff,0.0f,1.0f},
	{{V_RIGHT, V_BOTTOM, V_FRONT},	0xffffffff,1.0f,1.0f},
	{{V_RIGHT, V_TOP,    V_FRONT},	0xffffffff,1.0f,0.0f},

	{{V_LEFT,  V_TOP,    V_BACK},	0xffffffff,0.0f,0.0f},
	{{V_RIGHT, V_TOP,    V_BACK},	0xffffffff,0.0f,1.0f},
	{{V_RIGHT, V_BOTTOM, V_BACK},	0xffffffff,1.0f,1.0f},
	{{V_LEFT,  V_BOTTOM, V_BACK},	0xffffffff,1.0f,0.0f},

	{{V_LEFT,  V_TOP,    V_BACK},	0xffffffff,0.0f,0.0f},
	{{V_LEFT,  V_BOTTOM, V_BACK},	0xffffffff,0.0f,1.0f},
	{{V_LEFT,  V_BOTTOM, V_FRONT},	0xffffffff,1.0f,1.0f},
	{{V_LEFT,  V_TOP,    V_FRONT},	0xffffffff,1.0f,0.0f},

	{{V_RIGHT, V_TOP,    V_BACK},	0xffffffff,0.0f,0.0f},
	{{V_RIGHT, V_TOP,    V_FRONT},	0xffffffff,0.0f,1.0f},
	{{V_RIGHT, V_BOTTOM, V_FRONT},	0xffffffff,1.0f,1.0f},
	{{V_RIGHT, V_BOTTOM, V_BACK},	0xffffffff,1.0f,0.0f},

	{{V_LEFT,  V_TOP,    V_BACK},	0xffffffff,0.0f,0.0f},
	{{V_LEFT,  V_TOP,    V_FRONT},	0xffffffff,0.0f,1.0f},
	{{V_RIGHT, V_TOP,    V_FRONT},	0xffffffff,1.0f,1.0f},
	{{V_RIGHT, V_TOP,    V_BACK},	0xffffffff,1.0f,0.0f},

	{{V_LEFT,  V_BOTTOM, V_BACK},	0xffffffff,0.0f,0.0f},
	{{V_RIGHT, V_BOTTOM, V_BACK},	0xffffffff,0.0f,1.0f},
	{{V_RIGHT, V_BOTTOM, V_FRONT},	0xffffffff,1.0f,1.0f},
	{{V_LEFT,  V_BOTTOM, V_FRONT},	0xffffffff,1.0f,0.0f},
};

int init_cube(void)
{
	CUSTOMVERTEX *pVertices;
	HRESULT hr;

	hr = IDirect3DDevice9_CreateVertexBuffer(d3d_dev, sizeof cube,
										  D3DUSAGE_DYNAMIC, D3DFVF_CUSTOMVERTEX,
										  D3DPOOL_DEFAULT, &vertex_buffer, NULL); 

	if (hr != D3D_OK)
		return 0;

	// Fill the vertex buffer
	hr = IDirect3DVertexBuffer9_Lock(vertex_buffer, 0, 0, (void**)&pVertices, D3DLOCK_DISCARD);

	if (hr != D3D_OK)
		return 0;

	memcpy(pVertices, cube, sizeof cube);
	hr = IDirect3DVertexBuffer9_Unlock(vertex_buffer);

	return 1;
}

//---------------------------------------------------------------------------------------
// Create some basic textures
//---------------------------------------------------------------------------------------
#define TEX_WIDTH 16
#define TEX_HEIGHT 16

static const char pattern[2*TEX_WIDTH*TEX_HEIGHT]=
{
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,
	0,0,0,0,1,1,1,0,1,0,1,1,1,0,0,0,
	0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,
	0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
	0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,
	0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,
	0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,
	0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,
	0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,
	0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,
	0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,
	0,0,1,0,0,0,1,0,0,1,0,0,0,1,0,0,
	0,0,1,0,0,0,1,0,0,1,0,0,0,1,0,0,
	0,0,1,0,0,0,1,0,0,1,0,0,0,1,0,0,
	0,0,1,0,0,0,1,0,0,1,0,0,0,1,0,0,
	0,0,1,0,0,0,1,0,0,1,0,0,0,1,0,0,
	0,0,0,1,1,1,0,0,0,1,0,0,0,1,0,0,
	0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,
	0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,
	0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

};

void init_textures(void)
{
	HRESULT hr;
	int i;
	unsigned int colours[6] =
	{
		0xffff0000,
		0xff00ff00,
		0xff0000ff,
		0xffffff00,
		0xff00ffff,
		0xffff00ff,
	};

    D3DSURFACE_DESC ddsd;
	D3DLOCKED_RECT lr;
    IDirect3DSurface9 *pSurf;

	unsigned char *b;
	unsigned short wcolour;
	unsigned int x,y, width;
	unsigned int tex;

	for (i = 0; i < 6; i++)
	{
		if (textures_dynamic)
		{
			hr = IDirect3DDevice9_CreateTexture(d3d_dev, TEX_WIDTH, TEX_HEIGHT, 1, D3DUSAGE_DYNAMIC, 
										 texture_format,D3DPOOL_DEFAULT,
										 &texture[i], NULL);
		}
		else
		{
			hr = IDirect3DDevice9_CreateTexture(d3d_dev, TEX_WIDTH, TEX_HEIGHT, 1, 0, 
										 texture_format,D3DPOOL_MANAGED,
										 &texture[i], NULL);

		}

		// Texturing unsupported
		if (hr != D3D_OK)
			return;

		// CreateTexture can silently change the parameters on us

		memset(&ddsd, 0, sizeof ddsd);
		hr = IDirect3DTexture9_GetLevelDesc(texture[i], 0, &ddsd);


	    hr = IDirect3DTexture9_GetSurfaceLevel(texture[i], 0, &pSurf);
		hr = IDirect3DSurface9_GetDesc(pSurf, &ddsd);
		hr = IDirect3DSurface9_Release(pSurf);


		if (textures_dynamic)
			hr = IDirect3DTexture9_LockRect(texture[i], 0, &lr, NULL, D3DLOCK_DISCARD);
		else
			hr = IDirect3DTexture9_LockRect(texture[i], 0, &lr, NULL, 0);

		// Writing to textures unsupported (broken driver?)
		if (hr != D3D_OK)
			return;

		b = (unsigned char *)lr.pBits;

		tex = (i&1)*TEX_WIDTH*TEX_HEIGHT;

		switch (ddsd.Format)
		{
			case D3DFMT_X8R8G8B8:
			case D3DFMT_A8R8G8B8:
				width = TEX_WIDTH * 4;

				for (y = 0; y < TEX_HEIGHT; y++)
				{
					for (x = 0; x < TEX_WIDTH; x++)
					{
						*(((unsigned int *)b)+x) = pattern[tex+x+y*TEX_WIDTH]?colours[i]^0xffffff:colours[i];
					}
					b += lr.Pitch;
				}
				break;

			case D3DFMT_A1R5G5B5:
				width = TEX_WIDTH * 2;

				wcolour  = (colours[i]>>3)&0x1f;
				wcolour |= (colours[i]>>6)&(0x1f<<5);
				wcolour |= (colours[i]>>9)&(0x1f<<10);
				wcolour |= (colours[i]>>16)&0x8000;

				for (y = 0; y < TEX_HEIGHT; y++)
				{
					for (x = 0; x < TEX_WIDTH; x++)
					{
						*(((unsigned short *)b)+x) = pattern[tex+x+y*TEX_WIDTH]?wcolour^0x7fff:wcolour;
					}
					b += lr.Pitch;
				}
				break;

			case D3DFMT_R5G6B5:
				width = TEX_WIDTH * 2;

				wcolour  = (colours[i]>>3)&0x1f;
				wcolour |= (colours[i]>>5)&(0x3f<<5);
				wcolour |= (colours[i]>>11)&(0x1f<<11);

				for (y = 0; y < TEX_HEIGHT; y++)
				{
					for (x = 0; x < TEX_WIDTH; x++)
					{
						*(((unsigned short *)b)+x) = pattern[tex+x+y*TEX_WIDTH]?wcolour^0xffff:wcolour;
					}
					b += lr.Pitch;
				}
				break;

			default:
				assert(0);
		}

		hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
	}
}

//---------------------------------------------------------------------------------------
// Shutdown Direct3D
//---------------------------------------------------------------------------------------
void shutdown_d3d(void)
{
	int i;

	for (i = 0; i < 6; i++)
		if (texture[i]) IDirect3DTexture9_Release(texture[i]);


	if (vertex_buffer) IDirect3DVertexBuffer9_Release(vertex_buffer);
	if (d3d_dev) IDirect3DDevice9_Release(d3d_dev);
	if (d3d) IDirect3D9_Release(d3d);
}

//---------------------------------------------------------------------------------------
// Set the Viewport
//---------------------------------------------------------------------------------------
void set_view(void)
{
	HRESULT hr;

    D3DXMATRIX matWorld;
    D3DXMATRIX matView;
    D3DXMATRIX matProj;

	float A,B,C,D,E,F,AD,BD;
	float zn, zf;

	memset(&matWorld, 0, sizeof matWorld);
	matWorld._11 = 1.0f;
	matWorld._22 = 1.0f;
	matWorld._33 = 1.0f;
	matWorld._44 = 1.0f;
	D3DXMatrixIdentity(&matWorld);
    hr = IDirect3DDevice9_SetTransform(d3d_dev, D3DTS_WORLD, &matWorld);


	A=(float)cos((double)yaw);  B=(float)sin((double)yaw);
	C=(float)cos((double)pitch);D=(float)sin((double)pitch);
	E=(float)cos((double)roll); F=(float)sin((double)roll);
	AD=A*D;
	BD=B*D;

	memset(&matView, 0, sizeof matView);
	matView._11 = C*E;
	matView._12 = -C*F;
	matView._13 = D;
	matView._21 = BD*E+A*F;
	matView._22 = -BD*F+A*E;
	matView._23 = -B*C ;
	matView._31 = -AD*E+B*F;
	matView._32 = AD*F+B*E;
	matView._33 = A*C;
	matView._41 = x;
	matView._42 = y;
	matView._43 = z;
	matView._44 = 1.0f;

	matView._11 *= scale;
	matView._12 *= scale;
	matView._13 *= scale;
	matView._21 *= scale;
	matView._22 *= scale;
	matView._23 *= scale;
	matView._31 *= scale;
	matView._32 *= scale;
	matView._33 *= scale;

    hr = IDirect3DDevice9_SetTransform(d3d_dev, D3DTS_VIEW, &matView);

/*
	D3DXMatrixPerspectiveLH(&matProj, 1.0f, 0.75f, 1.0f, 32767.0f);
	2*zn/w  0       0              0
	0       2*zn/h  0              0
	0       0       zf/(zf-zn)     1
	0       0       zn*zf/(zn-zf)  0
*/
	zn = 1.0f;
	zf = 32767.0f;
	memset(&matProj, 0, sizeof matProj);
	matProj._11 = 2.0f / 1.0f;
	matProj._22 = 2.0f / 0.75f;
	matProj._33 = 1.0f/(zf-zn);
	matProj._34 = 1.0f;
	matProj._43 = zn/(zn-zf);
/*
	D3DXMatrixOrthoLH(&matProj, 1.0f, 0.75f, 1.0f, 32767.0f);
	2/w  0    0           0
	0    2/h  0           0
	0    0    1/(zf-zn)   0
	0    0    zn/(zn-zf)  1

	zn = 1.0f;
	zf = 32767.0f;
	memset(&matProj, 0, sizeof matProj);
	matProj._11 = 2.0f / 1.0f;
	matProj._22 = 2.0f / 0.75f;
	matProj._33 = 1.0f/(zf-zn);
	matProj._34 = 1.0f;
	matProj._43 = zn/(zn-zf);
*/
	hr = IDirect3DDevice9_SetTransform(d3d_dev, D3DTS_PROJECTION, &matProj);
}

//---------------------------------------------------------------------------------------
// Flip between the backbuffer and frontbuffer
//---------------------------------------------------------------------------------------
void flip(void)
{
	HRESULT hr;
	hr = IDirect3DDevice9_Present(d3d_dev, 0,0,0,0);
}

//---------------------------------------------------------------------------------------
// Draw the Direct3D scene
//---------------------------------------------------------------------------------------
void draw(void)
{
	HRESULT hr;
	int i;

	// Clear the scene
	if (zbuffer_enabled)
		hr = IDirect3DDevice9_Clear(d3d_dev, 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
	else
		hr = IDirect3DDevice9_Clear(d3d_dev, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 1.0f, 0);

	// Begin scene
	hr = IDirect3DDevice9_BeginScene(d3d_dev);

	set_view();

	// Set the vertext format
	hr = IDirect3DDevice9_SetStreamSource(d3d_dev, 0, vertex_buffer, 0, sizeof(CUSTOMVERTEX));
	hr = IDirect3DDevice9_SetVertexShader(d3d_dev, NULL);
	hr = IDirect3DDevice9_SetFVF(d3d_dev, D3DFVF_CUSTOMVERTEX);

	// Set texture states
	hr = IDirect3DDevice9_SetTextureStageState(d3d_dev, 0, D3DTSS_COLOROP,   D3DTOP_MODULATE);
	hr = IDirect3DDevice9_SetTextureStageState(d3d_dev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
	hr = IDirect3DDevice9_SetTextureStageState(d3d_dev, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
	hr = IDirect3DDevice9_SetTextureStageState(d3d_dev, 0, D3DTSS_ALPHAOP,   D3DTOP_DISABLE);

	// Render the vertex buffer contents
	for (i = 0; i < 6; i++)
	{
		// Set the texture
		hr = IDirect3DDevice9_SetTexture(d3d_dev, 0, (IDirect3DBaseTexture9 *)texture[i]);
		// Draw one of the faces
		hr = IDirect3DDevice9_DrawPrimitive(d3d_dev, D3DPT_TRIANGLEFAN, 4*i, 2);
	}

	// End the scene
	hr = IDirect3DDevice9_EndScene(d3d_dev);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?