博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
D3D中的一项高级技术---渲染到纹理(转)
阅读量:2453 次
发布时间:2019-05-10

本文共 3388 字,大约阅读时间需要 11 分钟。

D3D中的一项高级技术---渲染到纹理(转)[@more@]

  ?内容

  渲染到纹理是D3D中的一项高级技术。一方面,它很简单,另一方面它很强大并能产生很多特殊效果。 比如说发光效果,环境映射,阴影映射,都可以通过它来实现。渲染到纹理只是渲染到表面的一个延伸。我们只需再加些东西就可以了。首先,我们要创造一个纹理,并且做好一些防范措施。第二步我们就可以把适当的场景渲染到我们创建的纹理上了。然后,我们把这个纹理用在最后的渲染上。

  ?main.cpp

  首先我们得声明所需要的对象。当然我们需要一张用来渲染的纹理。此外,我们还需要两个Surface对象。一个是用来存储后台缓冲区,一个用来当纹理的渲染对象。后面我再详细介绍它们。另外我们还需要两个矩阵,一个是用来当纹理的投影矩阵,另一个是存储原来的矩阵。

  LPDIRECT3DTEXTURE9 pRenderTexture = NULL;

  LPDIRECT3DSURFACE9 pRenderSurface = NULL,pBackBuffer = NULL;

  D3DXMATRIX matProjection,matOldProjection;

  现在我们来创建纹理。前两个参数是纹理的宽度和高度,第三个参数是纹理的多级渐进纹理序列参数,在这里是设为1,第四个参数非常重要而且必须设为D3DUSAGE_RENDERTARGET,表明我们所创建的纹理是用来渲染的。剩下的参数就是指纹理格式,顶点缓冲区的内存位置,和一个指向纹理的指针。当纹理是用来当渲染对象时,顶点缓冲区的内存位置必须设为D3D_DEFAILT。

  g_App.GetDevice()->CreateTexture(256,256,1,D3DUSAGE_RENDERTARGET,D3DFMT_R5G6B5,D3DPOOL_DEFAULT,&pRenderTexture,NULL);

  为了访问纹理内存对象,我们需要一个Surface对象,因为D3D中的纹理是用这样的一个Surface来存储纹理数据的。为了得到纹理表面的Surface,我们需要调用方法GetSurfaceLevel() 。第一个参数我们设为0,第二个参数为一个指向surface对象的指针。

  pRenderTexture->GetSurfaceLevel(0,&pRenderSurface);

  下一步就是创建一个适合纹理维数的投影矩阵,因为纹理的横纵比和后台缓冲区的不一样。

  D3DXMatrixPerspectiveFovLH(&matProjection,D3DX_PI / 4.0f,1,1,100);

  在我们的循环渲染之前,我们必须保存后台缓冲区和它的投影矩阵。

  g_App.GetDevice()->GetTransform(D3DTS_PROJECTION,&matOldProjection);

  g_App.GetDevice()->GetRenderTarget(0,&pBackBuffer);

  渲染循环函数可以分为两个部分。第一部分是渲染到纹理的过程。因此,渲染对象必须设为纹理表面。然后我们就可以把东西渲染到这个对象上了。渲染到另一个表面上和正常地渲染到后台缓冲区差不多。只有一点不同,那就是先不调用Prensent()函数,因为纹理上的内容并不需要显示在屏幕上。象平时一样,我们先要重置表面颜色缓冲区,并且调用BeginSence()和EndSence()方法。为了能够适当的渲染,我们必须设置和纹理表面相符的投影矩阵。否则最后的图象可能被扭曲

  //render-to-texture

  g_App.GetDevice()->SetRenderTarget(0,pRenderSurface); //set new render target

  g_App.GetDevice()->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(100,100,100),1.0f,0); //clear texture

  g_App.GetDevice()->BeginScene();

  g_App.GetDevice()->SetTexture(0,pPyramideTexture);

  D3DXMatrixRotationY(&matRotationY,fRotation);

  D3DXMatrixTranslation(&matTranslation,0.0f,0.0f,5.0f);

  g_App.GetDevice()->SetTransform(D3DTS_WORLD,&(matRotationY * matTranslation));

  g_App.GetDevice()->SetTransform(D3DTS_PROJECTION,&matProjection); //set projection matrix

  g_App.GetDevice()->SetStreamSource(0,pTriangleVB,0,sizeof(D3DVERTEX));

  g_App.GetDevice()->DrawPrimitive(D3DPT_TRIANGLELIST,0,4);

  g_App.GetDevice()->EndScene();

  渲染循环的第二部分就是渲染最后场景的过程(也就是显示到屏幕上的过程)。渲染对象重新设为后台缓冲区,投影矩阵重新设为原来的投影矩阵。由于纹理已经准备好了,所以它和纹理层0相关联。

  //render scene with texture

  g_App.GetDevice()->SetRenderTarget(0,pBackBuffer); //set back buffer

  g_App.GetDevice()->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0);

  g_App.GetDevice()->BeginScene();

  g_App.GetDevice()->SetTexture(0,pRenderTexture); //set rendered texture

  g_App.GetDevice()->SetTransform(D3DTS_WORLD,&matTranslation);

  g_App.GetDevice()->SetTransform(D3DTS_PROJECTION,&matOldProjection); //restore projection matrix

  g_App.GetDevice()->SetStreamSource(0,pQuadVB,0,sizeof(D3DVERTEX));

  g_App.GetDevice()->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);

  g_App.GetDevice()->EndScene();

  g_App.GetDevice()->Present(NULL,NULL,NULL,NULL);

  最后我们通过调用Release()方法释放Surface对象。

  pRenderSurface->Release();

  pRenderSurface = NULL;

  pBackBuffer->Release();

  pBackBuffer = NULL;

  渲染到纹理能让你做很多事情,但是你必须注意一些限制。首先深度缓冲区必须总是大于或等于渲染对象的大小。此外,渲染对象和深度缓冲区的格式必须一致

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/8225414/viewspace-951645/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/8225414/viewspace-951645/

