前言
在光栅扫描显示器等设备上,所有图形的显示都归结为按照图形的描述将显示设备上的光栅像素点亮。为了输出一个像素,需要将该像素的坐标和颜色信息转换成输出设备的相应指令,根据指令在指定的屏幕位置上开启(接通)电路(电子束),将该位置上的显示单元器件发亮。基本图元显示问题就是根据基本图元的描述信息来生成像素组合。 ——《计算机图形学基础(OpenGL版)》
本系列文章主要介绍根据描述来生成基本图元的算法,例如两点生成直线。
这篇文章中我们主要实现基础的一个 OpenGL 代码框架来为我们之后的直线或者其他图形生成来做准备。如果你还完全不懂 OpenGL ,那么可以参考本博客站中的 OpenGL 学习记录。
在很多介绍这些基本算法的文章或者书中,要么是 OpenGL 伪代码,要么是使用命令行来绘制(毕竟算法才是本体),现代 OpenGL 中已经没有了直接操作像素的方法 SetPixel()
(使用 OpenGL 3.0+ 和 GLEW , GLFW),所以我们使用了纹理来代替。我们将纹理覆盖在窗口,然后通过修改纹理的数据来达到类似于设置像素的结果。
基础框架的 Shader 代码极为简单:
1 | //File Name : vertexShader.glsl |
编译和链接此 Shader 程序的代码暂且不提,之后可以在文末下载。我们主要来看看我们实现 SetPixel
方法的过程。
我们的纹理将使用我们自己定义的一个数组,如下:
1 | /* |
这是我们 Texture 类的声明,它共包括四个方法,构造方法,更新,绑定和我们所需要的 SetPixel
,在构造方法中我们接收纹理的 width 和 height 参数,并初始化 data 。
1 | width = w; |
同时也初始化纹理:
1 | glGenTextures(1, &ID); |
我们的纹理类型为 GL_RGB 三通道,所以 data 的大小应该为 w h 3 。
在 Use()
方法中我们绑定纹理,在 UpdateTexture
中我们使用 data 加载纹理:
1 | void Use() { |
事实上这几个方法都是为 SetPixel()
服务 ,SetPixel()
方法中我们修改 data 数据后调用 Use
和 UpdateTexture()
。SetPixel
方法接受要修改的像素坐标以及要设置的颜色:
1 | void SetPixel(int w, int h, unsigned char r, unsigned char g, unsigned char b) { |
现在,我们创建这么一个简单的 SetPixel 方法,在 OpenGL 的窗口中我们调用这个纹理,并生成一条直线,完整的 main 文件代码如下:
1 |
|
最终效果如下:
完整代码:GraphicsAlgorithm