Android OpenGLES2.0 - 呈现时的纯黑色纹理

时间:2013-04-11 12:31:36

标签: java android opengl-es opengl-es-2.0 textures

过去一周左右我一直在制作Android OpenGLES2.0 2D游戏引擎,经过几次颠簸后,我基本上都取得了成功。我已经实现了ModelMatrix,ProjectionMatrix,ViewMatrix,LightMatrix,着色器,2D平面和纹理。然而,虽然我的数据似乎正好穿过这个管道丛林,但我的纹理并没有出现,而是一个坚实的黑色。

大多数(如果不是全部)我的代码都来自this source,并且它最终是相同的,除了我创建了自己的着色器类,边界框类,房间类和游戏对象类以简化在游戏中实例化对象的过程。渲染器占用空间,房间占用GameObject(SpaceShip扩展游戏对象),GameObject占用BoundingBox,然后渲染器在for循环中渲染房间的对象。为此,我从示例中移动了确切的代码,以便某些句柄是我创建的某些类的元素,而不是渲染器的元素。这并没有引起矩阵乘法或我的数据到达管道末端的任何问题,所以我怀疑移动句柄是问题,但我觉得知道它很重要。

我尝试过的事情:

  1. 更改位图
    • 将其更改为没有Alpha通道的位图,均为32x32(2 ^ 5)且为.png。
  2. 更改操作顺序
    • 我在实现中移动了glBindTexture,所以我把它移回了,然后又回来了。
  3. 更改纹理参数
    • 我尝试了几种组合,没有使用mip-mapping
  4. 更改加载图片的方式
    • 从BitmapFactory.decodeResource到BitmapFactory.decodeStream
  5. 将纹理移动到所有可绘制文件夹
    • 也在原始文件夹
    • 中尝试过
  6. 在另一台设备上尝试过
    • 我朋友的DROID(Froyo 2.2),我扎根的NextBook(Gingerbread 2.3)。两者都支持OpenGLES2.0。
  7. 我没有尝试过(我知道):

    1. 更改纹理坐标
      • 他们直接来自这个例子。我只拿了一个立方体的脸。
    2. 更改我的着色器
      • 它也直接来自这个例子(除了它现在是它自己的类)。
    3. 将我的程序重构为两个(3,4 ... x)类
      • 多德...
    4. 我已经在模拟器(Eclipse Indigo,AVD,Intel Atom x86,ICS 4.2.2,API级别17)上进行了一段时间的测试,并且正好在我使所有矩阵工作的时候,模拟器失败了渲染任何东西。它曾用于渲染得很好(当投影都是螺旋状的时候),现在它只显示带有标题栏的黑色。这使得调试非常困难。我不确定这是否与我所做的事情有关(可能是),或者它是否与模拟器在OpenGL上吮吸有关。

      很抱歉这么长时间啰嗦并包含如此多的代码,但我不知道如何使用显示/隐藏按钮。

      有什么想法吗?

      编辑:我在示例中使用了错误的着色器。命名非常误导。我没有传递颜色信息。我仍然没有纹理,但模拟器再次工作。 :)

      OpenGLES20_2DRenderer

      package mycompany.OpenGLES20_2DEngine;
      
      import javax.microedition.khronos.egl.EGLConfig;
      import javax.microedition.khronos.opengles.GL10;
      
      import android.content.Context;
      import android.opengl.GLES20;
      import android.opengl.GLSurfaceView;
      import android.opengl.Matrix;
      import android.util.Log;
      
      public class OpenGLES20_2DRenderer implements GLSurfaceView.Renderer {
      
      /** Used for debug logs. */
      private static final String TAG = "Renderer";
      
      //Matrix Declarations*************************
      /**
       * Store the model matrix. This matrix is used to move models from object space (where each model can be thought
       * of being located at the center of the universe) to world space.
       */
      private float[] mModelMatrix = new float[16];
      /**
       * Store the view matrix. This can be thought of as our camera. This matrix transforms world space to eye space;
       * it positions things relative to our eye.
       */
      private float[] mViewMatrix = new float[16];
      /** Store the projection matrix. This is used to project the scene onto a 2D viewport. */
      private float[] mProjectionMatrix = new float[16];
      /** Allocate storage for the final combined matrix. This will be passed into the shader program. */
      private float[] mMVPMatrix = new float[16];
      /**
       * Stores a copy of the model matrix specifically for the light position.
       */
      private float[] mLightModelMatrix = new float[16];
      
      //********************************************
      
      //Global Variable Declarations****************
      //Shader
      Shader shader;
      //PointShader
      PointShader pointShader;
      //Application Context
      Context context;
      //A room to add objects to
      Room room;
      //********************************************
      
      public OpenGLES20_2DRenderer(Context ctx) {
          context = ctx;
      }
      
      public void onSurfaceCreated(GL10 unused, EGLConfig config) {
      
          //Initialize GLES20***************************
          // Set the background frame color
          GLES20.glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
          // Use culling to remove back faces.
          GLES20.glEnable(GLES20.GL_CULL_FACE);
          // Enable depth testing
          GLES20.glEnable(GLES20.GL_DEPTH_TEST);
          // Position the eye in front of the origin.
          final float eyeX = 0.0f;
          final float eyeY = 0.0f;
          final float eyeZ = -0.5f;
          // We are looking toward the distance
          final float lookX = 0.0f;
          final float lookY = 0.0f;
          final float lookZ = -5.0f;
          // Set our up vector. This is where our head would be pointing were we holding the camera.
          final float upX = 0.0f;
          final float upY = 1.0f;
          final float upZ = 0.0f;
          // Set the view matrix. This matrix can be said to represent the camera position.
          // NOTE: In OpenGL 1, a ModelView matrix is used, which is a combination of a model and
          // view matrix. In OpenGL 2, we can keep track of these matrices separately if we choose.
          Matrix.setLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ);    
          //********************************************
      
          //Initialize Shaders**************************
          shader = new Shader();
          pointShader = new PointShader();
          //********************************************
      
          //Load The Level******************************
          //Create a new room
          room = new Room(800,600, 0);
          //Load game objects
          SpaceShip user = new SpaceShip();
          //Load sprites
          for(int i=0;i<room.numberOfGameObjects;i++) {
              room.gameObjects[i].spriteGLIndex = room.gameObjects[i].loadSprite(context, room.gameObjects[i].spriteResId);   
          }
          //Add them to the room
          room.addGameObject(user);
          //********************************************
      
      }
      
      public void onDrawFrame(GL10 unused) {
      
          //Caclulate MVPMatrix*************************
          GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
          // Set our per-vertex lighting program.
          GLES20.glUseProgram(shader.mProgram);
          // Set program handles for object drawing.
          shader.mMVPMatrixHandle = GLES20.glGetUniformLocation(shader.mProgram, "u_MVPMatrix");
          shader.mMVMatrixHandle = GLES20.glGetUniformLocation(shader.mProgram, "u_MVMatrix");
          shader.mLightPosHandle = GLES20.glGetUniformLocation(shader.mProgram, "u_LightPos");
          shader.mTextureUniformHandle = GLES20.glGetUniformLocation(shader.mProgram, "u_Texture");
          shader.mPositionHandle = GLES20.glGetAttribLocation(shader.mProgram, "a_Position");
          shader.mColorHandle = GLES20.glGetAttribLocation(shader.mProgram, "a_Color");
          shader.mNormalHandle = GLES20.glGetAttribLocation(shader.mProgram, "a_Normal");
          shader.mTextureCoordinateHandle = GLES20.glGetAttribLocation(shader.mProgram, "a_TexCoordinate");
      
          // Calculate position of the light. Rotate and then push into the distance.
          Matrix.setIdentityM(mLightModelMatrix, 0);
          Matrix.translateM(mLightModelMatrix, 0, 0.0f, 0.0f, -5.0f);
          Matrix.rotateM(mLightModelMatrix, 0, 0, 0.0f, 1.0f, 0.0f);
          Matrix.translateM(mLightModelMatrix, 0, 0.0f, 0.0f, 2.0f);
          Matrix.multiplyMV(shader.mLightPosInWorldSpace, 0, mLightModelMatrix, 0, shader.mLightPosInModelSpace, 0);
          Matrix.multiplyMV(shader.mLightPosInEyeSpace, 0, mViewMatrix, 0, shader.mLightPosInWorldSpace, 0); 
          //********************************************
      
          //Draw****************************************
          //Draw the background
          //room.drawBackground(mMVPMatrix);
          // Draw game objects
          for(int i=0;i<room.numberOfGameObjects;i++) {
      
              // Set the active texture unit to texture unit 0.
              GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
              // Bind the texture to this unit.
              GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, room.gameObjects[i].spriteGLIndex);
              // Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
              GLES20.glUniform1i(shader.mTextureUniformHandle, 0);
      
              //Set up the model matrix
              Matrix.setIdentityM(mModelMatrix, 0);
              Matrix.translateM(mModelMatrix, 0, 4.0f, 0.0f, -7.0f);
              Matrix.rotateM(mModelMatrix, 0, room.gameObjects[i].rotation, 1.0f, 0.0f, 0.0f); 
      
              //Draw the object
              room.gameObjects[i].draw(mModelMatrix, mViewMatrix, mProjectionMatrix, mMVPMatrix, shader);
          }
          //********************************************
      
          // Draw a point to indicate the light.********
          drawLight();
          //********************************************
      
      }
      
      public void onSurfaceChanged(GL10 unused, int width, int height) {
      
          //Initialize Projection Matrix****************
          // Set the OpenGL viewport to the same size as the surface.
          GLES20.glViewport(0, 0, width, height);
          // Create a new perspective projection matrix. The height will stay the same
          // while the width will vary as per aspect ratio.
          final float ratio = (float) width / height;
          final float left = -ratio;
          final float right = ratio;
          final float bottom = -1.0f;
          final float top = 1.0f;
          final float near = 1.0f;
          final float far = 10.0f;
          Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
          //********************************************
      
      }
      
      // Draws a point representing the position of the light.
      private void drawLight()
      {
          GLES20.glUseProgram(pointShader.mProgram);
          final int pointMVPMatrixHandle = GLES20.glGetUniformLocation(pointShader.mProgram, "u_MVPMatrix");
          final int pointPositionHandle = GLES20.glGetAttribLocation(pointShader.mProgram, "a_Position");
          // Pass in the position.
          GLES20.glVertexAttrib3f(pointPositionHandle, shader.mLightPosInModelSpace[0], shader.mLightPosInModelSpace[1], shader.mLightPosInModelSpace[2]);
          // Since we are not using a buffer object, disable vertex arrays for this attribute.
          GLES20.glDisableVertexAttribArray(pointPositionHandle);
          // Pass in the transformation matrix.
          Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mLightModelMatrix, 0);
          Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
          GLES20.glUniformMatrix4fv(pointMVPMatrixHandle, 1, false, mMVPMatrix, 0);
          // Draw the point.
          GLES20.glDrawArrays(GLES20.GL_POINTS, 0, 1);
      }
      }
      

      着色

      package mycompany.OpenGLES20_2DEngine;
      
      import android.opengl.GLES20;
      import android.util.Log;
      
      public class Shader {
      
      /** Used for debug logs. */
      private static final String TAG = "Shader";
      
      //Shaders*************************************
      public int vertexShader;
      public int fragmentShader;
      //********************************************
      
      //Handles*************************************
      /** This will be used to pass in model position information. */
      public int mPositionHandle;
      /** This will be used to pass in model color information. */
      public int mColorHandle;
      /** This will be used to pass in model normal information. */
      public int mNormalHandle;
      /** This will be used to pass in model texture coordinate information. */
      public int mTextureCoordinateHandle;
      /** This will be used to pass in the transformation matrix. */
      public int mMVPMatrixHandle;
      /** This will be used to pass in the modelview matrix. */
      public int mMVMatrixHandle;
      /** This will be used to pass in the light position. */
      public int mLightPosHandle;
      /** This will be used to pass in the texture. */
      public int mTextureUniformHandle;
      /** Used to hold a light centered on the origin in model space. We need a 4th coordinate so we can get translations to work when
       * we multiply this by our transformation matrices. */
      public final float[] mLightPosInModelSpace = new float[] {0.0f, 0.0f, 0.0f, 1.0f};
      /** Used to hold the current position of the light in world space (after transformation via model matrix). */
      public final float[] mLightPosInWorldSpace = new float[4];
      /** Used to hold the transformed position of the light in eye space (after transformation via modelview matrix) */
      public final float[] mLightPosInEyeSpace = new float[4];
      //********************************************
      
      //GL Code For Shaders*************************
      public final String vertexShaderCode =
          // A constant representing the combined model/view/projection matrix.
          "uniform mat4 u_MVPMatrix;" + "\n" + 
          // A constant representing the combined model/view matrix.
          "uniform mat4 u_MVMatrix;" + "\n" + 
          // Per-vertex position information we will pass in.
          "attribute vec4 a_Position;" + "\n" + 
          // Per-vertex normal information we will pass in.
          "attribute vec3 a_Normal;" + "\n" + 
          // Per-vertex texture coordinate information we will pass in.
          "attribute vec2 a_TexCoordinate;" + "\n" + 
          // This will be passed into the fragment shader.
          "varying vec3 v_Position;" + "\n" + 
          // This will be passed into the fragment shader.
          "varying vec3 v_Normal;" + "\n" + 
          // This will be passed into the fragment shader.
          "varying vec2 v_TexCoordinate;" + "\n" + 
      
          // The entry point for our vertex shader.
          "void main()" + "\n" +
              "{" + "\n" +
              // Transform the vertex into eye space.
              "v_Position = vec3(u_MVMatrix * a_Position);" + "\n" +
              // Pass through the texture coordinate.
              "v_TexCoordinate = a_TexCoordinate;" + "\n" +
              // Transform the normal's orientation into eye space.
              "v_Normal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));" + "\n" +
              // gl_Position is a special variable used to store the final position.
              // Multiply the vertex by the matrix to get the final point in normalized screen coordinates.
              "gl_Position = u_MVPMatrix * a_Position;" + "\n" +
          "}";
      public final String fragmentShaderCode =
          "precision mediump float;" + "\n" +  // Set the default precision to medium. We don't need as high of a
          // precision in the fragment shader.
          "uniform vec3 u_LightPos;" + "\n" +  // The position of the light in eye space.
          "uniform sampler2D u_Texture;" + "\n" +  // The input texture.
          "varying vec3 v_Position;" + "\n" +  // Interpolated position for this fragment.
          "varying vec3 v_Normal;" + "\n" +  // Interpolated normal for this fragment.
          "varying vec2 v_TexCoordinate;" + "\n" +  // Interpolated texture coordinate per fragment.
      
          // The entry point for our fragment shader.
          "void main()" + "\n" + 
          "{" + "\n" + 
              // Will be used for attenuation.
              "float distance = length(u_LightPos - v_Position);" + "\n" + 
              // Get a lighting direction vector from the light to the vertex.
              "vec3 lightVector = normalize(u_LightPos - v_Position);" + "\n" + 
              // Calculate the dot product of the light vector and vertex normal. If the normal and light vector are
              // pointing in the same direction then it will get max illumination.
              "float diffuse = max(dot(v_Normal, lightVector), 0.0);" + "\n" + 
              // Add attenuation.
              "diffuse = diffuse * (1.0 / (1.0 + (0.25 * distance)));" + "\n" + 
              // Add ambient lighting
              "diffuse = diffuse + 0.7;" + "\n" + 
              // Multiply the color by the diffuse illumination level and texture value to get final output color.
              "gl_FragColor = (diffuse * texture2D(u_Texture, v_TexCoordinate));" + "\n" + 
          "}";
      //********************************************
      
      //GL Program Handle***************************
      public int mProgram;
      //********************************************
      
      public Shader() {
      
          //Load Shaders********************************
          vertexShader = compileShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
          fragmentShader = compileShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
          //********************************************
      
          //Create GL Program***************************
          mProgram = createAndLinkProgram(vertexShader, fragmentShader, new String[] {"a_Position",  "a_Color", "a_Normal", "a_TexCoordinate"});
          //********************************************
      
      }
      
      /**
       * Helper function to compile a shader.
       *
       * @param shaderType The shader type.
       * @param shaderSource The shader source code.
       * @return An OpenGL handle to the shader.
       */
      public static int compileShader(final int shaderType, final String shaderSource)
      {
          int shaderHandle = GLES20.glCreateShader(shaderType);
      
          if (shaderHandle != 0)
          {
              // Pass in the shader source.
              GLES20.glShaderSource(shaderHandle, shaderSource);
      
              // Compile the shader.
              GLES20.glCompileShader(shaderHandle);
      
              // Get the compilation status.
              final int[] compileStatus = new int[1];
              GLES20.glGetShaderiv(shaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0);
      
              // If the compilation failed, delete the shader.
              if (compileStatus[0] == 0)
              {
                  Log.e(TAG, "Error compiling shader " /*+ GLES20.glGetShaderInfoLog(shaderHandle)*/);
                  GLES20.glDeleteShader(shaderHandle);
                  shaderHandle = 0;
              }
          }
      
          if (shaderHandle == 0)
          {   
              throw new RuntimeException("Error creating shader.");
          }
      
          return shaderHandle;
      }
      
      /**
       * Helper function to compile and link a program.
       *
       * @param vertexShaderHandle An OpenGL handle to an already-compiled vertex shader.
       * @param fragmentShaderHandle An OpenGL handle to an already-compiled fragment shader.
       * @param attributes Attributes that need to be bound to the program.
       * @return An OpenGL handle to the program.
       */
      public static int createAndLinkProgram(final int vertexShaderHandle, final int fragmentShaderHandle, final String[] attributes)
      {
          int programHandle = GLES20.glCreateProgram();
      
          if (programHandle != 0)
          {
              // Bind the vertex shader to the program.
              GLES20.glAttachShader(programHandle, vertexShaderHandle);   
      
              // Bind the fragment shader to the program.
              GLES20.glAttachShader(programHandle, fragmentShaderHandle);
      
              // Bind attributes
              if (attributes != null)
              {
                  final int size = attributes.length;
                  for (int i = 0; i < size; i++)
                  {
                      GLES20.glBindAttribLocation(programHandle, i, attributes[i]);
                  }   
              }
      
              // Link the two shaders together into a program.
              GLES20.glLinkProgram(programHandle);
      
              // Get the link status.
              final int[] linkStatus = new int[1];
              GLES20.glGetProgramiv(programHandle, GLES20.GL_LINK_STATUS, linkStatus, 0);
      
              // If the link failed, delete the program.
              if (linkStatus[0] == 0)
              {   
                  Log.e(TAG, "Error compiling program " /*+ GLES20.glGetProgramInfoLog(programHandle)*/);
                  GLES20.glDeleteProgram(programHandle);
                  programHandle = 0;
              }
          }
      
          if (programHandle == 0)
          {
              throw new RuntimeException("Error creating program.");
          }
      
          return programHandle;
      }
      
      }
      

      游戏物体

      package mycompany.OpenGLES20_2DEngine;
      
      import java.io.IOException;
      import java.io.InputStream;
      import android.content.Context;
      import android.graphics.Bitmap;
      import android.graphics.BitmapFactory;
      import android.opengl.GLES20;
      import android.opengl.GLUtils;
      import android.opengl.Matrix;
      import android.util.Log;
      
      public class GameObject {
      
      /** Used for debug logs. */
      private static final String TAG = "GameObject";
      
      //Declare Variables****************************
      //Position
      public int x;
      public int y;
      public int z;
      //Size
      public int width;
      public int height;
      //Movement
      double thrustX;
      double thrustY;
      //Rotation
      public int rotation;
      public int rotationSpeed;
      //Unique Identifier
      public int UID;
      //Sprite Resource ID
      int spriteResId;
      //GL Texture Reference
      int spriteGLIndex;
      //Bounding Box
      BoundingBox boundingBox;
      //********************************************
      
      GameObject() {
      
      }
      
      public int loadSprite(final Context context, final int resourceId) {
          final int[] textureHandle = new int[1];
      
          GLES20.glGenTextures(1, textureHandle, 0);
      
          if (textureHandle[0] != 0)
          {
              final BitmapFactory.Options options = new BitmapFactory.Options();
              options.inScaled = false;   // No pre-scaling
      
              // Read in the resource
              InputStream is = context.getResources()
                      .openRawResource(resourceId);
              Bitmap bitmap = null;
              try {
                  bitmap = BitmapFactory.decodeStream(is);
                  is.close();
              } catch(IOException e) {
                  Log.e(TAG, "Could not load the texture");
              }
      
              // Bind to the texture in OpenGL
              GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);
      
              // Set filtering
              //TODO: Offending Line - Makes textures black because of parameters
              GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
              GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
              GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
              GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
      
              // Load the bitmap into the bound texture.
              GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
      
              // Recycle the bitmap, since its data has been loaded into OpenGL.
              bitmap.recycle();
          }
      
          if (textureHandle[0] == 0)
          {
              throw new RuntimeException("Error loading texture.");
          }
      
          return textureHandle[0];
      }
      
      public void setUID(int uid) {
          UID = uid;
      }
      
      public int getUID() {
          return UID;
      }
      
      public void draw(float[] mModelMatrix, float[] mViewMatrix, float[] mProjectionMatrix, float[] mMVPMatrix, Shader shader) {
      
          {   
              // Pass in the position information
              boundingBox.mPositions.position(0); 
              GLES20.glVertexAttribPointer(shader.mPositionHandle, boundingBox.mPositionDataSize, GLES20.GL_FLOAT, false,
                      0, boundingBox.mPositions);
      
              GLES20.glEnableVertexAttribArray(shader.mPositionHandle);
      
              // Pass in the color information
              boundingBox.mColors.position(0);
              GLES20.glVertexAttribPointer(shader.mColorHandle, boundingBox.mColorDataSize, GLES20.GL_FLOAT, false,
                      0, boundingBox.mColors);
      
              GLES20.glEnableVertexAttribArray(shader.mColorHandle);
      
              // Pass in the normal information
              boundingBox.mNormals.position(0);
              GLES20.glVertexAttribPointer(shader.mNormalHandle, boundingBox.mNormalDataSize, GLES20.GL_FLOAT, false,
                      0, boundingBox.mNormals);
      
              GLES20.glEnableVertexAttribArray(shader.mNormalHandle);
      
              // Pass in the texture coordinate information
              boundingBox.mTextureCoordinates.position(0);
              GLES20.glVertexAttribPointer(shader.mTextureCoordinateHandle, boundingBox.mTextureCoordinateDataSize, GLES20.GL_FLOAT, false,
                      0, boundingBox.mTextureCoordinates);
      
              GLES20.glEnableVertexAttribArray(shader.mTextureCoordinateHandle);
      
              // This multiplies the view matrix by the model matrix, and stores the result in the MVP matrix
              // (which currently contains model * view).
              Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
      
              // Pass in the modelview matrix.
              GLES20.glUniformMatrix4fv(shader.mMVMatrixHandle, 1, false, mMVPMatrix, 0);
      
              // This multiplies the modelview matrix by the projection matrix, and stores the result in the MVP matrix
              // (which now contains model * view * projection).
              Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
      
              // Pass in the combined matrix.
              GLES20.glUniformMatrix4fv(shader.mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
      
              // Pass in the light position in eye space.
              GLES20.glUniform3f(shader.mLightPosHandle, shader.mLightPosInEyeSpace[0], shader.mLightPosInEyeSpace[1], shader.mLightPosInEyeSpace[2]);
      
              // Draw the object
              GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);
          }
      }
      }
      

      的BoundingBox

      package mycompany.OpenGLES20_2DEngine;
      
      import java.nio.ByteBuffer;
      import java.nio.ByteOrder;
      import java.nio.FloatBuffer;
      //TODO: make this dynamic, both the constructor and the coordinates.
      class BoundingBox {
      
      //Variable Declarations***********************
      /** How many bytes per float. */
      private final int mBytesPerFloat = 4;
      /** Store our model data in a float buffer. */
      public final FloatBuffer mPositions;
      public final FloatBuffer mColors;
      public final FloatBuffer mNormals;
      public final FloatBuffer mTextureCoordinates;
      //Number of coordinates per vertex in this array
      final int COORDS_PER_VERTEX = 3;
      //Coordinates
      float[] positionData;
      //Texture Coordinates
      float[] textureCoordinateData;
      //Vertex Color
      float[] colorData;
      float[] normalData;
      //Vertex Stride
      final int vertexStride = COORDS_PER_VERTEX * 4;
      /** Size of the position data in elements. */
      public final int mPositionDataSize = 3; 
      /** Size of the color data in elements. */
      public final int mColorDataSize = 4;    
      /** Size of the normal data in elements. */
      public final int mNormalDataSize = 3;
      /** Size of the texture coordinate data in elements. */
      public final int mTextureCoordinateDataSize = 2;
      //********************************************
      
      public BoundingBox(float[] coords) {
          //TODO: Normalize values
          //Set Coordinates and Texture Coordinates*****
          if(coords==null) {
              float[] newPositionData = {
                      // Front face
                      -1.0f, 1.0f, 1.0f,  
                      -1.0f, -1.0f, 1.0f,
                      1.0f, 1.0f, 1.0f,
                      -1.0f, -1.0f, 1.0f,
                      1.0f, -1.0f, 1.0f,
                      1.0f, 1.0f, 1.0f
              };
              positionData = newPositionData;
      
              float[] newColorData = {
                      // Front face (red)
                      1.0f, 0.0f, 0.0f, 1.0f, 
                      1.0f, 0.0f, 0.0f, 1.0f,
                      1.0f, 0.0f, 0.0f, 1.0f,
                      1.0f, 0.0f, 0.0f, 1.0f, 
                      1.0f, 0.0f, 0.0f, 1.0f,
                      1.0f, 0.0f, 0.0f, 1.0f
              };
      
              colorData = newColorData;
      
              float[] newTextureCoordinateData =
                  {   
                      // Front face
                      0.0f, 0.0f,
                      0.0f, 1.0f,
                      1.0f, 0.0f,
                      0.0f, 1.0f,
                      1.0f, 1.0f,
                      1.0f, 0.0f, 
                  };
              textureCoordinateData = newTextureCoordinateData;
      
              float[] newNormalData = {
                      // Front face
                      0.0f, 0.0f, 1.0f,   
                      0.0f, 0.0f, 1.0f,
                      0.0f, 0.0f, 1.0f,
                      0.0f, 0.0f, 1.0f,   
                      0.0f, 0.0f, 1.0f,
                      0.0f, 0.0f, 1.0f
              };
      
              normalData = newNormalData;
          }
          else {
              positionData = coords;
              //TODO:Reverse coords HERE
              textureCoordinateData = coords;
          }
          //********************************************
      
          //Initialize Buffers**************************
          mPositions = ByteBuffer.allocateDirect(positionData.length * mBytesPerFloat)
                  .order(ByteOrder.nativeOrder()).asFloatBuffer();    
          mPositions.put(positionData).position(0);   
      
          mColors = ByteBuffer.allocateDirect(colorData.length * mBytesPerFloat)
                  .order(ByteOrder.nativeOrder()).asFloatBuffer();    
          mColors.put(colorData).position(0);
      
          mNormals = ByteBuffer.allocateDirect(normalData.length * mBytesPerFloat)
                  .order(ByteOrder.nativeOrder()).asFloatBuffer();    
          mNormals.put(normalData).position(0);
      
          mTextureCoordinates = ByteBuffer.allocateDirect(textureCoordinateData.length * mBytesPerFloat)
                  .order(ByteOrder.nativeOrder()).asFloatBuffer();
          mTextureCoordinates.put(textureCoordinateData).position(0);
          //********************************************
      }
      }
      

      宇宙飞船

      package mycompany.OpenGLES20_2DEngine;
      
      public class SpaceShip extends GameObject{
      
      public SpaceShip() {
          spriteResId = R.drawable.spaceship;
          boundingBox = new BoundingBox(null);
      }
      }
      

1 个答案:

答案 0 :(得分:0)

知道了。在我加载它的位图(从房间里)之后,我将太空船添加到了房间。

    //Load The Level******************************
    //Create a new room
    room = new Room(800,600, 0);
    //Load game objects
    SpaceShip user = new SpaceShip();
    **//Load sprites
    for(int i=0;i<room.numberOfGameObjects;i++) {
        room.gameObjects[i].spriteGLIndex = room.gameObjects[i].loadSprite(context, room.gameObjects[i].spriteResId);   
    }
    //Add them to the room
    room.addGameObject(user);**
    //********************************************