美文网首页
二、OpenGL 2D绘制

二、OpenGL 2D绘制

作者: Johnny_Wu | 来源:发表于2021-07-22 14:41 被阅读0次

1、概述

下面我通过使用OpenGL绘制三角形,来解析OpenGL的绘制原理。

我们先来回顾下OpenGL的渲染管道流程:

顶点数据 -> 顶点着色器 -> 图元装配 -> 几何着色器 -> 光栅化 -> 片断着色器 -> 逐片断处理/测试与混合 -> 帧缓冲

简化掉不可操作的部分,渲染管道流程为:

顶点数据 -> 顶点着色器 -> 片断着色器 -> 帧缓冲

所以,使用OpenGL进行绘制,需提供用于输入的顶点数据和提供用于输出的帧缓存区。

通过调用下面的方法,就触发了OpenGL的这个渲染管道流程:

glDrawArrays(GL_TRIANGLES, 0, 3);
GL_TRIANGLES:图元装配阶段使用,表示这些顶点是用来组成三角形的
第三个参数:一个有3个顶点

思考:

glDrawArrays 第一个参数表示图元构造的形状,有GL_TRIANGLES(三角形)、GL_POINTS(点)、GL_LINES(线)。但就是没有四边形或多边形,为什么?

三个点一定只能画出一个面,超过三个点,绘制的图形就不一定只有一个面了。比如四个点,根据不同的连接方式,可以组成不同的图形,不能确定唯一的图形,所以没有多边形的绘制方式。要构造四边形,可以通过绘制两个三角形拼接成四边形。

2、输入部分

顶点数据:顶点坐标,顶点颜色,顶点法向量等。绘制三角形的话,只需要顶点坐标和顶点颜色。

顶点坐标:

image

OpenGL接收的x,y坐标都是介于[-1,1]之间。

本案例的顶点为:

const GLfloat vertices[] = {
    0.0f, 0.5f, 0.0f,
    -0.5f, -0.5f, 0.0f,
    0.5f, -0.5f, 0.0f 
  };

顶点着色器:

attribute vec4 Position;  // position of vertex
attribute vec4 SourceColor; // color of vertex

varying vec4 DestinationColor;

void main(void) {

  DestinationColor = SourceColor;

  gl_Position = Position;
}

是不是很简单,就那么几句,就构成了顶点着色器。这里可以对顶点数据进行加工处理,比如进行光照计算处理。本案例,我们不需要计算光照,保持上面代码就可以。

为顶点着色器传值:

顶点着色器定义两个作为输入变量,我们外部只需要把顶点值赋值给这两个变量就完成了传值:

attribute vec4 Position:接收顶点坐标值

attribute vec4 SourceColor:接收顶点颜色值

通过以下代码,得到上面两个变量:

_colorSlot = glGetAttribLocation(_glProgram, "SourceColor");
_positionSlot = glGetAttribLocation(_glProgram, "Position");

通过以下代码,给两个变量分别传入顶点坐标值和顶点颜色值

//顶点坐标
  const GLfloat vertices[] = {
    0.0f, 0.5f, 0.0f,
    -0.5f, -0.5f, 0.0f,
    0.5f, -0.5f, 0.0f 
  };
  // 给_positionSlot传递顶点坐标数据
  glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, 0, vertices);
  glEnableVertexAttribArray(_positionSlot);

  // 顶点颜色值
  const GLfloat Colors[] = {
    0,0,0,1, // 左下,黑色
    1,0,0,1, // 右下,红色
    0,0,1,1, // 左上,蓝色
  };
  // 取出Colors数组中的每个坐标点的颜色值,赋给_colorSlot
  glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, 0, Colors);
  glEnableVertexAttribArray(_colorSlot);

片元着色器:

varying lowp vec4 DestinationColor;
void main(void) {
//  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // must set gl_FragColor for fragment shader
  gl_FragColor = DestinationColor;
}

比顶点着色器还简单。在这里,我们可以改变顶点的颜色。本案例不需要改变定义颜色,保存默认就好。

