本文由zhangbaochong原创,转载请注明出处http://www.cnblogs.com/zhangbaochong/p/5751111.html

由于开学就大四面临找工作了,为了整理下项目,最近又把上学期练手写的一个c++软光栅渲染demo拿出来重新改了改,稍微优化了一下,顺便增加了光照。虽然写的比较简单,但还是拿出来分享一下,希望能起个抛砖引玉的作用吧,也欢迎指点批评O(∩_∩)O~

  (ps :项目代码只有4000行左右,性能方面也比较渣,高性能的光栅渲染可以看空明大大的SALVIAhttp://www.cnblogs.com/lingjingqiu/)

1.主要模块功能

1.1数学库

  向量、矩阵的实现与变换(矩阵平移、旋转、转置、行列式、逆矩阵);

视角矩阵、投影矩阵和屏幕坐标转换矩阵;

  一些常用函数(插值、RGB颜色转UINT、角度弧度转换、求反射向量).

1.2后缓冲区

设置像素,我一开始采用SetPixel()函数,发现速度慢的不忍直视。后来改成用CreateDIBSections创建位图,直接向内存中写像素颜色值,完了后一块BitBlt到窗口就行了。

1.3模型标准

  由于之前一直在写directx11的代码,所以这里也采用标准d3d的坐标模型,左手系+world view proj三矩阵

1.4几何阶段

顶点从模型空间到世界空间到相机空间到齐次裁剪空间,对应的主要是三个矩阵world view proj,数学库中提供了相应方法。

图元装配,也就是将顶点以一定顺序组装成三角形,本项目中采用顶点索引的方式来组织顶点,并且三角形顺时针顺序对应的法线朝向外面。之所以规定好顺序,是为了法线方向的一致性,只有这样才能进行后面的背面消隐。

投影后的坐标再进行透视除法,让顶点坐标位于cvv中(x[-1,1],y[-1,1],z[0,1]),裁剪过后再将cvv坐标转化为屏幕中对应的坐标。

1.4三角形光栅化

线框模型使用的bresenham画线算法。

三角形光栅算法:http://blog.csdn.net/cppyin/article/details/6232453

填充三角形使用的扫描线。

1.5背面消隐

可以参考:http://blog.csdn.net/cppyin/article/details/6207206

1.6简单CVV裁剪

1.7支持纹理

  纹理uv坐标同d3d,纹理坐标寻址同d3d的wrap方式,贴图在物体表面重复,类似于我们设置桌面是图片的平铺方式。当坐标大于1时,通过去掉整数部分,根据得到的小数部分来得到纹理值;坐标小于0,则加上一个最小正数,让坐标大于0。

1.8简单光照

  phong光照模型,实现平行光、点光源与聚光灯三种。

1.9简单着色器

写了一个着色器类,有VS和PS两个函数对应顶点着色器和像素着色器,部分代码如下:

 VertexOut BoxShader::VS(const VertexIn& vin)
{
VertexOut out;
out.posH = vin.pos * m_worldViewProj; out.posTrans = vin.pos * m_world;
out.normal = out.normal * m_worldInvTranspose; out.color = vin.color;
out.tex = vin.tex; return out;
} ZCVector BoxShader::PS(VertexOut& pin)
{
//单位化法线
pin.normal.Normalize(); //纹理采样
ZCVector texColor = m_tex.Sample(pin.tex); //顶点到观察点向量
ZCVector toEye = (m_eyePos - pin.posTrans).Normalize(); //初始化颜色值全部为0
ZCVector ambient(.f, .f, .f, .f);
ZCVector diffuse(.f, .f, .f, .f);
ZCVector specular(.f, .f, .f, .f); //光源计算后得到的环境光、漫反射 、高光
ZCVector A, D, S; Lights::ComputeDirectionalLight(m_material, m_dirLight, pin.normal, toEye, A, D, S); ambient = ambient + A;
diffuse = diffuse + D;
specular = specular + S; //纹理+光照计算公式: 纹理*(环境光+漫反射光)+高光
ZCVector litColor = texColor * (ambient + diffuse) + specular; //最终颜色透明度使用漫反射光的透明度
litColor.w = m_material.diffuse.w * texColor.w; return litColor;
}

2.截图效果

2.1线框模型

2.2顶点色

2.3纹理+光照

图片本身是木纹材质,显得比较粗糙/(ㄒoㄒ)/~~

3.源码

项目托管到Github上了:https://github.com/zhangbaochong/Tiny3D

等有时间我会再优化一下,比如采用SIMD加速等等。最近应该没时间搞这个了,d3d最近都没怎么看,为了开学找工作得把算法数据结构再复习下!

开源一个简单的c++软光栅渲染器的更多相关文章

  1. 一个简单的AMD模块加载器

    一个简单的AMD模块加载器 参考 https://github.com/JsAaron/NodeJs-Demo/tree/master/require PS Aaron大大的比我的完整 PS 这不是一 ...

  2. 一个简单的基于 DirectShow 的播放器 2(对话框类)

    上篇文章分析了一个封装DirectShow各种接口的封装类(CDXGraph):一个简单的基于 DirectShow 的播放器  1(封装类) 本文继续上篇文章,分析一下调用这个封装类(CDXGrap ...

  3. 一个简单的基于 DirectShow 的播放器 1(封装类)

    DirectShow最主要的功能就是播放视频,在这里介绍一个简单的基于DirectShow的播放器的例子,是用MFC做的,今后有机会可以基于该播放器开发更复杂的播放器软件. 注:该例子取自于<D ...

  4. 哪种缓存效果高?开源一个简单的缓存组件j2cache

    背景 现在的web系统已经越来越多的应用缓存技术,而且缓存技术确实是能实足的增强系统性能的.我在项目中也开始接触一些缓存的需求. 开始简单的就用jvm(java托管内存)来做缓存,这样对于单个应用服务 ...

  5. cJSON: 一个用c写的一个简单好用的JSON解析器

    转自:http://blog.csdn.net/chenzhongjing/article/details/9188347 下载地址: http://sourceforge.net/projects/ ...

  6. 开源一个简单的react-native 菜单栏抽屉组件,带缩放效果

    效果如图所示,源码地址:https://github.com/pofabs/PoSideMenu

  7. 一个简单的C语言语法检查器的实现

    我自己的实现方法的核心过程:首先用一个非终结符代表所有要检查的程序代码,然后根据文法将这个整体的符号不断展开,以拼凑成按检查的程序的顺序排列的终结符序列,能成功说明语法正确,否则有错误. 关键词:分词 ...

  8. 一个简单有趣的Python音乐播放器

    (赠新手,老鸟绕行0.0) Python版本:3.5.2 源码如下: __Author__ = "Lance#" # -*- coding = utf-8 -*- #导入相应模块 ...

  9. 自己实现一个简单的网络音乐mp3播放器

    大繁至简,把思路搞清楚才是最重要的,如何去做依托于使用什么来实现这项功能 列出我使用的基本类 NSURLSessionDataTask 数据获取类 NSFileHandle 数据缓存和数据读取类 Au ...

随机推荐

  1. 无向图的最短路径算法JAVA实现(转)

    一,问题描述 给出一个无向图,指定无向图中某个顶点作为源点.求出图中所有顶点到源点的最短路径. 无向图的最短路径其实是源点到该顶点的最少边的数目. 本文假设图的信息保存在文件中,通过读取文件来构造图. ...

  2. 在Android中改动快捷方式的图标

    1)打开"res/drawable"-->复制一张icon2.jpg图片到该drawable目录,同一时候,也将复制icon2.jpg图片到bin/res/drawable. ...

  3. 使用notepad运行python

    Notepad++ 是一个开源的文本编辑器,功能强大而且使用方便,一般情况下,Notepad++作为代码查看器,很方便,但是每次要运行的时候,总是需要用右键打开其他的IDE来编译和运行,总有些不方便. ...

  4. hdu3622(二分+two-sat)

    传送门:Bomb Game 题意:给n对炸弹可以放置的位置(每个位置为一个二维平面上的点),每次放置炸弹是时只能选择这一对中的其中一个点,每个炸弹爆炸的范围半径都一样,控制爆炸的半径使得所有的爆炸范围 ...

  5. libevent book——event | Gaccob的博客

    libevent book——event | Gaccob的博客 libevent book——event 发表于 2013 年 2 月 22 日 由 gaccob 原文地址:http://www.w ...

  6. POJ 3458 Colour Sequence(简单题)

    [题意简述]:事实上题意我也没有特别看懂.可是依据它少许的题目描写叙述加上给的例子.就大胆的做了例如以下的推測: 就是说,如今给出一串字符s.然后紧接着给出可见的字符串visible还有隐藏的字符串h ...

  7. C#反射机制详解(转)

    两个现实中的例子:1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内脏的生理情况.这是如何做到的呢?B超是B型超声波,它可以透过肚皮通过向你体内发射B型超声波,当超声波遇到内脏壁的时 ...

  8. redis加入到Windows 服务

    1.cmd命令  安装命令: redis-server.exe --service-install redis.windows.conf --loglevel verbose  卸载命令:  redi ...

  9. MVC数据验证使用小结

    原文:MVC数据验证使用小结 描述:MVC数据验证使用小结 内容:display,Required,stringLength,Remote,compare,RegularExpression 本人最近 ...

  10. auto_ptr and scoped_ptr

    #include "boost/scoped_ptr.hpp" #include <iostream> #include <memory>//contain ...