OpenGL ES 2.0 for Android

1、了解OpenGL着色语言(OpenGL Shading Language)中的三种变量(uniform,attribute和varying) 

①、uniform:是由程序传入给(vertex和fragment)shader的变量,只能使用,不能修改。
            如果uniform变量在vertex和fragment两者之间声明方式完全一样,则它可以在vertex和fragment共享使用。(相当于一个被vertex和fragment shader共享的全局变量)。
            通过函数glUniform**()来赋值。
uniform变量一般用来表示:变换矩阵(viewProjMatrix),材质(material),光照参数(light)和颜色(color)等信息。
②、attribute: 只在vertex shader,不在fragment shader
                        通过函数glBindAttribLocation()、glVertexAttribPointer()来绑定数据和赋值。
attribute变量一般用来表示:一些顶点的数据,如:顶点坐标(vertex),法线(normal),纹理坐标(texcoord),顶点颜色(vertex color)等。
③、varying: vertex和fragment shader之间传递数据。vertex改变,fragment变换。
                        varying变量在vertex和fragment shader二者之间的声明必须是一致。

2、解读ShaderHelper(着色器助手类)  

    编译(compileVertexShader和compileFragmentShader)--->链接(linkProgram)--->验证(validateProgram)

编译

/**
           * 编译着色器
           * @param type                          着色器类型
           * @param shaderCode                     着色器代码
           * @return
           */
          private static int compileShader(int type, String shaderCode){
                   int shaderObjectId = glCreateShader(type);
                   
                   if(shaderObjectId == 0){
                              if(LoggerConfig.ON){
                                        Log.w(TAG, "Coult not create new Shader");
                              }
                              return 0;
                   }
                   
                   glShaderSource(shaderObjectId, shaderCode);
                   
                   glCompileShader(shaderObjectId);
                   
                   int[] compileStatus = new int[1];
                   glGetShaderiv(shaderObjectId, GL_COMPILE_STATUS, compileStatus, 0);
                   
                   if(LoggerConfig.ON){
                              Log.v(TAG, "Result of compiling source:"+"\n"+shaderCode+"\n"+glGetShaderInfoLog(shaderObjectId));
                   }
                   
                   if(compileStatus[0] == 0){
                              glDeleteShader(shaderObjectId);
                              if(LoggerConfig.ON){
                                        Log.w(TAG, "Compilation of shader failed");
                              }
                              return 0;
                   }
                   
                   return shaderObjectId;
          }


 

链接

/**
           * 链接程序
           * @param vertexShaderId                                     顶点着色器Id
           * @param fragmentShaderId                         碎片着色器Id
           * @return
           */
          public static int linkProgram(int vertexShaderId, int fragmentShaderId){
                   int programObjectId = glCreateProgram();
                   
                   if(programObjectId == 0){
                              if(LoggerConfig.ON){
                                        Log.w(TAG, "Could not create new Program");
                              }
                                        return 0;
                   }
                   
                   // 附上着色器
                   glAttachShader(programObjectId, vertexShaderId);
                   glAttachShader(programObjectId, fragmentShaderId);
                   
                   // 链接
                   glLinkProgram(programObjectId);
                   
                   int[] linkStatus = new int[1];
                   glGetProgramiv(programObjectId, GL_LINK_STATUS, linkStatus, 0);
                   
                   if(LoggerConfig.ON){
                              Log.v(TAG, "Results of linking program:\n"+glGetProgramInfoLog(programObjectId));
                   }
                   
                   if(linkStatus[0] == 0){
                              glDeleteProgram(programObjectId);
                              if(LoggerConfig.ON){
                                        Log.v(TAG, "Linking of program failed");
                              }
                              return 0;
                   }
                   
                   return programObjectId;
          }



验证

/**
           * 验证程序
           * @param programObjectId                          链接后的程序Id
           * @return
           */
          public static boolean validateProgram(int programObjectId){
                   glValidateProgram(programObjectId);
                   
                   int[] validateSatus = new int[1];
                   glGetProgramiv(programObjectId, GL_VALIDATE_STATUS, validateSatus, 0);
                   Log.v(TAG, "Result of validating program:\n"+glGetProgramInfoLog(programObjectId));
                   
                   return validateSatus[0] != 0;
          }





3、开始使用opengl es程序

。。。