片元着色器的输入变量为DestinationColor,这个值是顶点着色器传过来的:

varying vec4 DestinationColor;

void main(void) {
   //把顶点颜色值传给片元着色器
  DestinationColor = SourceColor;

  gl_Position = Position;
}

3、输出部分

帧缓冲区:

GLuint _frameBuffer; // 帧缓冲区
glGenFramebuffers(1, &_frameBuffer);
//设置为当前framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer);

上面定义了一个帧缓冲区,在glDrawArrays调用前,使用glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer)指定输出的帧缓冲区,那么OpenGL管道流程执行完成,就会把绘制的内容输出到指定的帧缓冲区。

渲染缓冲区:

这个可以不算OpenGL的内容了。对于OpenGL,把内容输出到帧缓冲区,就算完成了。加入渲染缓冲区,只是为了在界面把图形展示出来。

glGenRenderbuffers(1, &_colorRenderBuffer);
  // 设置为当前renderBuffer
glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer);
  //为color renderbuffer 分配存储空间
[_eaglContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:_eaglLayer];

  // FBO用于管理colorRenderBuffer,离屏渲染
glGenFramebuffers(1, &_frameBuffer);
  //设置为当前framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer);
  // 将 _colorRenderBuffer 装配到 GL_COLOR_ATTACHMENT0 这个装配点上
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorRenderBuffer);

上面会有把渲染缓冲区与具体的CALayer关联起来。更多的上下文代码,
请参考demo:https://github.com/wulang150/MyProject/tree/master/MyProject/Controller/TmpTestController/OpenGL

运行结果为:

image

如上图,我只设置了三个点的颜色,OpenGL自动帮我们填充了三角形内部的颜色,并且是通过渐变的方式填充。这是光栅化颜色插值。

4、更多OpenGL知识

OpenGL ES 2.0 (iOS)[01]: 一步从一个小三角开始

OpenGL ES 2.0 Programming Guide

相关文章

  • OpenGL ES概述

    OpenGL ES Android包含支持高性能2D和3D图形绘制开源库(OpenGL),尤其是OpenGL ES...

  • 二、OpenGL 2D绘制

    1、概述 下面我通过使用OpenGL绘制三角形,来解析OpenGL的绘制原理。 我们先来回顾下OpenGL的渲染管...

  • Core Graphics绘图

    Core Graphics入门IOS中使用Quartz 2D绘制虚线 Core Graphics与OpenGL的关...

  • OpenGL ES on iOS --- 2D纹理

    OpenGL ES on iOS --- 2D纹理 简介 纹理是用来丰富我们绘制物体细节的,它可以是一张2D图片(...

  • OpenGL ES 3.0纹理映射-绘制一张图片

    本篇博客了解一下2D纹理,并完成一个绘制显示一张图片的Renderer。 2D纹理 2D纹理是OpenGL ES中...

  • OpenGL基本概念(知识)

    OpenGL基本概念 基本概念与说明 基本概念 OpenGL是一个图形API,用来绘制三维物体(也可以是2D物体)...

  • 9、什么是 OpenGL、Quartz 2D?

    Quartz 2D是apple提供的基本图形工具库,只提供2D图形的绘制OpenGL是一个跨平台的图形开发库,适用...

  • OpenGL基础(一) 相关专业名词

    一、图形API框架简介 OpenGL OpenGL (Open Graphics Library) 用于渲染2D、...

  • OpenGL 学习笔记

    一. OpenGL,OpenGL ES,EGL区别(1)概念区别OpenGL:开源的,与平台无关的,用来渲染2D,...

  • 三、OpenGL 3D绘制

    1、三角形变金字塔 有了上面OpenGL绘制2D三角形的经验,大家可以想下,要绘制3D的图形,需要怎么做呢? 也许...

网友评论

      本文标题:二、OpenGL 2D绘制

      本文链接:https://www.haomeiwen.com/subject/wygemltx.html