简体   繁体   中英

Render image for 2D game use in OpenGL ES for android

EDIT: Solved it! I made stupid mistake, I had a textureId I'd forgotten about when it was textureID I should use.

Okay, I am fully aware that this is a recurring question, and that there is a lot of tutorials and open source code. But I've been trying as best as I can for quite a while here, and my screen is still blank (with whatever color I set using glClearColor()).

So, I would be grateful for some pointers to what I'm doing wrong, or even better, some working code that will render a resource image.

I'll show what I've got so far (by doing some crafty copy-pasting) in my onDrawFrame of the class that implements the Renderer. I've removed some of the jumping between methods, and will simply paste it in the order it is executed.

Feel free to disregard my current code, I'm more than happy to start over, if anyone can give me a working piece of code.

Setup:

    bitmap = BitmapFactory.decodeResource(panel.getResources(), 
            R.drawable.test); 
    addGameComponent(new MeleeAttackComponent());

    // Mapping coordinates for the vertices
    float textureCoordinates[] = { 0.0f, 2.0f, //
            2.0f, 2.0f, //
            0.0f, 0.0f, //
            2.0f, 0.0f, //
    };

    short[] indices = new short[] { 0, 1, 2, 1, 3, 2 };

    float[] vertices = new float[] { -0.5f, -0.5f, 0.0f,
                                      0.5f, -0.5f, 0.0f,
                                     -0.5f,  0.5f, 0.0f,
                                      0.5f, 0.5f, 0.0f };

    setIndices(indices);
    setVertices(vertices);
    setTextureCoordinates(textureCoordinates);

protected void setVertices(float[] vertices) {
    // a float is 4 bytes, therefore we multiply the number if
    // vertices with 4.
    ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
    vbb.order(ByteOrder.nativeOrder());
    mVerticesBuffer = vbb.asFloatBuffer();
    mVerticesBuffer.put(vertices);
    mVerticesBuffer.position(0);
}


protected void setIndices(short[] indices) {
    // short is 2 bytes, therefore we multiply the number if
    // vertices with 2.
    ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
    ibb.order(ByteOrder.nativeOrder());
    mIndicesBuffer = ibb.asShortBuffer();
    mIndicesBuffer.put(indices);
    mIndicesBuffer.position(0);
    mNumOfIndices = indices.length;
}


protected void setTextureCoordinates(float[] textureCoords) { 

    // float is 4 bytes, therefore we multiply the number of
    // vertices with 4.
    ByteBuffer byteBuf = ByteBuffer
            .allocateDirect(textureCoords.length * 4);
    byteBuf.order(ByteOrder.nativeOrder());
    mTextureBuffer = byteBuf.asFloatBuffer();
    mTextureBuffer.put(textureCoords);
    mTextureBuffer.position(0);
}

//The onDrawFrame(GL10 gl)

    gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
    gl.glLoadIdentity();
    gl.glTranslatef(0, 0, -4);

    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    // Specifies the location and data format of an array of vertex
    // coordinates to use when rendering.
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVerticesBuffer);

    if(shoudlLoadTexture){
        loadGLTextures(gl);
        shoudlLoadTexture = false;
    }

    if (mTextureId != -1 && mTextureBuffer != null) {
        gl.glEnable(GL10.GL_TEXTURE_2D);
        // Enable the texture state
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        // Point to our buffers
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTextureBuffer);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureId);
    }

    gl.glTranslatef(posX, posY, 0);
    // Point out the where the color buffer is.
    gl.glDrawElements(GL10.GL_TRIANGLES, mNumOfIndices,
            GL10.GL_UNSIGNED_SHORT, mIndicesBuffer);
    // Disable the vertices buffer.
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

    if (mTextureId != -1 && mTextureBuffer != null) {
        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    }


 private void loadGLTextures(GL10 gl) {

    int[] textures = new int[1];
    gl.glGenTextures(1, textures, 0);
    mTextureID = textures[0];

    gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);

    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
    gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE);

    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

}

It doesn't crash, no exceptions, simply a blank screen with color. I've printed stuff in there, so I'm pretty sure it is all executed.

I know it's not optimal to just paste code, but at the moment, I just want to be able to do what I was able to do with canvas :)

Thanks a lot

If you're getting the background colour, that means your window is properly set up. OpenGL is connected to that area of the screen.

However, OpenGL clips to the near and far clip planes, ensuring that objects don't cross or intersect the camera (which, both mathematically and logically, doesn't make sense) and that objects too far away don't appear. So if you've not set up modelview and projection correctly, it's probable that all your geometry is being clipped.

Modelview is used to map from world to eye space. Projection maps from eye space to screen space. So a typical applications uses the former to position objects within the scene, and position the scene relative to the camera, then the latter deals with whether the camera sees with perspective or not, how many world units make how many screen units, etc.

If you look at examples like this one , particularly onSurfaceChanged , you'll see an example of a perspective projection with a camera fixed at the origin.

Because the camera is at (0, 0, 0), leaving your geometry on z = 0 as your code does will cause it to be clipped. In that example code they've set the near clip plane to be at z = 0.1, so in your existing code you could change:

gl.glTranslatef(posX, posY, 0);

To:

gl.glTranslatef(posX, posY, -1.0);

To push your geometry back sufficiently far to appear on screen.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM