2014-04-08 18 views
5

in questo momento sto cercando di creare la grafica per un piccolo gioco. Per prima cosa sto cercando di creare i miei ostacoli. Questi sono solo rettangoli. Provo a rendere statici tutti i dati, che è lo stesso per tutti i rettangoli. Colore, Startposition, shader. Sto cercando di farlo, perché una versione precedente funzionava, aveva problemi di prestazioni. Voglio anche passare a VBO quando ho questo lavoro. Questi oggetti saranno spostati e ridimensionati (non ancora nel codice) individuali.OpenGL ES 2.0 IllegalArgumentException

Voglio provare il mio codice ma ho un errore che non capisco. Qui è la mia uscita Logcat

04-08 15:03:05.573: E/AndroidRuntime(3051): FATAL EXCEPTION: GLThread 4926 
04-08 15:03:05.573: E/AndroidRuntime(3051): Process: com.example.jump, PID: 3051 
04-08 15:03:05.573: E/AndroidRuntime(3051): java.lang.IllegalArgumentException: length - offset < count*4 < needed 
04-08 15:03:05.573: E/AndroidRuntime(3051):  at android.opengl.GLES20.glUniform4fv(Native Method) 
04-08 15:03:05.573: E/AndroidRuntime(3051):  at com.example.jump.ObstacleGL.initialize(ObstacleGL.java:82) 
04-08 15:03:05.573: E/AndroidRuntime(3051):  at com.example.jump.GameRenderer.onSurfaceCreated(GameRenderer.java:57) 
04-08 15:03:05.573: E/AndroidRuntime(3051):  at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1501) 
04-08 15:03:05.573: E/AndroidRuntime(3051):  at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240) 

Questo mi confonde, la lunghezza è di 3, l'offset è 0, contare * 4 è 4. non so quale valore "necessario" è. Immagino che questo sia il luogo in cui l'affermazione fallisce.

e qui è la mia classe. chiamo il metodo di inizializzazione in onSurfacecreated

package com.example.jump; 

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

import android.opengl.GLES20; 
import android.opengl.Matrix; 

public class ObstacleGL { 
    static final int COORDS_PER_VERTEX = 3; 
    static final int vertexStride = COORDS_PER_VERTEX * 4; 
    private static final String vertexShaderCode = 
      "uniform mat4 uMVPMatrix;" + 
      "attribute vec4 vPosition;" + 
      "void main() {" + 
      " gl_Position = uMVPMatrix * vPosition;" + 
      "}"; 
    private static final String fragmentShaderCode = 
      "precision mediump float;" + 
      "uniform vec4 vColor;" + 
      "void main() {" + 
      " gl_FragColor = vColor;" + 
      "}"; 

    private static float [] coords={ 
      //x,y,z z=0 
      1,1,0,  //ol 
      1,0,0,    //ul 
      1.2f,0,0,  //ur 
      1.2f,1,0 //or 
    }; 
    private static final short[] drawOrder = { 0, 1, 2, 0, 2, 3 }; 
    private static int fragmentShader; 
    private static int vertexShader; 
    private static int mProgram; 
    private static float[] color={0.33f,1,0.33f}; 
    private static int colorHandle; 
    private static int positionHandle; 
    private static FloatBuffer vertexBuffer; 
    private static ShortBuffer drawListBuffer; 

    //Gamelogic 
    public final int id; 
    private float x,y,height,width; 
    private float xOffset,yOffset; 
    //Opengl 
    private int matrixHandle; 
    private int vertexCount; 
    private float[] translationMatrix=new float[16]; 


