dx游戏编程吧 关注:13贴子:143

回复:DX11资源贴,附带个人学习心得与记录

只看楼主收藏回复

写了一个自认为封装得比较好的框架,可以做到第一视角移动(懂得原理以后就能很容易的写出第三人称视角和其他摄像特效)还有一个比较好的计时器,当然很多都是参考网上的,把这个框架共享出来(已经发到网盘里面),我是边做游戏边学习,个人感觉这样效果很好,所以游戏内容的丰富是随我学的知识增长的。。
顺便说一下自己的心得


IP属地:四川36楼2013-05-28 01:02
回复

    先复制一下我在群里面以前说过的心得:
    创建windows窗口,初始化D3D设备,绑定视图,绑定布局(HLSL),然后开始画图,DX9应该每帧画图开始都是BeginScene结束都是EndScene,好像是这样,DX11没有这两个函数了,自己写了个BeginScene清除后置缓存和深度缓存,EndScene交换链呈像,
    3D世界里面的物体都有各自的坐标,但是一般要描述一个物体都是在一个自己假想的坐标里面描述,也就是说物体在假想的坐标的原点中心,这样物体比较容易描述,等要用使用物体的时候,再用物体对应的世界矩阵将物体转换到世界坐标里面(只要把矩阵交给HLSL就行了,用HLSL将顶点都和这个世界矩阵相乘一次),这样物体就在世界坐标里面了,然后就是视点的设置,可以想成是游戏人物的眼睛,需要视点的坐标,设点看的位置,和头顶方向,有这3个参数就能建立视点矩阵了,再将世界坐标里面的物体每一个顶点和这个矩阵相乘,那些物体的坐标就变成以你眼睛为中心的坐标,你的屏幕就是你的眼睛,最后是眼睛看物体的范围,和将物体投影到屏幕的矩阵就是投影矩阵,将物体现在的坐标再乘以这个矩阵,这些顶点就都集中在屏幕这张画板上了,然后通过深度值和法向量的筛选选择哪些顶点要画出来,就变成我们看到的图像。对于物体的运动和人物的运动,这些都能使画面变化,物体的运动就是改变物体对应的世界矩阵,世界矩阵不同,物体的位置就不同,人物的运动就是改变视点的坐标和视点所看的方向。
    然后是顶点,顶点的颜色,顶点的纹理坐标等等,这些在描述物体的时候需要知道的,物体需要什么属性就在顶点里面插入更多的属性,然后和HLSL联系起来渲染,也就是先前绑定的布局,前提是要将这些顶点和引索存到缓存里面并指定用这个缓存,要画这个物体的时候再通过物体对应的顶点和引索在缓存里面的起始位置以及引索的个数,当然还要设置拓扑结构,通过DrawIndexed画出来。


    IP属地:四川37楼2013-05-28 01:03
    回复
      2025-09-05 10:31:20
      广告
      不感兴趣
      开通SVIP免广告
      接下来大致浏览一下框架


      IP属地:四川38楼2013-05-28 01:04
      回复

        其中程序入口在进击の物语.cpp里面。
        我将
        SystemClass *g_systemClass;
        TimerClass *g_timerClass;
        InputClass *g_inputClass;
        D3DClass *g_D3DClass;
        CameraClass *g_cameraClass;
        ModelClass *g_modelClass;
        ShaderClass *g_shaderClass;
        都单独封装了起来,然后提供了接口函数
        CameraClass 里面还有一个geometryspace,提供一些简单的几何体创建接口
        看下初始化就能了解个大概了吧
        srand((unsigned)time(NULL));
        g_applicationName = L"进击の物语";
        g_isFullScreen = false;
        if(g_isFullScreen)
        {
        g_width = GetSystemMetrics(SM_CXSCREEN);
        g_height = GetSystemMetrics(SM_CYSCREEN);
        }
        else
        {
        g_width = 800;
        g_height = 600;
        }
        g_hInstance = GetModuleHandle(NULL);
        g_isVsync = false;
        g_screenNear = 0.1f;
        g_screenDeep = 1000.0f;
        g_totalVertices = 0;
        g_totalIndices = 0;
        g_systemClass = new SystemClass;
        if( !g_systemClass->Initialize(g_applicationName, g_hInstance, g_isFullScreen, g_width, g_height) )
        {
        return false;
        }
        g_hWnd = g_systemClass->GetHWnd();
        g_timerClass = new TimerClass;
        if( !g_timerClass->Initialize() )
        {
        return false;
        }
        g_inputClass = new InputClass;
        if( !g_inputClass->Initialize(g_hWnd) )
        {
        return false;
        }
        g_D3DClass = new D3DClass;
        if( !g_D3DClass->Initialize(g_hWnd, g_isFullScreen, g_width, g_height, g_isVsync) )
        {
        return false;
        }
        g_device = g_D3DClass->GetDevice();
        g_deviceContext = g_D3DClass->GetDeviceContext();
        g_cameraClass = new CameraClass;
        if( !g_cameraClass->Initialize(g_width, g_height, g_screenNear, g_screenDeep) )
        {
        return false;
        }
        g_modelClass = new ModelClass;
        if( !g_modelClass->Initialize(g_device, g_deviceContext) )
        {
        return false;
        }
        g_shaderClass = new ShaderClass;
        if( !g_shaderClass->Initialize(g_hWnd, g_device, g_deviceContext) )
        {
        return false;
        }


        IP属地:四川39楼2013-05-28 01:05
        回复

          因为都集中起来初始化了
          所以直接使用Initialize()就完成了主要的初始化
          几何体的创建也很简单,这里创建了3种几何体,并且初始化了它们的位置,meshData的结构在MODELCLASS里面,这里就不多讲了
          用它们创建缓存
          首先是顶点缓存内容
          顶点的颜色Colors,在这里只是给一个例子,如果你不使用纹理而是直接给几何着色的话,可以使用颜色数组先保存顶点的颜色
          然后是创建引索缓存内容和创建缓存


          然后画出这些图像是很简单的事,因为都封装好了,当然功能不是很完善,但这样清晰的流水线有助于学习


          IP属地:四川40楼2013-05-28 01:08
          收起回复
            不小心加了水印了,度娘这默认参数太坑爹了
            算了,不多说了,直接看源代码吧,注释还是挺多的
            另外吐槽一下,我把执行程序发给N台不同的电脑测试,只有一台能运行,VS2012的开发环境我不想吐槽了


            IP属地:四川41楼2013-05-28 01:10
            收起回复
              正在整合一个相当不错的shader框架,等弄好了发上来并说明一下


              IP属地:四川42楼2013-05-29 23:04
              回复
                HLSL缓存池的命名重复了,一开始一直找不到错误,重点是缓存池的命名重复编译shader的时候居然没有错误信息,然后大概是内存重叠访问了


                IP属地:四川43楼2013-06-01 00:30
                回复
                  2025-09-05 10:25:20
                  广告
                  不感兴趣
                  开通SVIP免广告
                  程序框架大改了很多,所以先把网盘里面的源码删了


                  IP属地:四川44楼2013-06-10 00:09
                  回复
                    现在基本完善了光照,纹理,天空盒,顶点引索文件载入模块,关于碰撞阅读了一些资料,写了半天渣得不忍直视,更别说物理碰撞了,这部分以后再弄吧
                    对于blend说一下自己的心得,首先要创建混合状态描述来修改混合状态,只有设置了混合状态才能使用透明度管道,默认是不使用的,混合过程用HLSL写,而且重要的是,混合只作用于当前要渲染的像素点和当前后置缓存中的像素点,也就是说不同物体使用DrawIndexed的顺序不同是有影响的,简单的来说就是一个物体(A)渲染过了,再去渲染其他的物体(B),那么A不会对B进行混合,因为渲染B之前A已经渲染了。
                    We start rendering the frame by first drawing the terrain followed by the wooden crate, so that theterrain and crate pixels are on the back buffer. We then draw the water surface to the back buffer using blending, sothat the water pixels get blended with the terrain and crate pixels on the back buffer in such a way that the terrain andcrate shows through the water. In this chapter, we examine blending techniques which allow us to blend (combine) thepixels that we are currently rasterizing (so-called source pixels) with the pixels that were previously rasterized to theback buffer (so-called destination pixels).
                    一开始轻视了这段话,结果纠结了半天


                    IP属地:四川45楼2013-06-10 00:20
                    收起回复


                      IP属地:四川46楼2013-06-10 00:23
                      回复
                        接下来目标是模版缓存,动态天空盒(PS天空盒真够难制作的),粒子系统,然后骨骼动画,这些先前多少有看过一些资料了,应该不难,不过LZ这段时间得期末考了= =


                        IP属地:四川47楼2013-06-10 00:30
                        回复
                          正如上面所说,混合需要根据物体的远近顺序,这造成了很大的不便
                          因此这几天在研究OIT
                          说看资料是SDK里面的OIT例子

                          由于这个例子是使用SDK公共框架,好几W行的代码= =
                          很大部分和OIT无关,看起来好吃力,但是大致方向如上,我把它写到自己的框架里面以后会另外开一帖说明,不过到那时候不知道会过了多久


                          IP属地:四川48楼2013-06-11 15:18
                          收起回复
                            DXUT框架没有使用effect11框架,各种繁琐,特别是更新HLSL里面的cbuffer变量的时候还要调用map和unmap函数,每个pass都要另外获取,看了常规的方法我才体会到effect11框架的优势


                            IP属地:四川49楼2013-06-12 16:40
                            收起回复
                              2025-09-05 10:19:20
                              广告
                              不感兴趣
                              开通SVIP免广告
                              另外说一下网上的许多教程,几乎都很喜欢把不同效果的开关分成一大堆tech,我建议把hlsl里面的开关和C++变量联系起来,
                              例如
                              这样就可以在C++里面轻松更改特效的开关了,而不是选择tech来更改特效的开关


                              IP属地:四川50楼2013-06-12 16:46
                              回复