opengl es 颜色和着色

原创 2017年07月17日 23:43:45

上一节介绍了opengl es着色器原理和过程
我们对着色器原理和过程有了较为详细的理解,并且重点讲解了使用顶点着色器来实现opengl基本图元(点,直线,三角形)的位置,那么本节讲解opengl es对颜色的绘制。

三角形扇:
之前讲解如果想描述一个长方形可以用两个三角形来描述,比如:
// Triangle 1
-0.5f, -0.5f,
0.5f, 0.5f,
-0.5f, 0.5f,
// Triangle 2
-0.5f, -0.5f,
0.5f, -0.5f,
0.5f, 0.5f,
。。。。
很容易发现有很多坐标重复的问题,特别是复杂图形这样组成坐标的数组里有大量的数据冗余,为了解决这个问题提出了三角形扇的概念。如下图:
这里写图片描述
我们在桌子中间引入一个点(0,0)即1位置作为起始点,使用相邻两个顶点创建第一个三角形,接下来的每个顶点都会创建一个三角形,围绕起始点按照扇形展开,当最后重复第二个点时我们知道绘制完成。坐标位置数组也变成如下:

    /*
        float[] tableVerticesWithTriangles = {
            // Triangle Fan
               0,     0,            
            -0.5f, -0.5f,             
             0.5f, -0.5f,
             0.5f,  0.5f,
            -0.5f,  0.5f,            
            -0.5f, -0.5f,

            // Line 1
            -0.5f, 0f, 
             0.5f, 0f,

            // Mallets
            0f, -0.25f,
            0f,  0.25f 
        };*/

在本例AirHockeyRenderer的onDrawFrame中,代码如下:

 /**
     * OnDrawFrame is called whenever a new frame needs to be drawn. Normally,
     * this is done at the refresh rate of the screen.
     */
    @Override
    public void onDrawFrame(GL10 glUnused) {
        // Clear the rendering surface.
        glClear(GL_COLOR_BUFFER_BIT);

        // Draw the table.        
        glDrawArrays(GL_TRIANGLE_FAN, 0, 6);

        // Draw the center dividing line.        
        glDrawArrays(GL_LINES, 6, 2);

        // Draw the first mallet.        
        glDrawArrays(GL_POINTS, 8, 1);

        // Draw the second mallet.
        glDrawArrays(GL_POINTS, 9, 1);
    }

glDrawArrays(GL_TRIANGLE_FAN, 0, 6);指定用6个坐标值绘制三角形扇。
颜色属性:
我们要为每个顶点增加颜色属性代码如下:

       //
        // Vertex data is stored in the following manner:
        // 
        // The first two numbers are part of the position: X, Y
        // The next three numbers are part of the color: R, G, B
        //
        float[] tableVerticesWithTriangles = {   
            // Order of coordinates: X, Y, R, G, B

            // Triangle Fan
               0f,    0f,   1f,   1f,   1f,         
            -0.5f, -0.5f, 0.7f, 0.7f, 0.7f,            
             0.5f, -0.5f, 0.7f, 0.7f, 0.7f,
             0.5f,  0.5f, 0.7f, 0.7f, 0.7f,
            -0.5f,  0.5f, 0.7f, 0.7f, 0.7f,
            -0.5f, -0.5f, 0.7f, 0.7f, 0.7f,

            // Line 1
            -0.5f, 0f, 1f, 0f, 0f,
             0.5f, 0f, 1f, 0f, 0f,

            // Mallets
            0f, -0.25f, 0f, 0f, 1f,
            0f,  0.25f, 1f, 0f, 0f
        };

可以看到为每个顶点增加了三个分量坐标分别对应颜色的红,绿,蓝分量,每个分量值在0-1范围。
打开simple_fragment_shader.glsl和simple_vertex_shader.glsl我们发现里面没有了uniform属性而是varying。varying的意思就是把给他的值进行混合,比如在第一个顶点是红色,第二个顶点是绿色则使用varying后的效果就是组成第一第二顶点连线的直线离第一个顶点越近越呈现红色,直线离第二个点越近越呈现绿色,而且这是一种平滑按比例呈现的效果,用公式表达如下:
这里写图片描述
这个公式是应用于每个颜色分量的。如下图是从红到绿的直线,
这里写图片描述
则线上各个颜色分量如下图
这里写图片描述
这里写图片描述

