Java OpenGL纹理不遵循几何体

Java OpenGL纹理不遵循几何体,java,android,opengl-es,opengl-es-2.0,Java,Android,Opengl Es,Opengl Es 2.0,我正在与OpenGLES1.x到2.0之间复杂度的跳跃作斗争。我试图将纹理应用于矩形平面,然后能够缩放和平移该平面,同时保持纹理正确映射 我的问题是:我做错了什么?在平移和缩放平面时,我将如何对平面进行纹理处理 我将发布渲染器类、对象用于绘制自身的类以及顶点和片段着色器: GL渲染器: package com.detour.raw; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khrono

我正在与OpenGLES1.x到2.0之间复杂度的跳跃作斗争。我试图将纹理应用于矩形平面,然后能够缩放和平移该平面,同时保持纹理正确映射

我的问题是:我做错了什么?在平移和缩放平面时,我将如何对平面进行纹理处理

我将发布渲染器类、对象用于绘制自身的类以及顶点和片段着色器:

GL渲染器:

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();
}

}
可提取类别:

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();
}

}
片段着色器:

precision mediump float;

uniform sampler2D u_texture;

varying vec2 v_texcoord;

void main()
{
    gl_FragColor = texture2D(u_texture, v_texcoord);
}
顶点着色器:

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);
}
当我像这样运行程序时,我得到了预期的结果:

当我更改可渲染对象的顶点时(在本例中,所有顶点都将每个值除以2),平面的形状将发生更改,但纹理不会以我所期望的方式随之移动。我不知道为什么(解释一下就好了)


当我修复平面的顶点并更改顶点着色器以接受我给它的纹理坐标(
v_texcoord=a_texcoord;
)时,我得到了正确大小的正方形,但纹理不可见/正方形完全为白色


我还尝试为renderable(RenderVisible)类创建方法,以简化精灵的移动和缩放。我该怎么做呢?

纹理坐标是顶点坐标的函数,这就是为什么会出现这种行为,要解决它,只需更改顶点着色器:

v_texcoord = a_texcoord;
所以你使用恒定的纹理坐标。还请记住启用纹理坐标顶点属性:

GLES20.glEnableVertexAttribArray(texCoordHandle);

如果不在vertex程序中计算纹理坐标,而是使用java代码中指定的坐标,会发生什么?(在顶点程序中:v_texcoord=a_texcoord;)我得到了正确大小的正方形,但纹理不可见/正方形是完全白色的。我在问题的最后提到了这一点。当我尝试这样做时,我得到了正确大小的矩形,但它是完全白色的,没有纹理。@如果看到更新的答案,您没有启用texcoord属性。啊!非常感谢。我知道这一定是个小小的愚蠢的错误。你对如何翻译和缩放精灵有什么建议?