设为首页 加入收藏

TOP

OpenGL ES学习笔记(二)——平滑着色、自适应宽高及三维图像生成(一)
2017-10-12 10:07:22 】 浏览:8305
Tags:OpenGL 学习 笔记 平滑 着色 适应 高及 三维 图像 生成

首先申明下,本文为笔者学习《OpenGL ES应用开发实践指南(Android卷)》的笔记,涉及的代码均出自原书,如有需要,请到原书指定源码地址下载。

      《Android学习笔记——OpenGL ES的基本用法、绘制流程与着色器编译》中实现了OpenGL ES的Android版HelloWorld,并且阐明了OpenGL ES的绘制流程,以及编译着色器的流程及注意事项。本文将从现实世界中图形显示的角度,说明OpenGL ES如何使得图像在移动设备上显示的更加真实。首先,物体有各种颜色的变化,在OpenGL ES中为了生成比较真实的图像,对图像进行平滑着色是一种常见的操作。其次,移动设备存在横竖屏的切换,进行图像显示时,需要根据屏幕方向考虑屏幕的宽高比,使图像不因屏幕切换而变形。最后,现实中的物体都是三维的,我们观察物体都带有一定的视角,因此需要在OpenGL ES实现三维图像的显示。本文主要包括以下内容:

  1. 平滑着色
  2. 自适应宽高
  3. 三维图像生成


 

一、平滑着色

      平滑着色是通过在三角形的每个点上定义不同的颜色,在三角形的表面混合这些颜色得到的。那么,如何用三角形构成实际物体的表面呢?如何混合定义在顶点出的不同颜色呢?

      首先引入三角形扇的概念。以一个中心顶点作为起始,使用相邻的两个顶点创建第一个三角形,接下来的每个顶点都会创建一个三角形,围绕起始的中心点按扇形展开。为了使扇形闭合,只需在最后重复第二个点。在OpenGL中通过GL_TRIANGLE_FAN指定数据代表三角形扇。

glDrawArrays(GL_TRIANGLE_FAN, 0, 6);

      上述代码中,glDrawArrays的参数列表为:

// C function void glDrawArrays ( GLenum mode, GLint first, GLsizei count )

    public static native void glDrawArrays(
        int mode,
        int first,
        int count
    );

      可知,0代表第一顶点的位置,6表示6个顶点绘制一个三角形扇。

      接下来会把每个点上的颜色定义为一个顶点属性,需要两部分的工作:(1)顶点数据;(2)着色器。《Android学习笔记——OpenGL ES的基本用法、绘制流程与着色器编译》中涉及到的顶点数据只有X/Y坐标,添加颜色属性,则在顶点坐标后增加了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,
};

      同样的,相比于上一篇中涉及到的顶点着色器,增加颜色属性。

attribute vec4 a_Position;  
attribute vec4 a_Color;

varying vec4 v_Color;

void main()                    
{                            
    v_Color = a_Color;
      
    gl_Position = a_Position;    
    gl_PointSize = 10.0;          
}

      这里需要说明的是varying变量,varying变量是平滑的关键。以直线AB为例,如果顶点A的a_Color是红色,顶点B的a_Color是绿色,那么,从A到B,将会是红色和绿色的混合。越接近顶点A,混合后的颜色显得越红;越接近顶点B,混合后的颜色就显示越绿。至于混合的算法,采用最基本的线性插值就可以完成。

      在三角形表面混合时,与直线的线程插值相同,每个颜色在接近它的顶点处都是最强的,向其他顶点就会变暗,用比例确定每种颜色的相对权重,只是这里使用的是面积的比例,而不是线性插值所使用的长度。

      回到AirHockeyRenderer中,首先在onSurfaceCreated体现颜色属性。

aPositionLocation = glGetAttribLocation(program, A_POSITION);
aColorLocation = glGetAttribLocation(program, A_COLOR);

// Bind our data, specified by the variable vertexData, to the vertex
// attribute at location A_POSITION_LOCATION.
vertexData.position(0);
glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT, 
     false, STRIDE, vertexData);

glEnableVertexAttribArray(aPositionLocation);     
        
// Bind our data, specified by the variable vertexData, to the vertex
// attribute at location A_COLOR_LOCATION.
vertexData.position(POSITION_COMPONENT_COUNT);        
glVertexAttribPointer(aColorLocation, COLOR_COMPONENT_COUNT, GL_FLOAT, 
      false, STRIDE, vertexData);        

glEnableVertexAttribArray(aColorLocation);

      流程与《Android学习笔记——OpenGL ES的基本用法、绘制流程与着色器编译》中基本一致,只是添加了颜色属性。aColorLocation为颜色属性的位置,STRIDE为跨距,即tableVerticesWithTriangles数组中不仅包含顶点的坐标,还包含了颜色属性,因此在取顶点坐标时,需要跨越颜色属性。

      vertexData.position(POSITION_COMPONENT_

首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Android学习笔记--远程服务的使用 下一篇android 中listview之BaseAdapter..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目