OpenGL 学习系列--基础的绘制流程

这篇博客介绍了OpenGL的学习系列,重点是基础的绘制流程。内容涵盖内存拷贝、顶点着色器、光栅化技术、片段着色器以及编译OpenGL程序的步骤,包括编译着色器、创建OpenGL程序、验证程序和确定使用程序。文章以渲染管线为线索,解释了如何将顶点数据从Java层传递到Native层,以及顶点着色器和片段着色器如何处理数据生成最终颜色。
摘要由CSDN通过智能技术生成

事实上,随着显示技术的发展,渲染管线将不复存在了,顶点着色器和渲染管线统一被流处理器(Stream Processors)所取代。

但是目前手机上 OpenGL 还是使用渲染管线中,有了渲染管线,我们就可以完成点的形状绘制和着色两大问题了,接下来的工作也是围绕这条渲染管线开始的。

内存拷贝

当定义完了顶点坐标,并且明确了下一步:顶点坐标将要通过渲染管线进行一系列处理,那么接下来就是如何把顶点坐标传递给渲染管线了。

OpenGL 的实现是由显示设备厂商提供的,它作为本地系统库直接运行在硬件上。而我们定义的顶点 Java 代码是运行在虚拟机上的,这就涉及到了如何把 Java 层的内存复制到 Native 层了。

一种方法是直接使用JNI开发,直接调用本地系统库,也就是用 C++ 来开发 OpenGL,这种实现肯定要学会的。

另一种方法就是在 Java 层把内存块复制到 Native 层。

使用ByteBuffer.allocateDirect()方法就可以分配一块 Native 内存,这块内存不会被 Java 的垃圾回收器管理。

它的使用方法大致都一样,抽出公共的模板:

// 声明一个字节缓冲区 FloatBuffer
private FloatBuffer floatBuffer;
// 定义顶点数据
float[] vertexData = new float[16];
// FloatBuffer 初始化工作并放入顶点数据
floatBuffer = ByteBuffer
.allocateDirect(vertexData.length * Constant.BYTES_PRE_FLOAT)
.order(ByteOrder.nativeOrder())
.asFloatBuffer()
.put(vertexData);

allocateDirect方法分配了内存并指定了大小之后,下一步就是告诉 ByteBuffer 按照本地字节序组织它的内容。本地字节序是指,当一个值占用多个字节时,比如 32 位整型数,字节按照从最重要位到最不重要位或者相反顺序排列。

接下来asFloatBuffer方法可以得到一个反映底层字节的 FloatBuffer 类实例,避免直接操作单独的字节,而是使用浮点数。

最后,通过put方法就可以把数据从 Java 层内存复制到 Native 层了,当进程结束时,这块内存就会被释放掉。

顶点着色器

接下来可编程的部分了,定义着色器(Shader)程序。

使用不同的着色器对输入的图元数据执行计算操作,判断它们的位置、颜色,以及其他渲染属性。

首先是顶点着色器。

在渲染管线中传输的每个顶点坐标位置,OpenGL 都会调用一个顶点着色器来处理顶点相关的数据,这个处理过程可以很复杂,也可以很简单。

想要定义一个着色器程序,还要通过一种特殊的语言去编写:OpenGL Shading Language,简称GLSL.

GLSL语言类似于 C 语言或者 Java 语言,它的程序入口也是一个名为main的函数。关于 GLSL 的部分,完全可以单独写一篇博客了,暂时先不详细阐述。

下面就是一个简单的顶点着色器程序:

attribute vec4 a_Position;
void main()
{
gl_Position = a_Position;
gl_PointSize = 30.0;
}

着色器类似于一个函数调用的方式——数据传输进来,经过处理,然后再传输出去。

其中,gl_Positiongl_PointSize就是着色器中的特殊全局变量,它接收输入。

a_Position就是我们定义的一个变量,

  • 20
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值