你可能感兴趣的文章
css css2 css3_如何编写真正糟糕CSS
查看>>
git 初次提交_如何进行首次Git提交
查看>>
盖茨比乔布斯_盖茨比vs雨果,详细比较
查看>>
如何在twitter上看片_我在Twitter上一年学到的东西
查看>>
hitchhiker部署_Hitchhiker的React Router v4指南:20分钟内完成Grok React Router
查看>>
ecmascript6_ECMAScript 2015(ES6)概述
查看>>
css概念_要学习的最重要CSS概念
查看>>
ae初级教程视频教程_超级简单的Gulp初学者教程
查看>>
vanilla gan:_Vanilla JavaScript教程:如何构建内存匹配游戏
查看>>
渐进式web应用程序_渐进式Web应用程序101:什么,为什么以及如何
查看>>
angelhack_我的团队如何撼动AngelHack Seattle Hackathon
查看>>
将Socket.io添加到多线程Node.js
查看>>
javascript并发_限制JavaScript中的并发操作
查看>>
angular2创建应用_帮助您了解和创建Angular 6应用程序的快速指南
查看>>
可访问性不一致 可访问性低_如何开始网站可访问性
查看>>
自学区块链应用开发_我用来自学区块链开发的资源
查看>>
初学react实现路由跳转_初学者收集的强大的React技巧和窍门
查看>>
测试程序使用什么语言编写好_为未来的自我编写测试如何使您的测试更好
查看>>
跨域资源请求作用和应用场景_跨域资源共享请求如何影响应用程序的性能
查看>>
中国最年轻的亿万富翁_我和一个亿万富翁一起吃饭。 他给我的建议是无价的。
查看>>