7 纹理映射
来源:互联网 发布:网络照片素材 编辑:程序博客网 时间:2024/05/01 05:00
借助纹理映射技术,可以把图像数据映射到三角形单元中,为3D图型添加更具细节的描绘
使用纹理映射,需要学习
映射方式
纹理创建
纹理过滤
纹理坐标
D3D所使用的纹理坐标由平面坐标构成 水平u轴 和 竖直v轴
由坐标对 (u,v)标识的纹理元素称为纹理元
之前说过,纹理映射是把图像数据映射到三角形单元中,在3d世界中所有的单元都是由三角形构成的
要实现纹理映射,需要给顶点中添加一项纹理坐标 D3DFVF_TEX1
为每个需要纹理映射的图形的顶点添加相应的纹理坐标点,相当于每个三角形在纹理图像中都有对应的纹理块
纹理映射在图形3d变换到屏幕坐标,光栅化过程中才会进行,在此之前,3d流水线处理的都是大量的三角形组成的网格
创建和启用纹理
纹理创建函数
HRESULT D3DXCreateTextureFromFile( __in LPDIRECT3DDEVICE9 pDevice, __in LPCTSTR pSrcFile, __out LPDIRECT3DTEXTURE9 *ppTexture);
从文件载入纹理,可以载入格式有:.bmp, .dds, .dib, .hdr, .jpg, .pfm, .png, .ppm, and .tga.
返回值为载入成功或失败原因
载入后,为设备设置当前纹理
共有8层纹理可以设置,多层纹理可以带来更加细腻的视觉效果
初期只用一层:Device->SetTexture(0, Tex);
参数1是纹理层号(0开始),参数2是纹理指针,指向创建的指针,也就是创建函数的输出值
要禁用一层纹理,把参数2设为0即可
如果场景中各个三角形用的纹理不同,可以设置一个画一个,在绘制之前 换掉纹理即可
许多小型游戏的纹理都在一张图片上,使用的时候只需要不同的纹理坐标即可区分
纹理过滤器
在进行纹理映射的时候,大多情况下纹理三角形和屏幕三角形的大小是不同的,这种时候,纹理三角形就必须为了适应屏幕三角形而变化,放大或缩小,在变化的时候会有畸变发生,为了克服这个,诞生了纹理过滤器
D3D有三种过滤器,每种都提供一种质量水平,质量越高,运算开销越大,处理速度越慢
使用哪一种需要在具体情况下权衡
1最近点采样
默认的方式,处理速度最快,不需要额外的运算,直接提取最近的有纹理的点的纹理
在纹理三角形和屏幕三角形大小差别不大,或者纹理比较简单的时候效果可以接受,但是一旦差别较大就会很畸形
2线性纹理过滤
这是建议使用的纹理过滤,处理效果一般,速度也不错,至少应该使用这种纹理过滤方式
3各向异性纹理过滤
效果最好,需要牺牲速度
在D3D中,需要设定D3DSAMP_MAXANISOTROPY的值
它决定各向异性过滤的质量水平
各向异性过滤 用来过滤、处理当视角变化造成3D物体表面倾斜时做成的纹理错误
两大显卡厂商 ATI和NVIDIA产品都有相应的支持,在显卡驱动中可以设置硬件过滤质量
这里DX里的D3DSAMP_MAXANISOTROPY是取的这个硬件值作为各向异性过滤的最大质量
设置值越大对硬件消耗越大
在设置这个值时,需要先调用设备的 GetDeviceCaps函数检查返回的D3DCAOS9参数,获得取值的范围(不大于硬件支持的最大值)
多级渐进纹理
为了提高纹理映射效率和质量,尽量解决纹理映射时产生的畸变且具备更高效率
解决方法是采用多级渐进纹理,尽量消除屏幕三角形和纹理三角形大小的差异
创建一个多级渐进纹理链,为纹理创建一系列分辨率逐渐减小的纹理图像,并对每个分辨率所采用的过滤方式进行定制
以便保留重要细节,使图像不产生严重失真
多级渐进纹理过滤器用于控制D3D使用多级渐进纹理的方式,做一个设置取值即可
常用值是
D3DTEXF_NONE 禁用多级纹理过滤器
D3DTEXF_POINT 选择与屏幕三角形尺寸最接近的纹理
D3DTEXF_LINEAR 选择与屏幕三角形尺寸最接近的两个纹理,然后取线性组合,形成最终的颜色值
Device->SetSamplerState(0,D3DSAMP_MIPFILTER,Filter)
Filter取值为上述三个常量
由于硬件的良好支持,多级渐进处理速度和效果都不错,应用很多
寻址模式
顶点中的纹理坐标范围都在[0,1]区间,但是实际应用中有很多情况会超过这个范围
D3D中有4种用于应对的寻址模式
重复
边界颜色
钳位
镜像
按照实际需要选择合适的寻址模式
例程
//////////////////////////////////////////////////////////////////////////////////////////////////// // File: texCube.cpp// // Author: Frank Luna (C) All Rights Reserved//// System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0 //// Desc: Renders a textured cube. Demonstrates creating a texture, setting// texture filters, enabling a texture, and texture coordinates. Use// the arrow keys to orbit the scene.// //////////////////////////////////////////////////////////////////////////////////////////////////#include "d3dUtility.h"#include "cube.h"#include "vertex.h"//// Globals//IDirect3DDevice9* Device = 0; const int Width = 640;const int Height = 480; Cube* Box = 0;IDirect3DTexture9* Tex = 0;//// Framework Functions//bool Setup(){//// Create the cube.//Box = new Cube(Device);//// Set a directional light.//D3DLIGHT9 light;::ZeroMemory(&light, sizeof(light));light.Type = D3DLIGHT_DIRECTIONAL;light.Ambient = D3DXCOLOR(0.8f, 0.8f, 0.8f, 1.0f);light.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);light.Specular = D3DXCOLOR(0.2f, 0.2f, 0.2f, 1.0f);light.Direction = D3DXVECTOR3(1.0f, -1.0f, 0.0f);Device->SetLight(0, &light);Device->LightEnable(0, true);Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);Device->SetRenderState(D3DRS_SPECULARENABLE, true);//// Create texture.//D3DXCreateTextureFromFile(Device,"crate.jpg",&Tex);// // Set Texture Filter States.//Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);//// Set the projection matrix.//D3DXMATRIX proj;D3DXMatrixPerspectiveFovLH(&proj,D3DX_PI * 0.5f, // 90 - degree(float)Width / (float)Height,1.0f,1000.0f);Device->SetTransform(D3DTS_PROJECTION, &proj);return true;}void Cleanup(){d3d::Delete<Cube*>(Box);d3d::Release<IDirect3DTexture9*>(Tex);}bool Display(float timeDelta){if( Device ){// // Update the scene: update camera position.//static float angle = (3.0f * D3DX_PI) / 2.0f;static float height = 2.0f;if( ::GetAsyncKeyState(VK_LEFT) & 0x8000f )angle -= 0.5f * timeDelta;if( ::GetAsyncKeyState(VK_RIGHT) & 0x8000f )angle += 0.5f * timeDelta;if( ::GetAsyncKeyState(VK_UP) & 0x8000f )height += 5.0f * timeDelta;if( ::GetAsyncKeyState(VK_DOWN) & 0x8000f )height -= 5.0f * timeDelta;D3DXVECTOR3 position( cosf(angle) * 3.0f, height, sinf(angle) * 3.0f );D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);D3DXMATRIX V;D3DXMatrixLookAtLH(&V, &position, &target, &up);Device->SetTransform(D3DTS_VIEW, &V);//// Draw the scene://Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);Device->BeginScene();Device->SetMaterial(&d3d::WHITE_MTRL);Device->SetTexture(0, Tex);Box->draw(0, 0, 0);Device->EndScene();Device->Present(0, 0, 0, 0);}return true;}//// WndProc//LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){switch( msg ){case WM_DESTROY:::PostQuitMessage(0);break;case WM_KEYDOWN:if( wParam == VK_ESCAPE )::DestroyWindow(hwnd);break;}return ::DefWindowProc(hwnd, msg, wParam, lParam);}//// WinMain//int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd){if(!d3d::InitD3D(hinstance,Width, Height, true, D3DDEVTYPE_HAL, &Device)){::MessageBox(0, "InitD3D() - FAILED", 0, 0);return 0;}if(!Setup()){::MessageBox(0, "Setup() - FAILED", 0, 0);return 0;}d3d::EnterMsgLoop( Display );Cleanup();Device->Release();return 0;}
- 7 纹理映射
- 纹理映射
- 纹理映射
- 纹理映射
- 纹理映射
- 纹理映射
- 纹理映射
- 纹理映射
- 纹理映射
- 纹理映射
- 纹理映射
- 纹理映射
- 第九讲 纹理映射
- Direct3D纹理映射
- 纹理映射基础
- opengl 纹理映射
- 纹理映射和坐标
- openGL纹理映射
- 年度总结(13-14)
- codeforces div2 round#230 C
- STM32F4XX工程步骤
- 浅谈Redis数据库的键值设计
- HDU 1702 ACboy needs your help again!(栈与队列的基本使用)
- 7 纹理映射
- 2014Dedecms标签新增中...
- dfs
- 文件操作(OJ数据生成)
- 贪心 删数问题
- HDU 1016 Prime Ring Problem(经典DFS )
- linux进程与线程的区别
- codeforces div2 round#230 D
- iOS安全攻防(十九):基于脚本实现动态库注入