2011-07-27 20 views
5

OpenGL ES 1.x'den 2.0'a karmaşıklıktaki atlayışla uğraşıyorum. Dikdörtgen bir düzleme bir doku uygulamak ve doku düzgün bir şekilde haritalandırılırken o düzlemi ölçeklendirip çevirmeye çalışıyorum.OpenGL texture geometriyi takip etmiyor

Sorum şu: Ben yanlış yapıyorum ve bunları çevirirken ve ölçeklendirirken uçaklarımı nasıl oluşturabileceğim?

benim işleyici sınıfını, kendilerini çizmek için kullanacağı nesneleri sınıfını ve benim köşe ve fragman shader'lar yayınlayacağız:

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 sınıfı:

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

} 

Parça Shader:

precision mediump float; 

uniform sampler2D u_texture; 

varying vec2 v_texcoord; 

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

Vertex Shader: Ben bu durumda (benim renderable köşelerini değiştirdiğinizde tüm her bölünmüş

enter image description here

: Böyle bir program çalıştırdığınızda

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

, benim beklenen sonuç elde 2) değerine göre, uçağımın şekli değişiyor, ancak doku beklediğim gibi hareket etmiyor. Emin değilim neden (bir açıklama güzel olurdu). Benim uçağın tepe noktalarını düzeltmek ve doku I (v_texcoord = a_texcoord;) vermek koordinatları kabul etmek vertex shader değiştirdiğinizde

enter image description here

, ben doğru boyutta kare olsun ama doku/meydan görünür değil tamamen beyazdır.

Ayrıca, spritelarımın taşınmasını ve ölçeklendirilmesini kolaylaştıracak yeniden kullanılabilir (RenderVisible) sınıfı için yöntemler yapmaya da çalışıyorum. Bunu nasıl yapabilirim?

+0

Eğer köşe programında doku-Coords hesaplamak ancak java kodunda belirtmek olanları kullanmayın ne olur? (Köşe programında: v_texcoord = a_texcoord;) –

+0

Doğru boyut karesini alıyorum ancak doku görünmüyor/kare tamamen beyaz. – Amplify91

cevap

3

Sizin doku koordinatları bu davranışın, bunu düzeltmek için neden sadece köşe gölgelendiricisi değiştirmektir, senin köşenin bir fonksiyonu koordinatları şunlardır:

v_texcoord = a_texcoord; 

Yani sürekli doku koordinatları kullanın. Ayrıca doku coord köşe niteliğini etkinleştirmeyi unutmayın:

GLES20.glEnableVertexAttribArray(texCoordHandle); 
+0

Sorunun sonunda bundan bahsetmiştim. Bunu denediğimde, doğru boyuttaki dikdörtgeni aldım, ama tamamen beyaz, doku yok. – Amplify91

+1

@ Amplify91 Güncellenmiş yanıtı görün, texcoord özniteliğini etkinleştirmediniz. –

+1

UGH! Teşekkür ederim! Biraz minik, aptal bir hata olması gerektiğini biliyordum. Sprite nasıl tercüme edileceğini ve ölçeklendirileceğini gösteren öneriniz nedir? – Amplify91