zoukankan      html  css  js  c++  java
  • Android OpenGL ES 2.0 (六) 混合blending

    现在来看看的blending效果。

    blending分为Additive blending,Multiplicative blending和Interpolative blending。

    对应的方法分别为

    glBlendFunc(GL_ONE, GL_ONE),

    glBlendFunc(GL_DST_COLOR, GL_ZERO)和

    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

    现在就用Additive blending来写个例子。

    这里的GLSurfaceView要处理点击消息来开启和关闭blending效果,所以单独提取一个类。

    Test6SurfaceView.java

     1 package com.android.jayce.test;
     2 
     3 import android.content.Context;
     4 import android.opengl.GLSurfaceView;
     5 import android.view.MotionEvent;
     6 
     7 public class Test6SurfaceView extends GLSurfaceView
     8 {
     9     private Test6Renderer mRenderer;
    10     
    11     public Test6SurfaceView(Context context) {
    12         super(context);
    13         // TODO Auto-generated constructor stub
    14     }
    15     
    16     public boolean onTouchEvent(MotionEvent event)
    17     {
    18         if(event != null)
    19         {
    20             if(event.getAction() == MotionEvent.ACTION_DOWN)
    21             {
    22                 if(mRenderer != null)
    23                 {
    24                     queueEvent(new Runnable(){
    25 
    26                         @Override
    27                         public void run() {
    28                             // TODO Auto-generated method stub
    29                             mRenderer.switchMode();
    30                         }});
    31                     return true;
    32                 }
    33             }
    34         }
    35         return super.onTouchEvent(event);
    36     }
    37     
    38     public void setRenderer(Test6Renderer renderer)
    39     {
    40         mRenderer = renderer;
    41         super.setRenderer(renderer);
    42     }
    43     
    44 }

    Renderer里面开关blending效果在switchMode里。

    开启是:
                GLES20.glDisable(GLES20.GL_CULL_FACE);
                GLES20.glDisable(GLES20.GL_DEPTH_TEST);
                GLES20.glEnable(GLES20.GL_BLEND);
                GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE);

    关闭是:

         GLES20.glEnable(GLES20.GL_CULL_FACE);
                GLES20.glEnable(GLES20.GL_DEPTH_TEST);
                GLES20.glDisable(GLES20.GL_BLEND);

    看完整代码:

    Test6Renderer.java

      1 package com.android.jayce.test;
      2 
      3 import java.nio.ByteBuffer;
      4 import java.nio.ByteOrder;
      5 import java.nio.FloatBuffer;
      6 
      7 import javax.microedition.khronos.egl.EGLConfig;
      8 import javax.microedition.khronos.opengles.GL10;
      9 
     10 import com.learnopengles.android.common.ShapeBuilder;
     11 
     12 import android.opengl.GLES20;
     13 import android.opengl.Matrix;
     14 import android.opengl.GLSurfaceView;
     15 import android.os.SystemClock;
     16 
     17 public class Test6Renderer implements GLSurfaceView.Renderer
     18 {
     19     private static final int BYTES_PER_FLOAT = 4;
     20     private final FloatBuffer mCubePositions;
     21     private final FloatBuffer mCubeColors;
     22     private float[] mMVPMatrix = new float[16];
     23     private float[] mViewMatrix = new float[16];
     24     private float[] mModelMatrix = new float[16];
     25     private float[] mProjectionMatrix = new float[16];
     26     private int mMVPMatrixHandle;
     27     private int mPositionHandle;
     28     private int mColorHandle;
     29     private int mProgramHandle;
     30     private final int POSITION_DATA_SIZE = 3;
     31     private final int COLOR_DATA_SIZE = 4;
     32     private boolean mBlending = true;
     33     
     34     public Test6Renderer()
     35     {
     36         final float[] p1p = {-1.0f, 1.0f, 1.0f};                    
     37         final float[] p2p = {1.0f, 1.0f, 1.0f};
     38         final float[] p3p = {-1.0f, -1.0f, 1.0f};
     39         final float[] p4p = {1.0f, -1.0f, 1.0f};
     40         final float[] p5p = {-1.0f, 1.0f, -1.0f};
     41         final float[] p6p = {1.0f, 1.0f, -1.0f};
     42         final float[] p7p = {-1.0f, -1.0f, -1.0f};
     43         final float[] p8p = {1.0f, -1.0f, -1.0f};
     44         final float[] cubePosition = ShapeBuilder.generateCubeData(p1p, p2p, p3p, p4p, p5p, p6p, p7p, p8p, p1p.length);
     45         
     46         final float[] p1c = {1.0f, 0.0f, 0.0f, 1.0f};        // red            
     47         final float[] p2c = {1.0f, 0.0f, 1.0f, 1.0f};        // magenta
     48         final float[] p3c = {0.0f, 0.0f, 0.0f, 1.0f};        // black
     49         final float[] p4c = {0.0f, 0.0f, 1.0f, 1.0f};        // blue
     50         final float[] p5c = {1.0f, 1.0f, 0.0f, 1.0f};        // yellow
     51         final float[] p6c = {1.0f, 1.0f, 1.0f, 1.0f};        // white
     52         final float[] p7c = {0.0f, 1.0f, 0.0f, 1.0f};        // green
     53         final float[] p8c = {0.0f, 1.0f, 1.0f, 1.0f};        // cyan
     54         
     55         final float[] cubeColor = ShapeBuilder.generateCubeData(p1c, p2c, p3c, p4c, p5c, p6c, p7c, p8c, p1c.length);
     56         
     57         mCubePositions = ByteBuffer.allocateDirect(cubePosition.length * BYTES_PER_FLOAT)
     58                 .order(ByteOrder.nativeOrder()).asFloatBuffer();
     59         mCubePositions.put(cubePosition).position(0);
     60         mCubeColors = ByteBuffer.allocateDirect(cubeColor.length * BYTES_PER_FLOAT)
     61                 .order(ByteOrder.nativeOrder()).asFloatBuffer();
     62         mCubeColors.put(cubeColor).position(0);
     63     }
     64     
     65     @Override
     66     public void onDrawFrame(GL10 gl) {
     67         // TODO Auto-generated method stub
     68         if (mBlending)
     69         {
     70             GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
     71         }
     72         else
     73         {
     74             GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
     75         }
     76         long time = SystemClock.uptimeMillis() % 10000L;        
     77         float angleInDegrees = (360.0f / 10000.0f) * ((int) time);
     78         GLES20.glUseProgram(mProgramHandle);
     79         mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_MVPMatrix");
     80         mPositionHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Position");
     81         mColorHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Color");
     82         
     83         Matrix.setIdentityM(mModelMatrix, 0);
     84         Matrix.translateM(mModelMatrix, 0, 0.0f, 0.0f, -5.0f);
     85         Matrix.rotateM(mModelMatrix, 0, angleInDegrees, 1.0f, 1.0f, 0.0f);   
     86         drawCube(mCubePositions, mCubeColors);
     87     }
     88 
     89     public void switchMode()
     90     {        
     91         mBlending = !mBlending;
     92         
     93         if (mBlending)
     94         {
     95             // No culling of back faces
     96             GLES20.glDisable(GLES20.GL_CULL_FACE);
     97             
     98             // No depth testing
     99             GLES20.glDisable(GLES20.GL_DEPTH_TEST);
    100             
    101             // Enable blending
    102             GLES20.glEnable(GLES20.GL_BLEND);
    103             GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE);            
    104         }
    105         else
    106         {
    107             // Cull back faces
    108             GLES20.glEnable(GLES20.GL_CULL_FACE);
    109             
    110             // Enable depth testing
    111             GLES20.glEnable(GLES20.GL_DEPTH_TEST);
    112             
    113             // Disable blending
    114             GLES20.glDisable(GLES20.GL_BLEND);
    115         }
    116     }
    117     
    118     private void drawCube(final FloatBuffer cubePositionsBuffer, final FloatBuffer cubeColorsBuffer)
    119     {
    120         cubePositionsBuffer.position(0);
    121         GLES20.glVertexAttribPointer(mPositionHandle, POSITION_DATA_SIZE, GLES20.GL_FLOAT, false, 0, cubePositionsBuffer);
    122         GLES20.glEnableVertexAttribArray(mPositionHandle);
    123         
    124         cubeColorsBuffer.position(0);
    125         GLES20.glVertexAttribPointer(mColorHandle, COLOR_DATA_SIZE, GLES20.GL_FLOAT, false, 0, cubeColorsBuffer);
    126         GLES20.glEnableVertexAttribArray(mColorHandle);
    127         Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);   
    128         Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
    129         
    130         GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
    131         GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 36);
    132     }
    133     
    134     @Override
    135     public void onSurfaceChanged(GL10 gl, int width, int height) {
    136         // TODO Auto-generated method stub
    137         GLES20.glViewport(0, 0, width, height);
    138         
    139         final float ratio = (float) width / height;
    140         final float left = -ratio;
    141         final float right = ratio;
    142         final float bottom = -1.0f;
    143         final float top = 1.0f;
    144         final float near = 1.0f;
    145         final float far = 10.0f;
    146         
    147         Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
    148     }
    149 
    150     @Override
    151     public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    152         // TODO Auto-generated method stub
    153         GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    154         GLES20.glDisable(GLES20.GL_CULL_FACE);
    155         GLES20.glDisable(GLES20.GL_DEPTH_TEST);
    156         
    157         GLES20.glEnable(GLES20.GL_BLEND);
    158         GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE);
    159         
    160         // Position the eye behind the origin.
    161         final float eyeX = 0.0f;
    162         final float eyeY = 0.0f;
    163         final float eyeZ = -0.5f;
    164 
    165         // We are looking toward the distance
    166         final float lookX = 0.0f;
    167         final float lookY = 0.0f;
    168         final float lookZ = -5.0f;
    169 
    170         // Set our up vector. This is where our head would be pointing were we holding the camera.
    171         final float upX = 0.0f;
    172         final float upY = 1.0f;
    173         final float upZ = 0.0f;
    174 
    175         // Set the view matrix. This matrix can be said to represent the camera position.
    176         // NOTE: In OpenGL 1, a ModelView matrix is used, which is a combination of a model and
    177         // view matrix. In OpenGL 2, we can keep track of these matrices separately if we choose.
    178         Matrix.setLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ);
    179         
    180         final String vertexShader =
    181                 "uniform mat4 u_MVPMatrix;      \n"        // A constant representing the combined model/view/projection matrix.
    182                 
    183               + "attribute vec4 a_Position;     \n"        // Per-vertex position information we will pass in.
    184               + "attribute vec4 a_Color;        \n"        // Per-vertex color information we will pass in.              
    185               + "varying vec4 v_Color;          \n"        // This will be passed into the fragment shader.
    186               
    187               + "void main()                    \n"        // The entry point for our vertex shader.
    188               + "{                              \n"
    189               + "   v_Color = a_Color;          \n"        // Pass the color through to the fragment shader. 
    190                                                           // It will be interpolated across the triangle.
    191               + "   gl_Position = u_MVPMatrix   \n"     // gl_Position is a special variable used to store the final position.
    192               + "               * a_Position;   \n"     // Multiply the vertex by the matrix to get the final point in                                                                      
    193               + "}                              \n";    // normalized screen coordinates.
    194             
    195         final String fragmentShader =
    196                 "precision mediump float;       \n"        // Set the default precision to medium. We don't need as high of a 
    197                                                         // precision in the fragment shader.                
    198               + "varying vec4 v_Color;          \n"        // This is the color from the vertex shader interpolated across the 
    199                                                           // triangle per fragment.              
    200               + "void main()                    \n"        // The entry point for our fragment shader.
    201               + "{                              \n"
    202               + "   gl_FragColor = v_Color;     \n"        // Pass the color directly through the pipeline.          
    203               + "}                              \n";    
    204             
    205         int vertexShaderHandle = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
    206         if(vertexShaderHandle != 0)
    207         {
    208             GLES20.glShaderSource(vertexShaderHandle, vertexShader);
    209             GLES20.glCompileShader(vertexShaderHandle);
    210             
    211             final int[] compileStatus = new int[1];
    212             GLES20.glGetShaderiv(vertexShaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0);
    213             
    214             if(compileStatus[0] == 0)
    215             {
    216                 GLES20.glDeleteShader(vertexShaderHandle);
    217                 vertexShaderHandle = 0;
    218             }
    219         }
    220         
    221         if(vertexShaderHandle == 0)
    222         {
    223             throw new RuntimeException("failed to creating vertex shader");
    224         }
    225         
    226         int fragmentShaderHandle = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
    227         if(fragmentShaderHandle != 0)
    228         {
    229             GLES20.glShaderSource(fragmentShaderHandle, fragmentShader);
    230             GLES20.glCompileShader(fragmentShaderHandle);
    231             
    232             final int[] compileStatus = new int[1];
    233             GLES20.glGetShaderiv(fragmentShaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0);
    234             
    235             if(compileStatus[0] == 0)
    236             {
    237                 GLES20.glDeleteShader(fragmentShaderHandle);
    238                 fragmentShaderHandle = 0;
    239             }
    240             
    241         }
    242         
    243         if(fragmentShaderHandle == 0)
    244         {
    245             throw new RuntimeException("failed to create fragment shader");
    246         }
    247         
    248         mProgramHandle = GLES20.glCreateProgram();
    249         if(mProgramHandle != 0)
    250         {
    251             GLES20.glAttachShader(mProgramHandle, vertexShaderHandle);
    252             GLES20.glAttachShader(mProgramHandle, fragmentShaderHandle);
    253             
    254             GLES20.glBindAttribLocation(mProgramHandle, 0, "a_Position");
    255             GLES20.glBindAttribLocation(mProgramHandle, 1, "a_Color");
    256             
    257             GLES20.glLinkProgram(mProgramHandle);
    258             
    259             final int[] linkStatus = new int[1];
    260             GLES20.glGetProgramiv(mProgramHandle, GLES20.GL_LINK_STATUS, linkStatus, 0);
    261             
    262             if(linkStatus[0] == 0)
    263             {
    264                 GLES20.glDeleteProgram(mProgramHandle);
    265                 mProgramHandle = 0;
    266             }
    267         }
    268         
    269         if(mProgramHandle == 0)
    270         {
    271             throw new RuntimeException("failed to create program");
    272         }
    273         
    274     }
    275     
    276 }

    构造方法里用了内置方法来生成CubePosition和CubeColor。

    来看看效果:

    开启blending效果:

        

    关闭blending效果:

  • 相关阅读:
    [转]Oracle 语法之 OVER (PARTITION BY ..) 及开窗函数
    oracle本月、上月、去年
    Oracle 物理视图刷新报错ORA-00942
    [转]Oracle trunc()函数的用法
    [转]物化视图创建 及 刷新机制修改
    [转]oracle制定定时任务(dbms_jobs)
    【转】Windows平台下的Subversion安装配置新手指南
    【转】数字签名与数字证书
    [转]SQL 常用函数及示例
    【转】视图、索引、存储过程 、触发器、游标及事务
  • 原文地址:https://www.cnblogs.com/jayceli/p/2480348.html
Copyright © 2011-2022 走看看