2011-07-27 56 views
5

我正在为从OpenGL ES 1.x到2.0的复杂性的跳跃而挣扎。我试图将纹理应用于矩形平面,然后能够在保持纹理正确映射的同时对该平面进行缩放和平移。OpenGL纹理不遵循几何图形

我的问题是:我做错了什么,以及如何在翻译和缩放它们的同时对我的飞机进行贴图?

我会后我的渲染器类,即对象将用来绘制自己的班级,和我的顶点和片段着色器:

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

当我运行这样的程序,我得到我预期的结果:

enter image description here

当我改变我的渲染的顶点(在这种情况下,所有划分出的每个值除以2),我的平面形状会发生变化,但纹理不会按照我所期望的方式移动。我不确定为什么(解释会很好)。

enter image description here

当我解决我的飞机的顶点和改变顶点着色器接受纹理坐标我给它(v_texcoord = a_texcoord;),我得到正确的大小广场,但质地是不可见/平方是完全白色的。

我也在尝试为可渲染(RenderVisible)类制作方法,以便于移动和缩放我的精灵。我该怎么做?

+0

如果您不计算顶点程序中的纹理坐标但使用您在java代码中指定的纹理坐标,会发生什么情况? (在顶点程序中:v_texcoord = a_texcoord;) –

+0

我得到正确的大小正方形,但纹理不可见/正方形完全是白色的。 – Amplify91

回答

3

你的纹理坐标是你的顶点坐标的函数,这是为什么这种行为,解决它,只是在你的顶点着色器更改:

v_texcoord = a_texcoord; 

所以,你用你的不变纹理坐标。还请记住启用纹理坐标顶点属性:

GLES20.glEnableVertexAttribArray(texCoordHandle); 
+0

我在我的问题结尾处提到了这个问题。当我尝试时,我得到正确的大小的矩形,但它是完全白色的,没有纹理。 – Amplify91

+1

@ Amplify91查看最新的答案,你没有启用texcoord attrib。 –

+1

UGH!谢谢!我知道它必须是一个微不足道的,愚蠢的错误。对于如何翻译和缩放精灵,你有什么建议? – Amplify91