上面是直线按照线性比例来实现这种颜色的平滑变化,如果是三角形则是按照构成三角形面积的分量,原理相似。
值得注意的是在代码上引入了 private static final int STRIDE =
(POSITION_COMPONENT_COUNT + COLOR_COMPONENT_COUNT) * BYTES_PER_FLOAT;因为我们坐标和颜色使用的是同一个缓冲器(这样有利于节省内存,性能)所以我们需要用STRIDE 来表示内存字节偏移量。所以在
onSurfaceCreated里面指定位置的时候使用了这个偏移量
glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT,
false, STRIDE, vertexData);指定颜色的时候也使用了这个偏移量STRIDE ,

vertexData.position(POSITION_COMPONENT_COUNT);        
        glVertexAttribPointer(aColorLocation, COLOR_COMPONENT_COUNT, GL_FLOAT, 
            false, STRIDE, vertexData);  

本节我们不在使用uniform故在onDrawFrame里面也不需要glUniform4f方法。同时我们也已经把顶点数据和颜色关联起来了,故只需要glDrawArrays方法就能搞定。
本文代码路径:
https://github.com/pangrui201/OpenGlesProject/tree/master/OpenGlesProject_lesson3

在 opengl 中画出三角形并用 shader 改变颜色

/* glew.h 源代码中的一些宏定义 typedef unsigned int GLenum; typedef unsigned int GLbitfield; typedef unsigned ...
  • liqiangzju
  • liqiangzju
  • 2016-12-17 20:58:00
  • 1009

android opengl es基本操作,画线,三角形,正方形,颜色设置

上篇文章讲了opengl es的基本知识,GLSurfaceView的创建,画点等内容,这篇文章将opengl es另外的一些基本操作,比如画线,画三角形,正方形等,以及这些例子中涉及到了相关的知识点...
  • u012761326
  • u012761326
  • 2017-02-21 14:32:33
  • 2554

Android OpenGL ES顶点坐标、纹理贴图坐标设置

做纹理贴图的时候具体的贴图坐标是如何设置纠结了很长时间,下面把关于顶点坐标和贴图坐标的设置xian...
  • zhangjikuan
  • zhangjikuan
  • 2014-04-07 20:58:36
  • 3707

OpenGL ES 2.0——顶点着色器Vertex Shader

在上篇文章中,我们提到了OpenGL ES 2.0中的两个非常重要的着色器,它们分别是顶点着色器和片元着色器,那么我们接下来的学习内容就从这两个着色器开始。在此之前,我们可以先来看一下OpenGL E...
  • linshuhe1
  • linshuhe1
  • 2016-04-06 18:13:44
  • 5149

openGL es2.0 创建颜色球

创建带有颜色的球体: 一、Java代码: package com.gzdxid.utils; import java.nio.ByteBuffer; import java.nio.ByteOr...
  • sh15285118586
  • sh15285118586
  • 2015-01-23 14:31:52
  • 688

OpenGL ES 学习教程(十五) 从 颜色缓冲区(FBO的颜色附着)中 读取颜色数据 保存到图片(FreeImage)

GL中提供读取像素数据的API glReadPixels,方便实现游戏中截屏功能。
  • cp790621656
  • cp790621656
  • 2016-12-07 02:39:47
  • 1728

Android OpenGL ES学习笔记之添加颜色

一、分类 添加颜色的种类有两种 - Flat coloring 单色 - Smooth coloring 平滑着色 单色 顾命思义就是一...
  • qq_31530015
  • qq_31530015
  • 2016-08-10 10:27:52
  • 2067

Learn OpenGLES:颜色渐变

这一贴,是继上一贴的补充。主要介绍,Shader的顶点属性数组(即顶点有多个属性)的情况,以及Shader是如何对顶点渲染颜色的。 我们将以简单的 长方形为例, 并在最后讨论当手机横竖屏时,长方形显示...
  • jinghouxiang
  • jinghouxiang
  • 2015-07-26 13:35:16
  • 885

【Android开发学习11】Android OpenGL ES 颜色

一、基础知识: 1.平滑着色(Smooth coloring):   将多个顶点的不同颜色混合在一起,创建出漂亮的色彩混合。 2.单调着色:   给图形涂上一种固定单一的颜色。 ...
  • ypist
  • ypist
  • 2013-02-20 15:27:08
  • 2729

Android OpenGL ES(二)----平滑着色

直线或者三角形上的每个片段混合后的颜色可以用一个varying生成。我们不仅能混合颜色,还可以给varying传递任何值,OpenGL会选择属于那条直线的两个值,或者属于那个三角形的三个值,并平滑地在...
  • liyuanjinglyj
  • liyuanjinglyj
  • 2015-06-22 19:53:38
  • 2703
收藏助手
不良信息举报
您举报文章:opengl es 颜色和着色
举报原因:
原因补充:

(最多只允许输入30个字)