Odysseus
Odysseus

Reputation: 1092

Error passing vertices to shader

I'm beginning simple 2d gles 2.0 android application. For some strange reason I always get one point in the center of the screen instead of vertex coordinates passed to the shader. I'm clearly doing something wrong. Can't figure what. Lonely point P.S. I'm not using any projection matrices, because i need standard quad for drawing. tried projection - did not help.

public class TestActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        GLSurfaceView glv = new GLSurfaceView(this);
        glv.setEGLContextClientVersion(2);
        SimpleRenderer renderer = new SimpleRenderer(this);
        glv.setRenderer(renderer);
        glv.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
        setContentView(glv);
    }
}

public class SimpleRenderer implements GLSurfaceView.Renderer {
    private final float[] squareVertices = {
            -1.0f, -1.0f,
            1.0f, -1.0f,
            -1.0f,  1.0f,
            1.0f,  1.0f,
    };
    private FloatBuffer squareBuffer;

    private final Context context;

    private int text_program;
    private int aPositionLocation2;


    public SimpleRenderer(Context context) {
        this.context = context;
        squareBuffer = ByteBuffer.allocateDirect(squareVertices.length * 4).asFloatBuffer();
        squareBuffer.put(squareVertices).position(0);
    }

    public void onDrawFrame(GL10 gl) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glUseProgram(text_program);
        glEnableVertexAttribArray(aPositionLocation2);
        glVertexAttribPointer(aPositionLocation2, 2, GL_FLOAT, false, 0, squareBuffer);
        glDrawArrays(GL_POINTS, 0, 4);
        glDisableVertexAttribArray(aPositionLocation2);

    }

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

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        text_program = ShaderHelper.buildProgram(TextResourceReader.readTextFileFromResource(context, R.raw.texture_vertex_shader),
                TextResourceReader.readTextFileFromResource(context, R.raw.texture_fragment_shader));

        aPositionLocation2 = glGetAttribLocation(text_program, "a_Position");
        glClearColor(0f, 0f, 0f, 0f);
    }
}

public class ShaderHelper {
    private static final String TAG = "ShaderHelper";

    public static int compileVertexShader(String shaderCode) {
        return compileShader(GL_VERTEX_SHADER, shaderCode);
    }

    public static int compileFragmentShader(String shaderCode) {
        return compileShader(GL_FRAGMENT_SHADER, shaderCode);
    }

    private static int compileShader(int type, String shaderCode) {
        final int shaderObjectId = glCreateShader(type);
        if (shaderObjectId == 0) Log.w(TAG, "Shader not created!");
        glShaderSource(shaderObjectId, shaderCode);
        glCompileShader(shaderObjectId);
        final int[] compileStatus = new int[1];
        glGetShaderiv(shaderObjectId, GL_COMPILE_STATUS, compileStatus, 0);
        Log.v(TAG, "Results of compiling source:" + "\n" + shaderCode + "\n:"
                + glGetShaderInfoLog(shaderObjectId));
        if (compileStatus[0] == 0) {
            // If it failed, delete the shader object.
            glDeleteShader(shaderObjectId);
            Log.w(TAG, "Compilation of shader failed.");
            return 0;
        }
        return shaderObjectId;
    }

    public static int linkProgram(int vertexShaderId, int fragmentShaderId) {
        final int programObjectId = glCreateProgram();
        if (programObjectId == 0) {
            Log.w(TAG, "Could not create new program");
            return 0;
        }
        glAttachShader(programObjectId, vertexShaderId);
        glAttachShader(programObjectId, fragmentShaderId);
        glLinkProgram(programObjectId);
        final int[] linkStatus = new int[1];
        glGetProgramiv(programObjectId, GL_LINK_STATUS, linkStatus, 0);
        Log.v(TAG, "Results of linking program:\n"
                + glGetProgramInfoLog(programObjectId));
        if (linkStatus[0] == 0) {
            // If it failed, delete the program object.
            glDeleteProgram(programObjectId);
            Log.w(TAG, "Linking of program failed.");
            return 0;
        }
        return programObjectId;
    }

    public static boolean validateProgram(int programObjectId) {
        glValidateProgram(programObjectId);
        final int[] validateStatus = new int[1];
        glGetProgramiv(programObjectId, GL_VALIDATE_STATUS, validateStatus, 0);
        Log.v(TAG, "Results of validating program: " + validateStatus[0]
                + "\nLog:" + glGetProgramInfoLog(programObjectId));
        return validateStatus[0] != 0;
    }

    public static int buildProgram(String vertexShaderSource,
                                   String fragmentShaderSource) {
        int program;
        // Compile the shaders.
        int vertexShader = compileVertexShader(vertexShaderSource);
        int fragmentShader = compileFragmentShader(fragmentShaderSource);
        // Link them into a shader program.
        program = linkProgram(vertexShader, fragmentShader);

        validateProgram(program);

        return program;
    }

}

vertex shader:

attribute vec4 a_Position;

void main()
{
    gl_Position = a_Position;
    gl_PointSize = 10.0;
}

fragment shader:

void main()
{
    gl_FragColor = vec4(1.0,1.0,1.0,1.0);
}

Upvotes: 0

Views: 97

Answers (1)

Odysseus
Odysseus

Reputation: 1092

The problem was indeed in passing vertex data: OpenGL uses native byte order (little-endian for x86 emu), but I have allocated buffer in java (big-endian I suppose) so corrupted float values were passed to vertex shader. After specifying byte order in byte buffer everything works fine.

squareBuffer = ByteBuffer.allocateDirect(squareVertices.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();

Upvotes: 1

Related Questions