0

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

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

我尝试过的事情:

  1. 更改位图
    • 将其更改为没有 Alpha 通道的位图,均为 32x32 (2^5) 且均为 .png。
  2. 更改操作顺序
    • 我在我的实现中移动了 glBindTexture,所以我把它移回来,然后又移回来。
  3. 更改纹理参数
    • 我尝试了几种组合,没有一个使用 mip-mapping
  4. 改变我加载图像的方式
    • 从 BitmapFactory.decodeResource 到 BitmapFactory.decodeStream
  5. 将纹理移至所有可绘制文件夹
    • 在 raw 文件夹中也试过
  6. 在另一台设备上试过
    • 我朋友的 DROID (Froyo 2.2),我扎根的 NextBook (Gingerbread 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);
    }
}
}

边界框

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);
}
}
4

1 回答 1

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);**
    //********************************************
于 2013-04-14T18:09:05.583 回答