4、添加细节纹理(loadTexture

、创建纹理助手类(TextureHelper

/**
         * 加载纹理信息
         * @param context                                            上下文对象
         * @param resourceId                                  资源Id
         * @return
         */
        public static int loadTexture(Context context, int resourceId){
               int[] textureObjectId = new int[1];
              
               // 分配一个纹理对象Id
               glGenTextures(1, textureObjectId, 0);
              
               if(textureObjectId[0] == 0){
                       if(LoggerConfig.ON){
                               Log.w(TAG, "Could not generate a new OpenGL Texture Object");
                       }
                       return 0;
               }
              
               // 加载图片资源  绑定纹理数据
               BitmapFactory.Options o = new BitmapFactory.Options();
               o.inScaled = false;
              
               Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId, o);
              
               if(bitmap == null){
                       glDeleteTextures(resourceId, textureObjectId, 0);
                       if(LoggerConfig.ON){
                               Log.w(TAG, "Resource ID "+resourceId+" could not be decoded");
                       }
                       return 0;
               }
              
               // 绑定 纹理号 到 纹理目标
               glBindTexture(GL_TEXTURE_2D, textureObjectId[0]);
              
               // 设置纹理参数
               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
              
               // 生成纹理
               texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
              
               bitmap.recycle();
              
              
               glGenerateMipmap(GL_TEXTURE_2D);
              
               // 解除绑定
               glBindTexture(GL_TEXTURE_2D, 0);
              
               // 返回纹理对象标识
               return textureObjectId[0];
        }



②、编写texture_vertex_shader.glsl

uniform mat4 u_Matrix;
attribute vec4 a_Position;
attribute vec2 a_TextureCoordinates;
varying vec2 v_TextureCoordinates;
void main()
{
        v_TextureCoordinates = a_TextureCoordinates;
        gl_Position = u_Matrix * a_Position;
}



③、编写texture_fragment_shader.glsl

precision mediump float;
uniform sampler2D u_TextureUnit;
varying vec2 v_TextureCoordinates;
void main()
{
        gl_FragColor = texture2D(u_TextureUnit, v_TextureCoordinates);
}


 

④、创建VertexArray类

public class VertexArray extends Constants{
       
        private final FloatBuffer floatBuffer;
       
        public VertexArray(float[] vertexData) {
               // TODO Auto-generated constructor stub
               floatBuffer = ByteBuffer
                               .allocateDirect(vertexData.length * BYTES_PER_FLOAT)
                               .order(ByteOrder.nativeOrder())
                               .asFloatBuffer()
                               .put(vertexData);
        }
       
        public void setVertexAttribPointer( int dataOffset, int attributeLocation, int componentCount, int stride) {
                       floatBuffer.position(dataOffset);
                      glVertexAttribPointer(attributeLocation, componentCount, GL_FLOAT, false, stride, floatBuffer);
                       glEnableVertexAttribArray(attributeLocation);
                       floatBuffer.position(0);
        }
 
}



⑤、准备工作(数据,绑定,绘制)

package com.opengles.android.objects;
 
import static android.opengl.GLES20.*;
 
import com.opengles.android.Constants;
import com.opengles.android.data.VertexArray;
import com.opengles.android.programs.TextureShaderProgram;
 
public class Table extends Constants{
       
        private static final int POSITION_COMPONENT_COUNT = 2;
        private static final int TEXTURE_COORDINATES_COMPONENT_COUNT = 2;
        private static final int STRIDE = (POSITION_COMPONENT_COUNT
        + TEXTURE_COORDINATES_COMPONENT_COUNT) * BYTES_PER_FLOAT;
       
        private static final float[] VERTEX_DATA = {
               // Order of coordinates: X, Y, S, T
               // Triangle Fan
               0f, 0f, 0.5f, 0.5f,
               -0.5f, -0.8f, 0f, 0.9f,
               0.5f, -0.8f, 1f, 0.9f,
               0.5f, 0.8f, 1f, 0.1f,
               -0.5f, 0.8f, 0f, 0.1f,
               -0.5f, -0.8f, 0f, 0.9f };
       
        private VertexArray vertexArray;
 
        public Table() {
               vertexArray = new VertexArray(VERTEX_DATA);
        }
       
        public void bindData(TextureShaderProgram textureProgram) {
               vertexArray.setVertexAttribPointer(0,        textureProgram.getPositionAttributeLocation(), POSITION_COMPONENT_COUNT, STRIDE);
               vertexArray.setVertexAttribPointer(POSITION_COMPONENT_COUNT, textureProgram.getTextureCoordinatesAttributeLocation(), TEXTURE_COORDINATES_COMPONENT_COUNT, STRIDE);
        }
       
        public void draw() {
               glDrawArrays(GL_TRIANGLE_FAN, 0, 6);
        }
       
}



⑥、添加纹理着色器程序

package com.opengles.android.programs;
 
import static android.opengl.GLES20.*;
 
import com.opengles.android.R;
 
import android.content.Context;
 
public class TextureShaderProgram extends ShaderProgram {
 
        // Uniform locations
        private final int uMatrixLocation;
        private final int uTextureUnitLocation;
        // Attribute locations
        private final int aPositionLocation;
        private final int aTextureCoordinatesLocation;
 
        public TextureShaderProgram(Context context) {
               super(context, R.raw.texture_vertex_shader,
                               R.raw.texture_fragment_shader);
               // Retrieve uniform locations for the shader program.
               uMatrixLocation = glGetUniformLocation(program, U_MATRIX);
               uTextureUnitLocation = glGetUniformLocation(program, U_TEXTURE_UNIT);
               // Retrieve attribute locations for the shader program.
               aPositionLocation = glGetAttribLocation(program, A_POSITION);
               aTextureCoordinatesLocation = glGetAttribLocation(program,
                               A_TEXTURE_COORDINATES);
        }
 
        public void setUniforms(float[] matrix, int textureId) {
               // Pass the matrix into the shader program.
               glUniformMatrix4fv(uMatrixLocation, 1, false, matrix, 0);
               // Set the active texture unit to texture unit 0.
               glActiveTexture(GL_TEXTURE0);
               // Bind the texture to this unit.
               glBindTexture(GL_TEXTURE_2D, textureId);
               // Tell the texture uniform sampler to use this texture in the shader by
               // telling it to read from texture unit 0.
               glUniform1i(uTextureUnitLocation, 0);
        }
       
        public int getPositionAttributeLocation() {
               return aPositionLocation;
        }
 
        public int getTextureCoordinatesAttributeLocation() {
               return aTextureCoordinatesLocation;
        }
 
}



⑦、真正绘制纹理

// 加载纹理程序
textureProgram = new TextureShaderProgram(context);
// 加载纹理数据
texture = TextureHelper.loadTexture(context, R.drawable.air_hockey_surface);
// 设置纹理程序,并使用
textureProgram.useProgram();
textureProgram.setUniforms(projectionMatrix, texture);
// 绑定纹理程序,并绘制
table.bindData(textureProgram);
table.draw();


 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and The Pragmatic Programmers, LLC was aware of a trademark claim, the designations have been printed in initial capital letters or in all capitals. The Pragmatic Starter Kit, The Pragmatic Programmer, Pragmatic Programming, Pragmatic Bookshelf, PragProg and the linking g device are trademarks of The Pragmatic Programmers, LLC. Every precaution was taken in the preparation of this book. However, the publisher assumes no responsibility for errors or omissions, or for damages that may result from the use of information (including program listings) contained herein. Our Pragmatic courses, workshops, and other products can help you and your team create better software and have more fun. For more information, as well as the latest Pragmatic titles, please visit us at http://pragprog.com. The Android robot is reproduced from work created and shared by Google and is used according to terms described in the Creative Commons 3.0 Attribution License (http://creativecommons.org/licenses/by/3.0/us/legalcode). The unit circle image in Figure 43, from http://en.wikipedia.org/wiki/File:Unit_circle.svg, is used according to the terms described in the Creative Commons Attribution-ShareAlike license, located at http://creativecommons.org/licenses/by-sa/3.0/legalcode. Day skybox and night skybox courtesy of Jockum Skoglund, also known as hipshot, hipshot@zfight.com,http://www.zfight.com. The image of the trace capture button is created and shared by the Android Open Source Project and is used according to terms described in the Creative Commons 2.5 Attribution License.
In Pro OpenGL ES for Android, you'll find out how to harness the full power of OpenGL ES, and design your own 3D applications by building a fully-functional 3D solar system model using Open GL ES! OpenGL has set the standard for 3D computer graphics, and is an essential aspect of Android development. This book offers everything you need to know, from basic mathematical concepts to advanced coding techniques. You'll learn by building a fascinating 3D solar system simulator! After introducing Open GL ES, Pro OpenGL ES for Android explains the basics of 3D math and then orients you to the native Android 3D libraries you'll be using in your own 3D games and the solar system project you'll build using this book. Through the solar system example project, you'll learn how to incorporate a variety of graphic and animation techniques into your applications. You will also discover how the full spectrum of 3D development that awaits, with topics such as lighting, texture-mapping, modeling, shaders, blending modes, and several more advanced concepts. By the time you finish Pro OpenGL ES for Android, you'll have learned all the skills you'll need to build your own incredible 3D applications, based on one of the most powerful 3D libraries available. What you'll learn * The basics of 3D mathematics, and how they are applied in the OpenGL library * How to design and build your 3D worlds * To create 2D interfaces within the 3D world * To develop animation and 3D movement * How to implement 3D shading, coloring, and texturing * The differences between OpenGL and other 3D toolkits * To build a fully-functional 3D solar system simulator using OpenGL ES Who this book is for Experienced Android programmers who want to enter the 3D world of OpenGL ES programming. Table of Contents * Introduction to OpenGL ES and Our 3D Solar System Project * Generating a Basic OpenGL Program * Getting Past the 3D Math * Shading, Lighting and Colors * Materials and Textures * Animation * Creating a User Interface * Blending Modes, Buffer Objects, and Other Cool Stuff * Latest Features of OpenGL ES * Ray Tracing, Hidden Surfaces, and Other Advanced Topics Appendix A: APIs

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qiuchenlong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值