OpenGL ES:使用纹理:空白而不是纹理图像

时间:2012-02-19 09:51:52

标签: java android opengl-es render-to-texture

我在Android平台上编码。我正在尝试使用纹理(从Assets文件夹加载图像)来获得三角形。当我的应用程序运行时,它只是三角形的空白(不是我想要的纹理)。

我已经阅读了一些其他消息来源,说图像必须是2的幂。我检查过,我的形象是两个力量。 (128 x 128)。那个让我头痛的原因。

这是我的代码:(您应该在onDrawFrame方法中看到的主要代码,它包含我用于渲染的代码)

package com.test;

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

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

import android.app.Activity;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLUtils;
import android.os.Bundle;
import android.util.Log;

public class TextureTriangleTest extends Activity{

    GLSurfaceView glView;
    ByteBuffer byteBuffer;
    FloatBuffer vertices;
    AssetManager assets;

    @Override 
    public void onCreate(Bundle savedInstanceState){

        super.onCreate(savedInstanceState);
        assets = getAssets();

        int VERTEX_SIZE = (2+2)*4;
        byteBuffer = ByteBuffer.allocateDirect(3*VERTEX_SIZE);
        byteBuffer.order(ByteOrder.nativeOrder());
        vertices = byteBuffer.asFloatBuffer();
        vertices.put(new float[] { 0.0f, 0.0f, 0.0f, 1.0f,
                                   319.0f, 0.0f, 1.0f, 1.0f,
                                   160.0f, 479.0f, 0.5f, 0.0f } );
        vertices.flip();

        glView = new GLSurfaceView(this);
        glView.setRenderer(new Render());
        setContentView(glView);

    }



    class Render implements Renderer{

        @Override
        public void onDrawFrame(GL10 gl) {

            try {

                Bitmap bitmap = BitmapFactory.decodeStream(assets.open("bobrgb888.png"));
                int textureIds[] = new int[1];
                gl.glGenTextures(1, textureIds, 0);
                int textureId = textureIds[0];

                gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
                GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
                gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
                gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);
                gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);

                bitmap.recycle();

            } catch (IOException e) {
                Log.d("", "FAILED LOAD FILE");
                throw new RuntimeException("Couldn't load asset!");
            } 

            gl.glViewport(0, 0, glView.getWidth(), glView.getHeight());
            gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
            gl.glMatrixMode(GL10.GL_PROJECTION);
            gl.glLoadIdentity();
            gl.glOrthof(0, 320, 0, 480, 1, -1);

            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

            int VERTEX_SIZE = (2+2)*4;
            vertices.position(0);
            gl.glVertexPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices);
            vertices.position(2);
            gl.glTexCoordPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices);

            gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);

        }

        @Override
        public void onSurfaceChanged(GL10 gl, int width, int height) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            // TODO Auto-generated method stub

        }

    }

}

我的代码只是一个简单的例子。我有调试,一切都是真的。 (如:成功加载图片)。但是,我不知道如何调试OpenGL应用程序。 (这意味着:在调试时,我可以查看变量的参数,但我不知道它是怎么回事,因为OpenGL比Canvas太复杂 - 你只使用一行代码并且有结果:))

感谢您的帮助:)

2 个答案:

答案 0 :(得分:2)

喔。我已经修复了整个解决方案,下面是我的完整代码。我在这里发帖试图阅读我的长篇文章(^^)并需要一个真正的解决方案:)感谢SteveL建议我:)

在我的解决方案中,我有一些变化:    第一。性能:我将代码读取纹理放在onSurfaceCreate中。    第二。正如史蒂夫说的那样。我错过了gl.glEnable,我又重新gl.glBindTexture