    public static void initialize(){ 

     fragmentShader=GameRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,fragmentShaderCode); 
     vertexShader=GameRenderer.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode); 

     ByteBuffer bb; 
     ByteBuffer dlb; 
     bb= ByteBuffer.allocateDirect(coords.length*4); 
     bb.order(ByteOrder.nativeOrder()); 
     vertexBuffer=bb.asFloatBuffer(); 
     vertexBuffer.put(coords); 
     vertexBuffer.position(0); 

     dlb=ByteBuffer.allocateDirect(12); //drawOrder.length*2 
     dlb.order(ByteOrder.nativeOrder()); 
     drawListBuffer=dlb.asShortBuffer(); 
     drawListBuffer.put(drawOrder); 
     drawListBuffer.position(0); 
     mProgram=GLES20.glCreateProgram(); 

     GLES20.glAttachShader(mProgram, fragmentShader); 
     GLES20.glAttachShader(mProgram, vertexShader); 


     colorHandle=GLES20.glGetUniformLocation(mProgram, "vColor"); 
     positionHandle=GLES20.glGetAttribLocation(mProgram, "vPosition"); 
     GLES20.glLinkProgram(mProgram); 
     GLES20.glVertexAttribPointer(positionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false,vertexStride , vertexBuffer); 
     GLES20.glUniform4fv(colorHandle, 1, color,0); 
    } 

    public ObstacleGL(int id,float x, float y, float height,float width) 
    { 
     this.id=id; 
     //not used at the moment 
     this.x=x; 
     this.xOffset=0; 
     this.y=0; 
     this.yOffset=0; 
     this.height=height; 
     this.width=width; 
     // 
     vertexCount=coords.length/COORDS_PER_VERTEX; 

     Matrix.setIdentityM(translationMatrix, 0); 
     //getting the handle to set new translations 
     matrixHandle=GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); 
    } 

    public void draw() 
    { 
     GLES20.glUseProgram(mProgram); 
     //here I give the new position 
     GLES20.glUniformMatrix4fv(matrixHandle, 1,false, translationMatrix, 0); 
     GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, vertexCount); 
     GLES20.glDisableVertexAttribArray(positionHandle); 
    } 
    public void moveX(float x) 
    //moves the Obstacle on the x axies 
    { 
     this.xOffset+=x; 
     Matrix.translateM(translationMatrix, 0, x, 0, 0); 
    } 
    public void moveY(float y) 
    //moves the Obstacle on the y axies 
    { 
     this.yOffset+=y; 
     Matrix.translateM(translationMatrix, 0, 0, y, 0); 
    } 
} 

posso anche mostrare il mio renderer Classe

package com.example.jump; 

import java.util.LinkedList; 

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

import android.opengl.GLES20; 
import android.opengl.GLSurfaceView; 

public class GameRenderer implements GLSurfaceView.Renderer,GameVisualisation { 


    private LinkedList<ObstacleGL> obstacleList=new LinkedList<ObstacleGL>(); 
    private LinkedList<Obstacle> obstacleQueue= new LinkedList<Obstacle>(); 

    //Renderer Methoden 
    @Override 
    public void onDrawFrame(GL10 gl) { 
     GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); 
     createNewObstacles(); 


     for (int i = 0; i < obstacleList.size(); i++) { 
      obstacleList.get(i).draw(); 
     } 
    } 

    public static int loadShader(int type, String shadercode) 
    { 
     int shader=GLES20.glCreateShader(type); 
     GLES20.glShaderSource(shader, shadercode); 
     GLES20.glCompileShader(shader); 
     return shader; 
    } 

    private void createNewObstacles() { 
     while(!obstacleQueue.isEmpty()){ 
      Obstacle obs=obstacleQueue.poll(); 
      obstacleList.add(new ObstacleGL(obs.id,(float)obs.xPosition,(float)obs.yPosition,(float)obs.height,(float)obs.width)); 
     } 

    } 

    @Override 
    public void onSurfaceChanged(GL10 gl, int width, int height) { 
     GLES20.glViewport(0, 0, width, height); 
    } 

    @Override 
    public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
     GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f); 
     ObstacleGL.initialize(); 
    } 
//more gamerelated stuff is happening here 
} 
+1

senso, farò un copia e incolla e verificare se riesco a capire qualcosa – Lunchbox

+0

Ho anche aggiunto la mia classe di un renderer, se si desidera guardalo, le funzioni che gli usi gamelogici sono nascosti. – stubiklaus

risposta

3

così ho fatto il lavoro stesso. Il problema sembrava essere che non accetta un array Float di dimensione 3 con un uniforme vec4. La soluzione era di aggiungere il canale alfa al mio array di colori.

ho sostituito

private static float[] color={0.33f,1,0.33f}; 

con

private static float[] color={0.33f,1,0.33f,1};