OpenGL ES: использование текстуры: чистый белый вместо текстуры изображения - PullRequest
1 голос
/ 19 февраля 2012

Я пишу код на платформе Android.Я пытаюсь использовать текстуру (загрузить изображение из папки Assets) для треугольника.Когда мое приложение запускается, оно просто пустым белым в треугольнике (не текстура, что я хочу).

Я прочитал другой источник, который говорит, что изображение должно быть степенью двойки.И я проверил, мое изображение является степенью двойки.(128 х 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 ]

2 голосов
/ 19 февраля 2012

О.Я исправил все мои решения, и ниже мой полный код.Я написал здесь для тех, кто пытается прочитать мой длинный пост (^^) и ему нужно реальное решение :) Благодаря 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

        }

    }

}
0 голосов
/ 19 февраля 2012

О. Я исправил свою проблему. Но я не могу объяснить почему. (Я могу исправить, потому что мне нравится какой-то учебник в Интернете).

Вот мой код. Я указал некоторые строки, которые я изменил. Скажите, пожалуйста, почему это работает, пожалуйста:

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

        }

    }

}

Это работает для меня сейчас :) Кто может объяснить, почему ?? !!

...