Текстура OpenGL не соответствует геометрии

Я борюсь с скачком сложности с OpenGL ES 1.x на 2.0. Я пытаюсь применить текстуру к прямоугольной плоскости, а затем могу масштабировать и переводить эту плоскость, сохраняя при этом текстуру правильно сопоставленной.

У меня вопрос: что я делаю не так и как я смогу текстурировать свои самолеты, переводя и масштабируя их?

Я опубликую свой класс средства визуализации, класс, который объекты будут использовать для отрисовки самих себя, а также мои вершинные и фрагментные шейдеры:

GL Renderer:

package com.detour.raw;

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

import android.content.Context;
import android.graphics.Bitmap;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;

public class GameRenderer implements GLSurfaceView.Renderer{

private static final String TAG = "GameRenderer";
Context mContext;
Bitmap bitmap;

private float red = 0.5f;
private float green = 0.5f;
private float blue = 0.5f;

Shader shader;
int program;
FPSCounter fps;
Sprite sprite;
Sprite sprite2;
int x = 0;

private int muMVPMatrixHandle;

private float[] mMVPMatrix = new float[16];
private float[] mProjMatrix = new float[16];
private float[] mMVMatrix = new float[16];
//private float[] mVMatrix = new float[16];
//private float[] mMMatrix = new float[16];
//private float[] mVPMatrix = new float[16];
//private float[] mIMatrix = new float[16];



public GameRenderer(Context context){
    mContext = context;

    //create objects/sprites
    sprite = new Sprite(mContext);
    sprite2 = new Sprite(mContext);
    fps = new FPSCounter();
}

@Override
public void onDrawFrame(GL10 gl) {

    GLES20.glClearColor(red, green, blue, 1.0f);
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

    GLES20.glUseProgram(program);
    //Matrix.setIdentityM(mIMatrix, 0);

    //Matrix.multiplyMM(mMVMatrix, 0, mVMatrix, 0, mMMatrix, 0);
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVMatrix , 0);

    GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);

    sprite.draw();
    /*if(x>3){
        x=0;
    }
    if(x%2==0){
        sprite.draw();
    }else{
        sprite2.draw();
    }
    x++;*/

    //fps.calculate();
    //fps.draw(gl);
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {

    GLES20.glViewport(0, 0, width, height);
    float ratio = ((float)(width))/((float)(height));
    Matrix.orthoM(mProjMatrix, 0, -ratio, ratio, -1, 1, 0.5f, 10);
    Matrix.setLookAtM(mMVMatrix, 0, 0, 0, 1.0f, 0.0f, 0f, 0f, 0f, 1.0f, 0.0f);
}

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

    /*int error = GLES20.glGetError();
    Log.d(LOG_TAG, ""+error);*/

    shader = new Shader(R.raw.sprite_vs, R.raw.sprite_fs, mContext);
    program = shader.getProgram();

    muMVPMatrixHandle = GLES20.glGetUniformLocation(program, "u_MVPMatrix");

    GLES20.glEnable(GLES20.GL_TEXTURE_2D);
    GLES20.glEnable(GLES20.GL_DEPTH_TEST);
    GLES20.glClearDepthf(1.0f);
    GLES20.glDepthFunc(GLES20.GL_LEQUAL);
    GLES20.glDepthMask(true);
    GLES20.glEnable(GLES20.GL_CULL_FACE);
    GLES20.glCullFace(GLES20.GL_BACK);
    GLES20.glClearColor(red, green, blue, 1.0f);


    sprite.loadGLTexture(R.drawable.raw1a, program);
    sprite2.loadGLTexture(R.drawable.raw2, program);

    System.gc();
}

}

Drawable class:

package com.detour.raw;

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

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLUtils;

public class RenderVisible implements Renderable{

Context mContext;
Bitmap bitmap;

private int vertexHandle;
private int texCoordHandle;
private int textureHandle;

private int[] textures = new int[1];

private float textureCoordinates[] = {
        0.0f, 0.0f,
        0.0f, 1.0f,
        1.0f, 1.0f,
        1.0f, 0.0f
        };

private float vertices[] = {
        -1.0f,  1.0f,// 0.0f,
        -1.0f, -1.0f,// 0.0f,
         1.0f, -1.0f,// 0.0f,
         1.0f,  1.0f// 0.0f,
         };

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

private FloatBuffer vertexBuffer;
private FloatBuffer textureBuffer;
private ShortBuffer indexBuffer;


public RenderVisible(Context context){

    mContext = context;

    ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
    vbb.order(ByteOrder.nativeOrder());
    vertexBuffer = vbb.asFloatBuffer();
    vertexBuffer.put(vertices);
    vertexBuffer.position(0);

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

    ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
    ibb.order(ByteOrder.nativeOrder());
    indexBuffer = ibb.asShortBuffer();
    indexBuffer.put(indices);
    indexBuffer.position(0);

}

@Override
public void draw() {

    GLES20.glEnableVertexAttribArray(vertexHandle);
    GLES20.glVertexAttribPointer(vertexHandle, 2, GLES20.GL_FLOAT, false, 0, vertexBuffer);
    GLES20.glVertexAttribPointer(texCoordHandle, 2, GLES20.GL_FLOAT, false, 0, textureBuffer);
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
    GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length, GLES20.GL_UNSIGNED_SHORT, indexBuffer);

}

@Override
public void loadGLTexture(int id, int program) {

    vertexHandle = GLES20.glGetAttribLocation(program, "a_position");
    texCoordHandle = GLES20.glGetAttribLocation(program, "a_texcoord");
    textureHandle = GLES20.glGetUniformLocation(program, "u_texture");

    bitmap = BitmapFactory.decodeResource(mContext.getResources(), id);
    /*InputStream is = mContext.getResources().openRawResource(id);
    try {
        bitmap = BitmapFactory.decodeStream(is);
    } finally {
        try {
            is.close();
            is = null;
        } catch (IOException e) {
        }
    }*/

    GLES20.glGenTextures(1, textures, 0);
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
    GLES20.glUniform1i(textureHandle, 0);

    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);

    //GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, FRAME_WIDTH, FRAME_HEIGHT, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, byteBuf);//(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);

    bitmap.recycle();
}

}

Fragment Shader:

precision mediump float;

uniform sampler2D u_texture;

varying vec2 v_texcoord;

void main()
{
    gl_FragColor = texture2D(u_texture, v_texcoord);
}

Vertex Shader :

attribute vec2 a_position;
attribute vec2 a_texcoord;

uniform mat4 u_MVPMatrix;

varying vec2 v_texcoord;

void main()
{
    gl_Position = vec4(a_position, 0.0, 1.0) * u_MVPMatrix;
    v_texcoord = a_position * vec2(0.5, -0.5) + vec2(0.5);
}

Когда я запускаю программу вот так, я получаю ожидаемый результат:

enter image description here

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

enter image description here

Когда я исправляю вершины моей плоскости и меняю вершинный шейдер, чтобы он принял координаты текстуры, я даю это ( v_texcoord = a_texcoord; ) , Я получаю квадрат правильного размера, но текстура не видна / квадрат полностью белый.

Я также пытаюсь создать методы для отрисовываемого класса (RenderVisible), которые упростили бы перемещение и масштабирование моих спрайтов. Как я могу это сделать?

5
задан Amplify91 27 July 2011 в 17:24
поделиться