再想一想,我看到那些错误真的很傻。仅仅因为我是OpenGL的新手:(

package com.test;

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

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

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.os.Bundle;

public class ColorTriangleTest extends Activity{

    GLSurfaceView glView;
    ByteBuffer byteBuffer;
    FloatBuffer vertices;

    public void onCreate(Bundle savedInstanceState){

        super.onCreate(savedInstanceState);

        int VERTEX_SIZE = (2+4)*4;
        byteBuffer = ByteBuffer.allocateDirect(3*VERTEX_SIZE);
        byteBuffer.order(ByteOrder.nativeOrder());
        vertices = byteBuffer.asFloatBuffer();
        vertices.put(new float[] { 0.0f, 0.0f, 1, 0, 0, 1,
                                   319.0f, 0.0f, 1, 1, 0, 1,
                                   160.0f, 479.0f, 1, 0, 1, 1 });
        vertices.flip();

        glView = new GLSurfaceView(this);
        glView.setRenderer(new Render());
        setContentView(glView);
    }

    class Render implements Renderer {

        @Override
        public void onDrawFrame(GL10 gl) {

            int VERTEX_SIZE = (2+4)*4;

            gl.glViewport(0, 0, glView.getWidth(), glView.getHeight());
            gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
            gl.glMatrixMode(GL10.GL_PROJECTION);
            gl.glLoadIdentity();
            gl.glOrthof(0, 320, 0, 480, 10, -10);

            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
            gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

            vertices.position(0);
            gl.glVertexPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices);
            vertices.position(2);
            gl.glColorPointer(4, GL10.GL_FLOAT, VERTEX_SIZE, vertices);

            gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);

        }

        @Override
        public void onSurfaceChanged(GL10 gl, int width, int height) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            // TODO Auto-generated method stub

        }

    }

}

答案 1 :(得分:0)

喔。我已经解决了我的问题。但我无法解释原因。 (我可以修复因为我喜欢互联网上的一些教程)。

这是我的代码。我指出了一些我已经改变的路线。请告诉我它为什么有效,请:

package com.test;

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

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

import android.app.Activity;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLUtils;
import android.os.Bundle;
import android.util.Log;

public class TextureTriangleTest extends Activity{

    GLSurfaceView glView;
    ByteBuffer byteBuffer;
    FloatBuffer vertices;
    AssetManager assets;

    @Override 
    public void onCreate(Bundle savedInstanceState){

        super.onCreate(savedInstanceState);
        assets = getAssets();

        int VERTEX_SIZE = (2+2)*4;
        byteBuffer = ByteBuffer.allocateDirect(3*VERTEX_SIZE);
        byteBuffer.order(ByteOrder.nativeOrder());
        vertices = byteBuffer.asFloatBuffer();
        vertices.put(new float[] { 0.0f, 0.0f, 0.0f, 1.0f,
                                   319.0f, 0.0f, 1.0f, 1.0f,
                                   160.0f, 479.0f, 0.5f, 0.0f } );
        vertices.flip();

        glView = new GLSurfaceView(this);
        glView.setRenderer(new Render());
        setContentView(glView);

    }



    class Render implements Renderer{

        @Override
        public void onDrawFrame(GL10 gl) {

            int a = 0;
            try {

                Bitmap bitmap = BitmapFactory.decodeStream(assets.open("bobrgb888.png"));
                int textureIds[] = new int[1];
                gl.glGenTextures(1, textureIds, 0);
                int textureId = textureIds[0];
                a= textureId;

                gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);  //this line
                GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
                gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
                gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);
                gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);  //and this line

                bitmap.recycle();

            } catch (IOException e) {
                Log.d("", "FAILED LOAD FILE");
                throw new RuntimeException("Couldn't load asset!");
            } 

            gl.glViewport(0, 0, glView.getWidth(), glView.getHeight());
            gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
            gl.glMatrixMode(GL10.GL_PROJECTION);
            gl.glLoadIdentity();
            gl.glOrthof(0, 320, 0, 480, 1, -1);

            //Here two lines that I added. Two lines I have declared above in try_catch
            //So, WHY I NEED TO DECLARE AGAIN ??!!!
            gl.glEnable(GL10.GL_TEXTURE_2D);
            gl.glBindTexture(GL10.GL_TEXTURE_2D, a);

            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

            int VERTEX_SIZE = (2+2)*4;
            vertices.position(0);
            gl.glVertexPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices);
            vertices.position(2);
            gl.glTexCoordPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices);

            gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);

        }

        @Override
        public void onSurfaceChanged(GL10 gl, int width, int height) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            // TODO Auto-generated method stub

        }

    }

}

现在对我有用:)谁能解释为什么?? !!