2013-04-11 83 views
0

过去一周左右,我一直在制作Android OpenGLES2.0 2D游戏引擎,经过几次颠簸后,我基本上获得了成功。我有ModelMatrix,ProjectionMatrix,ViewMatrix,LightMatrix,着色器,2D平面和纹理。然而,虽然我的数据似乎通过这个管道丛林很好,但我的纹理不会出现,而是一个纯黑色。Android OpenGLES2.0 - 渲染时的纯黑色纹理

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

观光我试着:

  1. 改变位图
    • 将其改为没有alpha通道的位图,两者都是32×32(2^5)和.png格式。
  2. 更改操作
    • 我在实现移动glBindTexture的顺序,所以我把它回来,然后再回来。
  3. 改变纹理参数
    • 我尝试了几种组合,没有使用MIP映射
  4. 改变I加载图像
    • 从BitmapFactory.decodeResource走到BitmapFactory.decodeStream的方式
  5. 将纹理移动到所有可绘制文件夹
    • 也尝试过在原文件夹
  6. 试了一下其他设备上
    • 我朋友的DROID(升级Froyo 2.2),我扎根下一本书(姜饼2.3)。两者都支持OpenGLES2.0。

Thigs我还没有试过(我所知道的):

  1. 改变纹理坐标
    • 它们直接来自于例子。我只拿了一个立方体的脸。
  2. 更改我的着色器
    • 这也直接来自于例子(除了它是它自己的类了)。
  3. 重组我的计划是只有两个(3,4 ... X)班
    • 猪头...

我已经在模拟器上测试(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); 
    //******************************************** 
} 
} 

SpaceShip

package mycompany.OpenGLES20_2DEngine; 

public class SpaceShip extends GameObject{ 

public SpaceShip() { 
    spriteResId = R.drawable.spaceship; 
    boundingBox = new BoundingBox(null); 
} 
} 
+2

不想骗我upvoted因为你说“哥们......” – 2013-04-11 13:25:49

+3

的代码墙'o.O' – 2013-04-11 13:36:34

+0

与@BartekBanachewicz同意...你真的添加更多的代码在这里比你应该。你不应该期望我们能够渡过这一切。更好地磨砺你的问题。 – johnbakers 2013-04-11 15:52:30

回答

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);** 
    //********************************************