Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL ES 2.0 IllegalArgumentException

right now i'm trying to create the graphics for a little game. First I'm trying to create my obstacles. These are just rectangles. I try to make all data, which is the same for all rectangles, static. Color,Startposition,shader. I'm trying to to this, cause an earlier version which worked, had performance problems. I also want to switch to VBOs when i got this working. These Objects will be moved and scaled(not in code yet) individual.

I want to try my Code but i face an error which i don't understand. Here is my Logcat output

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)

This confuses me, the length is 3, the offset is 0, count*4 is 4. I don't know what value "needed" is. I excpect this to be the place where the statement fails.

and here is my Class. I call the initialisation method 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);
    }
}

I can also show you my Renderer Class

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
}
like image 217
stubiklaus Avatar asked Oct 02 '22 02:10

stubiklaus


1 Answers

So i made it work myself . The problem seemed to be that he doesn't accept a Size 3 Float array vor a vec4 Uniform. The Solution was to add the alpha channel to my color array.

i replaced

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

with

private static float[] color={0.33f,1,0.33f,1};
like image 192
stubiklaus Avatar answered Oct 03 '22 14:10

stubiklaus