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效果:

Android OpenGL ES 2.0 (六) 混合blending    

Android OpenGL ES 2.0 (六) 混合blending

关闭blending效果:

Android OpenGL ES 2.0 (六) 混合blending

Android OpenGL ES 2.0 (六) 混合blending

你可能感兴趣的:(openGL ES)