c++实现软光栅(一)软光栅基础功能/代码层级

初衷

LearnOpenGL的教程看了很多遍,基本熟悉了对OpenGL API的调用,熟悉了顶点到像素点的绘制过程,以及不同的坐标系的效果,旋转矩阵的作用等。但想要深入了解图形API的内部渲染原理,得自己实现一遍才能有更清晰的体会,脱离GPU,用CPU实现绘制。这个项目旨在:
1.熟练c++语法;
2.熟悉图形渲染管线过程;
3.熟悉基础矩阵变换;
本小白的理解能力有限,希望错误的地方,读者可以帮忙指出来,共同讨论~

参考

[1]闫令琪大神的图形学课
[2]杨超大大的项目,放上大佬的某乎链接与项目链接github
[3]LearnOpenGL网站的知识

基础功能/代码层级

期待能实现简单立方体的绘制(纹理+光照+视图变换),球体的绘制,模型的读取。
然后我也不知道哪天能写完。。。代码层级?首先先画个三角形出来吧:

三角形的光栅化

OpenGL渲染流程

手撕光栅化流程代码的原因,就是想深入理解OpenGL渲染管线的具体细节。在写前,最好理清楚大致的pipeline流程,而不至于迷失在架构上。
LearnOpenGL网站经典的管线过程图
配置好OpenGL上下文(窗口)后,将程序员定义的顶点数据发送给顶点着色器,顶点着色器中将传入的坐标利用几个坐标系转换矩阵进行变换(主要是Model,View,Projection这三种矩阵),得到的坐标信息再经过Viewport函数转换为屏幕上的对应位置,这样得到的位置数据再传入光栅器进行光栅化(这里就是我们要手撕代码自己实现的重点之一)生成对应的片元。光栅化后的像素点信息传入片元着色器计算最终颜色,然后再进行深度测试模板测试,如果一个片元通过所有的测试,就可以被直接绘制到帧缓存中了。
P.S.一个“片元”可以被视为一个“候选的像素”,因为片元着色器计算完片元的像素值后,该片元可能在后面的深度测试模板测试中被遮挡住,所以也可能不绘制。
下面放一张我自己制的比较好理解的图。

窗口的调用

本项目就简化对窗口调用部分,使用visual studio的win32项目的窗口。简单理解了win32窗口调用与绘制的关系,就可以上手撸OpenGL管线了。

ATOM				MyRegisterClass(HINSTANCE hInstance);//设置窗口类属性
BOOL				InitInstance(HINSTANCE, int);//创建一个全局窗口实例,为后文的窗口操作准备
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);//消息回调函数,对窗口的操作都在这里完成
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);
LunaScene* scene;
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPTSTR    lpCmdLine,
                     _In_ int       nCmdShow)//win32项目的入口函数,就类似控制台程序的main()函数

因为OpenGL的管线操作,就是一系列的流程,顶点变换,光栅化,片元裁剪等都有自己的顺序,所以我们在scene类中定义顶点vertex,方便管理对顶点的操作(比如顶点坐标的各种变换,顶点属性的存储)。场景scene最好是全局的,方便控制。
在InitInstance()函数中,初始化场景。
在WndProc()函数中,通过键盘,鼠标等改变顶点坐标,实现对场景的控制。

class LunaScene;//场景类,内含对目标物体的属性,以及各种操作的函数
class Lmesh;  //网格类,存储一个具体目标的属性;
class LMatrix;//矩阵类,坐标变换的基础

添加双缓冲区,设置viewport部分

为了避免闪烁,在WndProc的WM_CREATE函数中创建了后备缓冲区,句柄是hdc_back_buffer,在WM_PAINT中将场景scene绘制到后备缓冲区,再将缓冲区内容调到屏幕上。

因为是对简单的三角形初始化,我直接给顶点赋值(0.0,0.5),(0.5,-0.5),(-0.5,-0.5),跳过了乘以MVP矩阵的构建(but出来混还是得还的- -后面还要加上)和裁剪坐标系,只要对顶点乘以viewport变换矩阵就可以了。
红宝书的图
小白我做的图
由上面两图可见,光栅化前要对标准化的设备坐标(-1.0-1.0)转换到屏幕的像素点坐标,比如该项目定义的(800,600)中去。
这里,要构建viewport转换矩阵,然后左乘到坐标向量上去,就完成转换了。

三角形光栅化

该项目的光栅化采用基础的扫描线法(小白懒 没调研其他的更快的方法)。
并不难,考虑清楚三角形的形状,避免遗漏一些形状。
具体三角形的扫描光栅化,这篇讲的比较细
各种三角形
在这里插入图片描述
考虑好各种三角形之后,就可以具体进行扫描光栅化了。举一个栗子,就上图一个普通的平底三角形而言。执行从y0到y1的逐行绘制。每一行都要计算XL与XR。

下一篇记录对鼠标键盘的消息响应,以显示立方体在屏幕上的显示结果。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值