2011-07-27 13 views
5

Mam problem ze skokiem złożoności od OpenGL ES 1.x do 2.0. Próbuję zastosować teksturę do płaszczyzny prostokątnej, a następnie przeskalować i przetłumaczyć tę płaszczyznę, zachowując odpowiednią strukturę tekstury.Tekst OpenGL nieprzestrzegający geometrii

Moje pytanie brzmi: co robię źle i w jaki sposób będę w stanie teksturować moje samoloty podczas ich tłumaczenia i skalowania?

będę pisać moją klasę renderujący, klasa, że ​​obiekty będą wykorzystywać do rysowania siebie, a mój wierzchołków i fragmentów shaderów:

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

} 

rozciągliwej klasa:

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

Kiedy uruchomić program tak, mam mój oczekiwany rezultat:

enter image description here

Kiedy zmienić wierzchołki moim renderable (w tym przypadku wszystko podzielone każdy wartość o 2), zmienia się kształt mojej płaszczyzny, ale tekstura nie porusza się tak, jak się spodziewałam. Nie jestem pewien dlaczego (wyjaśnienie byłoby miłe).

enter image description here

Kiedy rozwiązać wierzchołki mojego samolotu i zmienić vertex shader, aby zaakceptować współrzędne tekstury daję (v_texcoord = a_texcoord;), uzyskać odpowiedni rozmiar tekstury kwadratowy ale nie jest widoczny/kwadrat jest całkowicie biały.

Próbuję również tworzyć metody dla renderowalnej klasy (RenderVisible), która ułatwiłaby przenoszenie i skalowanie moich ikonek. Jak mogę to zrobić?

+0

Co się stanie, jeśli nie obliczyć tekstury coords w programie wierzchołków, ale korzystać z tych, które określają w kodzie Java? (W programie wierzchołków: v_texcoord = a_texcoord;) –

+0

Otrzymuję prawidłowy rozmiar kwadratu, ale tekstura nie jest widoczna/kwadrat jest całkowicie biały. – Amplify91

Odpowiedz

3

współrzędne tekstury są funkcją swojej współrzędne wierzchołka, to dlaczego z tego zachowania, aby go naprawić, wystarczy zmienić w swoim vertex shader:

v_texcoord = a_texcoord; 

więc używać stałych współrzędnych tekstur. Należy również pamiętać, aby umożliwić tekstury atrybut coord wierzchołków:

GLES20.glEnableVertexAttribArray(texCoordHandle); 
+0

Wspomniałem o tym na końcu mojego pytania. Kiedy próbuję tego, otrzymuję prostokąt o prawidłowym rozmiarze, ale jest on całkowicie biały, bez tekstury. – Amplify91

+1

@ Amplify91 Zobacz zaktualizowaną odpowiedź, nie włączono atrybutu texcoord. –

+1

UGH! Dziękuję Ci! Wiedziałem, że musi to być jakaś drobna, głupia pomyłka. Jaka jest Twoja sugestia, jak tłumaczyć i skalować duszki? – Amplify91

Powiązane problemy