2

我正在使用 OpenGL 构建一个 Android 应用程序。我创建了 2 个正方形,每个正方形都有自己的纹理(PNG),并将它们叠加起来。根据我从上一个问题得到的提示,我使用了 gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);

我的问题是透明度效果会影响第二个正方形,因此我可以通过第二个正方形的纹理看到背景。有没有办法解决这个问题?

这是渲染器,底部是 Square.java 类:

package hello.project;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;

public class Square {

 private FloatBuffer vertexBuffer; // buffer holding the vertices
 static int sex=R.drawable.girl;

 private FloatBuffer textureBuffer; // buffer holding the texture coordinates
 private float texture[] = {
   // Mapping coordinates for the vertices
   0.0f, 1.0f,  // top left  (V2)
   0.0f, 0.0f,  // bottom left (V1)
   1.0f, 1.0f,  // top right (V4)
   1.0f, 0.0f  // bottom right (V3)
 };

 private float vertices[] = {
   -1.0f, -2.0f,  0.0f,  // V1 - bottom left
   -1.0f,  2.0f,  0.0f,  // V2 - top left
    0.8f, -2.0f,  0.0f,  // V3 - bottom right
    0.8f,  2.0f,  0.0f   // V4 - top right
 };

 public Square() {
  ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
  byteBuffer.order(ByteOrder.nativeOrder());
  vertexBuffer = byteBuffer.asFloatBuffer();
  vertexBuffer.put(vertices);
  vertexBuffer.position(0);

  byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
  byteBuffer.order(ByteOrder.nativeOrder());
  textureBuffer = byteBuffer.asFloatBuffer();
  textureBuffer.put(texture);
  textureBuffer.position(0);
 }

 /** The draw method for the square with the GL context */
 public void draw(GL10 gl) {
  // bind the previously generated texture
  gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

  // Point to our buffers
  gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
  gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);



  // Set the face rotation
  gl.glFrontFace(GL10.GL_CW);

  // Point to our vertex buffer
  gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
  gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

  // Draw the vertices as triangle strip
  gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);

  //Disable the client state before leaving
  gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
  gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
 }




 /** The texture pointer */
 private int[] textures = new int[1];

 public void loadGLTexture(GL10 gl, Context context,int sex ) {
  // loading texture
  Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
    sex);

  // generate one texture pointer
  gl.glGenTextures(1, textures, 0);
  // ...and bind it to our array
  gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

  // create nearest filtered texture
  gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
  gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

  // Use Android GLUtils to specify a two-dimensional texture image from our bitmap
  GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
  // Clean up
  bitmap.recycle();
 }

 public static int getSex() {
  return sex;
 }

 public static void setSex(int sex) {
  Square.sex = sex;
 }
}
---------------------------------------------------------------------------
package hello.project;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;

public class HelloOpenGLES10Renderer implements Renderer {

 private Square   square;  // the square
 private Square2  square2;  // the square
 private Context     context;


 /** Constructor to set the handed over context */
 public HelloOpenGLES10Renderer(Context context) {
  this.square  = new Square();
  this.square2 = new Square2();
  this.context=context;
 }

 public void onDrawFrame(GL10 gl) {
  // clear Screen and Depth Buffer
  gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

  // Reset the Modelview Matrix
  gl.glLoadIdentity();

  // Drawing
  gl.glTranslatef(0.0f, 0.0f, -5.0f);  // move 5 units INTO the screen
  square.draw(gl);
  square2.draw(gl); 


 }


 public void onSurfaceChanged(GL10 gl, int width, int height) {
  if(height == 0) {       //Prevent A Divide By Zero By
   height = 1;       //Making Height Equal One
  }

  gl.glViewport(0, 0, width, height);  //Reset The Current Viewport
  gl.glMatrixMode(GL10.GL_PROJECTION);  //Select The Projection Matrix
  gl.glLoadIdentity();      //Reset The Projection Matrix

  //Calculate The Aspect Ratio Of The Window
  GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 100.0f);

  gl.glMatrixMode(GL10.GL_MODELVIEW);  //Select The Modelview Matrix
  gl.glLoadIdentity();      //Reset The Modelview Matrix
 }


 public void onSurfaceCreated(GL10 gl, EGLConfig config) {
  // Load the texture for the square

  square.loadGLTexture(gl, this.context,Square.getSex());
  square2.loadGLTexture(gl, this.context,Square2.getSex());

  gl.glEnable(GL10.GL_TEXTURE_2D); 
  gl.glDisable(GL10.GL_DEPTH_TEST);
  gl.glEnable(GL10.GL_BLEND);

  gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);

  gl.glShadeModel(GL10.GL_SMOOTH);    //Enable Smooth Shading
  gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);  //Black Background
  gl.glClearDepthf(1.0f);      //Depth Buffer Setup
  gl.glDepthFunc(GL10.GL_NEVER);    //The Type Of Depth Testing To Do

  //Really Nice Perspective Calculations
  gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
 }
}
4

1 回答 1

2

您不只是对图形管道状态有问题吗?请记住,无论您告诉要先绘制哪个正方形,都会使用当前处于活动状态的混合函数来绘制(这将保持活动状态,直到您更改 OpenGL 状态)。也许您想在混合功能中添加更多的状态更改,或者更改绘制顺序以获得您想要的效果?您可能还想尝试启用/禁用绘图调用之间的深度测试以使正方形不透明。

希望这会有所帮助,您可能需要为您的问题提供更多细节。

于 2012-06-28T11:44:25.963 回答