Как мне рендерить текстуры на орто-проекции в Android - PullRequest
1 голос
/ 14 апреля 2011

Привет. В прошлом я занимался OpenGL и, насколько я понял, лучший способ сделать 2d-игры со спрайтовой анимацией - это исключить плоскость z и настроить ортографическую проекцию, чтобы вы могли просто использовать декартовы координаты для текстур и рисования. позиций.

Итак, я пытался реализовать это в Android. Я просто использовал все встроенные функции рисования, но рендеринг нескольких сотен изображений отдельно с помощью функций vanilla drawbitmap убивал мою частоту кадров.

Прямоугольник отображается на экране все в порядке, но текстура отказывается показывать. если бы вы могли взглянуть и дать мне знать, где я иду не так, я был бы очень благодарен. Имейте в виду, что у меня нет почти полного понимания opengl, как хотелось бы. Я уважаю любого, кто может обернуть голову вокруг этого материала.

Это класс спрайта, который рисует прямоугольник со связанной текстурой:

public class Sprite {

private FloatBuffer vertexBuffer;   // buffer holding the vertices
private FloatBuffer textureBuffer;
private int[] textures = new int[1];


private float vertices[] = {
         0.0f,  0.0f,
         0.0f, 32.0f,
         32.0f,  0.0f,
         32.0f, 32.0f

};

private float texture[] = {
        0.0f,  0.0f,
         0.0f, 16.0f,
         16.0f,  0.0f,
         16.0f, 16.0f

};

public Sprite() {
    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
    byteBuffer.order(ByteOrder.nativeOrder());
    vertexBuffer = byteBuffer.asFloatBuffer();
    vertexBuffer.put(vertices);
    vertexBuffer.position(0);

    byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
    byteBuffer.order(ByteOrder.nativeOrder());
    textureBuffer = byteBuffer.asFloatBuffer();
    textureBuffer.put(texture);
    textureBuffer.position(0);

}

public void loadGLTexture(GL10 gl, Context context)
{
    Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), 
            R.drawable.charactersprites);

    gl.glGenTextures(1, textures, 0);
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

    //Not sure if I need these...
    //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_LINEAR);

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

}

/** The draw method for the triangle with the GL context */
public void draw(GL10 gl) {
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);


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

    //gl.glFrontFace(GL10.GL_CW);//is this necessary?

    // set the colour for the triangle
    //gl.glColor4f(0.0f, 1.0f, 0.0f, 0.5f);

    // Point to our vertex buffer
    gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexBuffer);
    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);


    // Draw the vertices as triangle strip
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 2);

    //Disable the client state before leaving
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

}
}

И это средство визуализации ... Я передаю srfaceview, чтобы удержать его, чтобы получить высоту и ширину проекции

public class GlRenderer implements Renderer {

private Sprite sprite;
private GLSurfaceView surfaceView;
private Context context;

/** Constructor to set the handed over context */
public GlRenderer(GLSurfaceView surfaceView, Context context) {
    this.sprite = new Sprite();
    this.surfaceView = surfaceView;
    this.context = context;
}

@Override
public void onDrawFrame(GL10 gl) {
    // clear Screen and Depth Buffer
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    gl.glMatrixMode(GL10.GL_PROJECTION);

    // Reset the Modelview Matrix
    gl.glLoadIdentity();
    gl.glOrthof(0.0f, surfaceView.getWidth(), surfaceView.getHeight(), 0.0f, -1.0f, 1.0f);

    sprite.draw(gl);    

}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    sprite.loadGLTexture(gl, this.context);

    gl.glEnable(GL10.GL_TEXTURE_2D);
    gl.glShadeModel(GL10.GL_SMOOTH);
    gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
    gl.glClearDepthf(1.0f); 
    gl.glEnable(GL10.GL_DEPTH_TEST);
    gl.glDepthFunc(GL10.GL_LEQUAL);

    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);     
}
}

Ответы [ 3 ]

0 голосов
/ 09 июня 2011

Ниже работает на моем Galaxy S, но у меня возникают проблемы с настройкой его на HTC моего друга с помощью проекторов. Хотя они работают в модельном пространстве ... Не могли бы вы попробовать?

public void draw(GL10 gl) {
    gl.glActiveTexture(GL10.GL_TEXTURE0);

    gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
    gl.glEnable(GL10.GL_TEXTURE_2D);
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mCoordinateBuffer);

    // Draw the mesh
    gl.glFrontFace(GL10.GL_CCW);
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
    gl.glNormalPointer(GL10.GL_FLOAT, 0, mNormalBuffer);
    gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, mIndexBuffer.limit(), GL10.GL_UNSIGNED_BYTE, mIndexBuffer);

    // Disable texture
    gl.glDisable(GL10.GL_TEXTURE_2D);
    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}

public void loadTexture(Context context, GL10 gl) {
    Bitmap bmp;
    try {
            bmp = BitmapFactory.decodeStream(context.getResources().openRawResource(R.drawable.texture_loading));

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

            // Mendatory, tells openGL how to render the texture, nearest will look sharp, smooth will look blurry
            gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
            gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);

            // Not mendatory, tells openGL what to do when sprite is bigger than object
            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);

            // Mendatory, 
            // GL_REPLACE replaces all color info, 
            // GL_MODULATE modulates, texture will be affected by lightning 
            gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE);

            bmp.recycle();
    } catch (Error e) {

    }

} 
0 голосов
/ 10 июня 2011

Попробуйте установить текстуру среды на GL_REPLACE (используя glTexEnv).Если установлено значение GL_MODULATE, цвет текстуры будет умножен на текущий цвет (или цвет освещения, если он включен), а если этот цвет черный, то результат будет просто черным.

0 голосов
/ 15 апреля 2011

Вы пробовали

glActiveTexture(GL10.GL_TEXTURE0);

перед рендерингом спрайта?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...