以文本方式查看主题 - 计算机科学论坛 (http://bbs.xml.org.cn/index.asp) -- 『 C/C++编程思想 』 (http://bbs.xml.org.cn/list.asp?boardid=61) ---- 纹理映射基础(2) (http://bbs.xml.org.cn/dispbbs.asp?boardid=61&rootid=&id=69999) |
-- 作者:卷积内核 -- 发布时间:12/2/2008 10:15:00 AM -- 纹理映射基础(2) 最近点采样 最近点采样是4种过滤方式中速度最快但效果最差的过滤方式。Direct3D计算得到的纹理元素地址通常是一个浮点数值,而非整数的纹理下标值,当使用最近点采样时,Direct3D会复制与这个浮点值地址最接近的整数地址的纹理元素的颜色。 设置最近点采样的具体方法如下:调用IDirect3DDevice9::SetSamplerState(),可分别设置纹理过滤的放大过滤器和缩小过滤器。将第一个参数设置为纹理过滤器关联的纹理层序号(0~7)。如果要设置放大过滤器,第二个参数设为D3DSAMP_MAGFILTER,如果要设置缩小过滤器,第二个参数设为D3DSAMP_MINFILTER。第三个参数可设为表示最近点采样的枚举常量D3DTEXF_POINT。下列代码将纹理层0的纹理过滤方式设置为最近点采样。 g_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); 如果纹理的大小和屏幕图元的实际大小将近,那么采用最近点采样方法对图像质量的影响不大。但是,如果大小相差太多,就会降低图像精度,从而影响图像质量,出现色块或闪烁的失真现象。
线性纹理过滤 线性纹理过滤是目前使用最广泛的纹理过滤方法。它与最近点采样相比,能有效地提高图像的显示质量,并且对系统性能影响不大。线性纹理过滤取得与计算得到的纹理元素的浮点地址最接近的上、下、左、右4个纹理元素,对这4个纹理元素进行加权平均,得到最终显示的颜色值。 与设置最近点采样的方法相似,调用函数IDirect3DDevice9::SetSamplerState()设置线性纹理过滤,所不同的是第三个参数设置为D3DTEXF_LINEAR。下面的代码将纹理层0的放大和缩小过滤器设置为线性纹理过滤。 g_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); 因为是在单一纹理层上的线性过滤,而且是x、y方向上的线性过滤,所以称为双线性纹理过滤。目前大多数显卡都为线性纹理过滤进行了优化,所以使用线性纹理过滤一方面可以获得较好的图形质量,另一方面对程序性能影响不大。
各项异性纹理过滤 当三维物体表面与投影平面不平行时,它在屏幕上的投影会有拉长或扭曲,这种现象称为各项异性(anisotropy)。当一个各向异性图元的像素映射到纹理元素时,它的形状发生扭曲。Direct3D根据屏幕像素反向转换到纹理元素的延长度,决定各项异性程度。 要使用各项异性纹理过滤,还应当设置最大各项异性程度值。通过将函数IDirect3DDevive9::SetSamplerState()的第一个参数设为纹理层索引,第二个参数设为D3DSAMP_MAXANISOTOPY,第三个参数设为大于1的任何值,可以完成最大各项异性程度值的设置。下面的示例代码指定了最大各项异性值为4。 g_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC); 最大各项异性程度值D3DSAMP_MAXANISOTROPY为1时,表示禁用各项异性过滤。一般说来,其值越大,图像效果越好,计算量越大,速度越慢。需要注意的是,在设置最大各项异性之前,应调用IDirect3D9::GetDeviceCaps()函数,查询当前设备支持的Direct3D特性,获取当前设备支持的最大各项异性度的取值范围,具体代码如下: DWORD get_max_anisotropy(IDirect3DDevice9* device){ D3DCAPS9 caps; device->GetDeviceCaps(&caps); 纹理过滤方式示例程序 按下数字键“1”使用最近点采样纹理过滤方式,按下数字键“2”使用线性纹理过滤方式,按下数字键“3”使用各项异性纹理过滤方式。
源程序: #pragma warning(disable : 4127) #define CLASS_NAME "GameApp" #define release_com(p) do { if(p) { (p)->Release(); (p) = NULL; } } while(0) IDirect3D9* g_d3d; struct sCustomVertex #define D3DFVF_CUSTOM_VERTEX (D3DFVF_XYZ | D3DFVF_TEX1) void setup_matrices() // setup view matrix D3DXVECTOR3 eye(0.0f, 0.0f, -8.0f); D3DXMATRIX mat_view; // setup projection matrix D3DXMATRIX mat_proj; bool init_graphics() sCustomVertex vertices[] = }; g_device->CreateVertexBuffer(sizeof(vertices), 0, D3DFVF_CUSTOM_VERTEX, D3DPOOL_MANAGED, &g_vertex_buffer, NULL); void* ptr; g_vertex_buffer->Lock(0, 0, (void**)&ptr, 0); return true; bool init_d3d(HWND hwnd) if(g_d3d == NULL) D3DPRESENT_PARAMETERS d3dpp; d3dpp.Windowed = TRUE; if(FAILED(g_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, setup_matrices(); g_device->SetRenderState(D3DRS_LIGHTING, FALSE); void cleanup() void render() g_device->BeginScene(); g_device->SetTexture(0, g_texture); g_device->SetStreamSource(0, g_vertex_buffer, 0, sizeof(sCustomVertex)); g_device->EndScene(); g_device->Present(NULL, NULL, NULL, NULL); LRESULT WINAPI WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) case 49: // press key "1", use nearest point texture filter mode case 50: // press key "2", use linear texture filter mode case 51: // press key "3", use anisotropy texture filter mode case WM_DESTROY: return DefWindowProc(hwnd, msg, wParam, lParam); int WINAPI WinMain(HINSTANCE inst, HINSTANCE, LPSTR, INT) wc.cbSize = sizeof(WNDCLASSEX); if(! RegisterClassEx(&wc)) HWND hwnd = CreateWindow(CLASS_NAME, "Direct3D App", WS_OVERLAPPEDWINDOW, 200, 100, 800, 600, if(hwnd == NULL) if(init_d3d(hwnd)) MSG msg; while(msg.message != WM_QUIT) cleanup(); return 0; |
-- 作者:卷积内核 -- 发布时间:12/2/2008 10:16:00 AM -- 纹理映射基础(5) 多级渐进纹理过滤 多级渐进纹理由一组分辨率逐渐降低的纹理序列组成,每一级纹理宽度和高度都是上一级纹理宽度和高度的一半。宽和高不一定相等,也就是说,这些纹理不一定都是正方形。 Direct3D在纹理映射时,自动选择一幅与物体大小最接近的纹理进行渲染。当物体离投影平面较远时,Direct3D会选择一张尺寸较小、分辨率较低的纹理进行渲染;当物体离投影平面较近时,Direct3D会选择一张尺寸较大、分辨率较高的纹理进行渲染。Direct3D将纹理序列看成一条多级渐进纹理链。链头处纹理的分辨率最高,下一级往后依次递减,链尾处纹理的分辨率最低。 Direct3D能估计出多级渐进纹理链中哪幅纹理的分辨率最接近想要的输出结果,然后它将像素映射到纹理空间。当最终显示的图形大小介于任意两级纹理图形之间时,Direct3D将两级纹理的相应元素进行混合后显示。 多级渐进纹理过滤能够有效地提高图形渲染速度,当物体离投影平面较远时,Direct3D会选择一张尺寸较小的纹理进行渲染,而无需经过复杂的诸如各项异性纹理过滤,并且由于这时纹理需要的显存比不使用多级渐进纹理时小,因此能有效地减少纹理载入显存的时间。
生成多级渐进纹理 可以通过调用Direct3D扩展实用库函数D3DXCreateTextureFromFileEx()自动生成多级渐进纹理序列,该函数的声明如下: Creates a texture from a file. This is a more advanced function than D3DXCreateTextureFromFile. HRESULT D3DXCreateTextureFromFileEx( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, UINT Width, UINT Height, UINT MipLevels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, DWORD Filter, DWORD MipFilter, D3DCOLOR ColorKey, D3DXIMAGE_INFO * pSrcInfo, PALETTEENTRY * pPalette, LPDIRECT3DTEXTURE9 * ppTexture); D3DERR_NOTAVAILABLED3DERR_OUTOFVIDEOMEMORYD3DXERR_INVALIDDATAE_OUTOFMEMORY Use D3DXCheckTextureRequirements to determine if your device can support the texture given the current state. This function supports the following file formats: .bmp, .dds, .dib, .hdr, .jpg, .pfm, .png, .ppm, and .tga. See D3DXIMAGE_FILEFORMAT. Mipmapped textures automatically have each level filled with the loaded texture. When loading images into mipmapped textures, some devices are unable to go to a 1x1 image and this function will fail. If this happens, then the images need to be loaded manually. For the best performance when using D3DXCreateTextureFromFileEx: Doing image scaling and format conversion at load time can be slow. Store images in the format and resolution they will be used. If the target hardware requires power of 2 dimensions, then create and store images using power of 2 dimensions. 参数Format是D3DFORMAT枚举类型,指定纹理图形的格式,还可以将它设置为D3DFMT_DXT1 ~ D3DFMT_DXT5的值之一,表示生成DXT压缩纹理以节省空间。
These #defines are declared in d3dx9.h.
typedef struct D3DXIMAGE_INFO { UINT Width; UINT Height; UINT Depth; UINT MipLevels; D3DFORMAT Format; D3DRESOURCETYPE ResourceType; D3DXIMAGE_FILEFORMAT ImageFileFormat;} D3DXIMAGE_INFO, *LPD3DXIMAGE_INFO; typedef struct PALETTEENTRY { BYTE peRed; BYTE peGreen; BYTE peBlue; BYTE peFlags;} PALETTEENTRY, *LPPALETTEENTRY; 设置多级渐进纹理过滤方式 当最终显示的纹理贴图大小介于任意两级纹理之间时,Direct3D能够取得两级纹理元素进行混合后显示,具体的混合方式由指定的多级渐进纹理过滤方式决定。可以调用函数IDirect3DDevice9::SetSamplerState()设置多级渐进纹理过滤方式,将第一个参数设为纹理层序号,第二个参数设为D3DSAMP_MIPFILTER表示多级渐进纹理过滤,第三个参数设为在相邻纹理级之间的过滤方式,可取枚举类型D3DTEXTUREFILTERTYPE的任意值。下面的示例代码设置相邻纹理级之间的过滤方式为线性过滤。 g_device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); 如果将第三个参数设为D3DTEXF_NONE,那么就会一直使用最高一级的纹理,即禁用多级渐进纹理过滤。如果将其设为D3DTEXF_POINT,就会只使用与图元大小最匹配的一级纹理。如果将其设为D3DTEXF_LINEAR,Direct3D就将与图元大小最匹配的两级纹理以线性方式混合。 需要注意的是,多级纹理过滤是缩小和放大过滤器的结合。例如,如果将缩小和方法过滤器设为线性过滤,但是多级纹理过滤方式设为最近点采样,Direct3D就会选择与要显示的纹理贴图大小最接近的纹理级别,在该级纹理上完成双线性纹理过滤,并将结果作为像素的值。如果将缩小、放大过滤器和多级渐进纹理都设置为线性过滤,则Direct3D就会在两个最接近的纹理级别上都进行双线性纹理过滤,然后再对相邻两级纹理图形上对应的两个纹理颜色进行加权平均,最后的结果作为单个像素值。这种为了图元中的一个像素,而结合了两幅纹理,共8个像素的技术,称为“三线性过滤”,因为它在纹理的三个方向----u、 v和纹理级别上都进行了线性过滤。 可以通过IDirect3DDevice9::SetSamplerState()函数设置实际渲染时纹理过滤的最大级数,其中需要将第二个参数设为D3DSAMP_MAXMIPLEVEL,第三个参数设为实际渲染时纹理过滤的最大级数。下面的示例代码设置纹理层0的最大多级纹理过滤级数为16。 g_device->SetSamplerState(0, D3DSAMP_MAXMIPLEVEL, 16); 还可以通过将IDirect3DDevice9::SetSamplerState()的第二个参数设为D3DSAMP_MIPMAPLODBIAS,设置多级纹理映射级数偏移值。如果对某个纹理映射设置正偏移值,得到的图形结果就会比原来的更清晰,但锯齿更多;反之设为负偏移值,得到的图形结果就会更模糊。
|
-- 作者:卷积内核 -- 发布时间:12/2/2008 10:17:00 AM -- 多级渐进纹理过滤示例程序 该程序创建了一幅多级渐进纹理和一幅单级别纹理,按下数字键“1”则使用多级渐进纹理,按下数字键“2”则使用单级别纹理。按下“↓”和“↑”则缩小和放大显示的图形,仔细观察图像的变化,可以看到多级渐进纹理的效果。 使用MipMap纹理过滤
使用单级纹理过滤(即禁用多级纹理过滤)
源程序: #pragma warning(disable : 4127) #define CLASS_NAME "GameApp" #define release_com(p) do { if(p) { (p)->Release(); (p) = NULL; } } while(0) IDirect3D9* g_d3d; struct sCustomVertex #define D3DFVF_CUSTOM_VERTEX (D3DFVF_XYZ | D3DFVF_TEX1) void setup_matrices() // setup view matrix D3DXVECTOR3 eye(0.0f, 0.0f, g_distance); D3DXMATRIX mat_view; // setup projection matrix D3DXMATRIX mat_proj; bool init_graphics() // create mipmap texture object sCustomVertex vertices[] = }; g_device->CreateVertexBuffer(sizeof(vertices), 0, D3DFVF_CUSTOM_VERTEX, D3DPOOL_MANAGED, &g_vertex_buffer, NULL); void* ptr; g_vertex_buffer->Lock(0, 0, (void**)&ptr, 0); return true; bool init_d3d(HWND hwnd) if(g_d3d == NULL) D3DPRESENT_PARAMETERS d3dpp; d3dpp.Windowed = TRUE; if(FAILED(g_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, g_device->SetRenderState(D3DRS_LIGHTING, FALSE); void cleanup() void render() g_device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(5, 5, 5), 1.0f, 0); g_device->BeginScene(); g_device->SetTexture(0, g_use_mip_texture ? g_mip_texture : g_texture); g_device->SetStreamSource(0, g_vertex_buffer, 0, sizeof(sCustomVertex)); g_device->EndScene(); g_device->Present(NULL, NULL, NULL, NULL); LRESULT WINAPI WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) case 49: // press key "1", use mipmap texture filter mode case 50: // press key "2", use normal texture filter mode case VK_DOWN: case VK_UP: case WM_DESTROY: return DefWindowProc(hwnd, msg, wParam, lParam); int WINAPI WinMain(HINSTANCE inst, HINSTANCE, LPSTR, INT) wc.cbSize = sizeof(WNDCLASSEX); if(! RegisterClassEx(&wc)) HWND hwnd = CreateWindow(CLASS_NAME, "Direct3D App", WS_OVERLAPPEDWINDOW, 200, 100, 800, 600, if(hwnd == NULL) if(init_d3d(hwnd)) MSG msg; while(msg.message != WM_QUIT) cleanup(); return 0; |
-- 作者:卷积内核 -- 发布时间:12/2/2008 10:17:00 AM -- 纹理映射基础(6) 纹理寻址模式 Direct3D应用程序可以为任何图元的任何顶点指定纹理坐标,通常使用的 u、v 纹理坐标的取值范围是[0.0, 1.0],但是通过设置该范围外的坐标值,可以得到纹理映射的特殊效果。 虽然系统允许纹理坐标取[0.0, 1.0]范围外的值,但硬件极限常常影响纹理坐标的取值范围。当调用函数IDirect3DDevice9::GetDeviceCaps()得到设备性能后,一个渲染设备将此极限值放在结构D3DCAPS的成员MaxTextureRepeat中。这个成员的值表示该设备能允许的纹理坐标取值范围。例如,该值是128,那么输入的纹理坐标必须在范围[-128, 128]中,使用这个范围之外的纹理坐标是无效的。 对MaxTextureRepeat的解释也受D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE的影响。当设置了该标志位,那么结构D3DCAPS9的成员MaxTextureRepeat的使用就像前面所讲的一样;但如果没有设置该标志位,纹理坐标范围就根据纹理的大小和MaxTextureRepeat的值而定。假定一个纹理的大小为32 x 32像素,MaxTextureRepeat的值是512,那么512/32 = 16,有效的纹理坐标范围就是[-16, 16]。 Direct3D定义了4种纹理寻址模式来处理纹理坐标超出[0, 1]范围的纹理映射方法,它们分别是重叠映射寻址(wrap texture address mode)、镜像纹理寻址(mirror texture address mode)、夹取纹理寻址(clamp texture address mode)、边框颜色纹理寻址(border color texture address mode)。
重叠纹理寻址模式 使用重叠纹理寻址模式时,Direct3D会在每个整数纹理坐标连接处自动重复纹理。例如,应用程序创建了一个正方形图元,并指定4个顶点的纹理坐标为(0.0, 0.0)、(0.0, 3.0)、(3.0, 3.0)、(3.0, 0.0)。使用重叠纹理寻址,Direct3D就会在u、v方向各复制3遍原始纹理,如下图所示: 可以调用函数IDirect3DDevice9::SetSamplerState()设置纹理寻址模式。设置第一个参数为纹理层序号,第二个参数为D3DSAMP_ADDRESSU或D3DSAMP_ADDRESSV,表示对纹理的u方向或v方向设置纹理寻址模式,第三个参数设为相应的纹理寻址模式,可以取枚举类型D3DTEXTUREADDRESS中的一个。 Defines constants that describe the supported texture-addressing modes. typedef enum D3DTEXTUREADDRESS{ D3DTADDRESS_WRAP = 1, D3DTADDRESS_MIRROR = 2, D3DTADDRESS_CLAMP = 3, D3DTADDRESS_BORDER = 4, D3DTADDRESS_MIRRORONCE = 5, D3DTADDRESS_FORCE_DWORD = 0x7fffffff,} D3DTEXTUREADDRESS, *LPD3DTEXTUREADDRESS; g_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP); 重叠纹理寻址是Direct3D中缺省的寻址模式,也是三维系统中最常用的寻址模式之一。在渲染具有诸如砖墙之类纹理的物体时,如果使用包含一整张砖墙的纹理贴图会占用较多的内存,通常只需载入一张具有一块或多块砖瓦的较小的纹理贴图,再把它按照重叠纹理寻址模式在物体表面映射多次,就可以达到和使用整张砖墙贴图同样的效果。
镜像纹理寻址模式 使用镜像纹理寻址模式时,Direct3D会在每个整数纹理坐标连接处自动复制并翻转纹理。例如,应用程序创建了一个正方形图元,并指定4个顶点的纹理坐标为(0.0, 0.0)、(0.0, 3.0)、(3.0, 3.0)、(3.0, 0.0)。采用镜像纹理寻址模式,Direct3D就会在u、v方向各复制3遍并翻转原始纹理图,所有的行和列都是前一行或列的镜像,如下图所示: 用枚举类型D3DTEXTUREADDRESS的成员D3DTADDRESS_MIRROR指定镜像纹理寻址模式。下面的示例代码设置纹理层0的u、v方向寻址模式为镜像纹理寻址模式: g_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR);
夹取纹理寻址模式 夹取纹理寻址模式将纹理坐标夹取在[0.0, 1.0]范围之内。也就是说,它将纹理复制一遍,然后将纹理边缘像素的颜色延伸。例如,应用程序创建了一个正方形图元,并指定4个顶点的纹理坐标为(0.0, 0.0)、(0.0, 3.0)、(3.0, 3.0)、(3.0, 0.0)。将u、v方向上的纹理寻址模式都设置为夹取纹理寻址模式时的效果如下图所示: 用枚举类型D3DTEXTUREADDRESS的成员D3DTADDRESS_CLAMP指定夹取纹理寻址模式。下面的示例代码设置纹理层0的u、v方向寻址模式为夹取纹理寻址模式: g_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
边框颜色纹理寻址模式 边框颜色纹理寻址模式用枚举类型D3DTEXTUREADDRESS的成员D3DTADDRESS_BORDER指定,当纹理坐标超出[0.0, 1.0]范围时,Direct3D使用边框颜色代替纹理颜色。 边框颜色通过调用函数IDirect3DDevice9::SetSamplerState()设置,第一个参数设为纹理层序号,第二个参数设为D3DSAMP_BORDERCOLOR,第三个参数设为所需的边框颜色,为D3DCOLOR类型,以32位整数表示A、R、G、B颜色。下面的示例代码指定边框颜色为红色,并设置纹理层0的u、v方向寻址模式为边框颜色纹理寻址模式。 g_device->SetSamplerState(0, D3DSAMP_BORDERCOLOR, 0xFFFF0000); 渲染的结果如下图所示: |
-- 作者:卷积内核 -- 发布时间:12/2/2008 10:18:00 AM -- 纹理寻址模式示例程序 示例程序演示了重叠纹理寻址、镜像纹理寻址、夹取纹理寻址和边框颜色纹理寻址4种不同的纹理寻址模式的效果,其效果图如上面贴图所示。 #pragma warning(disable : 4127) #define TEXTURE_ADDRESS_WRAP 1 #define CLASS_NAME "GameApp" #define release_com(p) do { if(p) { (p)->Release(); (p) = NULL; } } while(0) IDirect3D9* g_d3d; struct sCustomVertex #define D3DFVF_CUSTOM_VERTEX (D3DFVF_XYZ | D3DFVF_TEX1) void setup_matrices() // setup view matrix D3DXVECTOR3 eye(0.0f, 0.0f, -10.0f); D3DXMATRIX mat_view; // setup projection matrix D3DXMATRIX mat_proj; bool init_graphics() if(FAILED(D3DXCreateTextureFromFile(g_device, "texture2.bmp", &g_texture2))) sCustomVertex vertices[] = }; g_device->CreateVertexBuffer(sizeof(vertices), 0, D3DFVF_CUSTOM_VERTEX, D3DPOOL_MANAGED, &g_vertex_buffer, NULL); void* ptr; g_vertex_buffer->Lock(0, 0, (void**)&ptr, 0); return true; bool init_d3d(HWND hwnd) if(g_d3d == NULL) D3DPRESENT_PARAMETERS d3dpp; d3dpp.Windowed = TRUE; if(FAILED(g_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, setup_matrices(); g_device->SetRenderState(D3DRS_LIGHTING, FALSE); void cleanup() void setup_texture() case TEXTURE_ADDRESS_MIRROR: case TEXTURE_ADDRESS_CLAMP: case TEXTURE_ADDRESS_BORDER: void render() g_device->BeginScene(); setup_texture(); g_device->SetStreamSource(0, g_vertex_buffer, 0, sizeof(sCustomVertex)); g_device->EndScene(); g_device->Present(NULL, NULL, NULL, NULL); LRESULT WINAPI WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) case 49: // press key "1" case 50: // press key "2" case 51: // press key "3" case 52: // press key "4" case WM_DESTROY: return DefWindowProc(hwnd, msg, wParam, lParam); int WINAPI WinMain(HINSTANCE inst, HINSTANCE, LPSTR, INT) wc.cbSize = sizeof(WNDCLASSEX); if(! RegisterClassEx(&wc)) HWND hwnd = CreateWindow(CLASS_NAME, "Direct3D App", WS_OVERLAPPEDWINDOW, 200, 100, 480, 480, if(hwnd == NULL) if(init_d3d(hwnd)) MSG msg; while(msg.message != WM_QUIT) cleanup(); return 0; |
W 3 C h i n a ( since 2003 ) 旗 下 站 点 苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》 |
234.375ms |