PPP
PPP

Reputation: 1850

Renderning simple square in Android OpenGL

Here are my coordinates to draw a square:

static float vertices_textures[] = {
    //vertices            //positions
    -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
    1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
    -1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
    1.0f, 1.0f, 0.0f, 1.0f, 0.0f
};
Buffer vertices_textures_buffer = FloatBuffer.wrap(vertices_textures);

Then my initialization code is:

    egl = (EGL10) EGLContext.getEGL();
    eglDisplay = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
    if (eglDisplay == EGL10.EGL_NO_DISPLAY) {
        throw new RuntimeException("eglGetDisplay failed");
    }

    int[] version = new int[2];
    if (!egl.eglInitialize(eglDisplay, version)) {
        throw new RuntimeException("eglInitialize failed");
    }

    EGLConfig eglConfig = chooseEglConfig();
    eglContext = createContext(egl, eglDisplay, eglConfig);

    eglSurface = egl.eglCreateWindowSurface(eglDisplay, eglConfig, surfaceTexture, null);

    if (eglSurface == null || eglSurface == EGL10.EGL_NO_SURFACE) {
        throw new RuntimeException("GL Error: " + GLUtils.getEGLErrorString(egl.eglGetError()));
    }

    if (!egl.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) {
        throw new RuntimeException("GL make current error: " + GLUtils.getEGLErrorString(egl.eglGetError()));
    }
    int vertexShader = loadShader(GL_VERTEX_SHADER, OrwellShaders.Vertex.video);
    int fragmentShader = loadShader(GL_FRAGMENT_SHADER, OrwellShaders.Fragment.color);

    program = glCreateProgram();

    glAttachShader(program, vertexShader);
    glAttachShader(program, fragmentShader);

    glLinkProgram(program);

    vertexInLocation = glGetAttribLocation(program, "aPos");
    textureInLocation = glGetAttribLocation(program, "aTexCoord");

    glGenVertexArrays(1, vertexArrayObject, 0);
    glGenBuffers(1, vertexBufferObject, 0);
    glGenBuffers(3, pixelBufferObjects, 0);

    glBindVertexArray(vertexArrayObject[0]);

    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject[0]);
    glBufferData(GL_ARRAY_BUFFER, vertices_textures.length, vertices_textures_buffer, GL_STATIC_DRAW);

    glVertexAttribPointer(vertexInLocation, 3, GL_FLOAT, false, 5*4 , 0);
    glEnableVertexAttribArray(vertexInLocation);

    glVertexAttribPointer(textureInLocation, 2, GL_FLOAT, false, 5*4 , 3*4);
    glEnableVertexAttribArray(textureInLocation);

This is how I render:

    glUseProgram(program);
    glClearColor(0.0f, 0.0f, 0.4f, 1f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glBindVertexArray(vertexArrayObject[0]);

    glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0);
    glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexImage2D(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0, GLES11Ext.GL_RGBA8_OES, 100, 100,
            0, GLES11Ext.GL_RGBA8_OES, GL_UNSIGNED_BYTE, buffer);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

Here is the EGL context creation

    private EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
    int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
    int[] attribList = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE};
    return egl.eglCreateContext(eglDisplay, eglConfig, EGL10.EGL_NO_CONTEXT, attribList);
}

private EGLConfig chooseEglConfig() {
    int[] configsCount = new int[1];
    EGLConfig[] configs = new EGLConfig[1];
    int[] configSpec = getConfig();

    if (!egl.eglChooseConfig(eglDisplay, configSpec, configs, 1, configsCount)) {
        throw new IllegalArgumentException("Failed to choose config: " + GLUtils.getEGLErrorString(egl.eglGetError()));
    } else if (configsCount[0] > 0) {
        return configs[0];
    }

    return null;
}

Here are my shaders

public static final String vertex  = 
        "#version 320 es\n " +
        "layout (location = 0) in vec3 aPos;\n " +
        "layout (location = 1) in vec2 aTexCoord;\n " +
        "\n " +
        "out vec2 TexCoord;\n " +
        "\n " +
        "void main()\n " +
        "{\n " +
        "    gl_Position = vec4(aPos, 1.0);\n " +
        "    TexCoord = vec2(aTexCoord.x, aTexCoord.y);\n " +
        "}\n";

and

    public static final String color  = 
        "#version 320 es\n " +
        "precision mediump float;\n " +
        "in vec2 TexCoord;\n " +
        "out vec4 FragColor;\n " +
        "\n " +
        "void main()\n " +
        "{\n " +
        "    FragColor = vec4(1.0f, 0, 0, 1.0f);\n " +
        "}\n";

As you can see by the shader I should see a red square, but I see a lot of random pixels binking on the screen. If I use glClearColor, I can see the color I put there, but nothing more happens.

Is there something wrong with my vertex arrays?

UPDATE:

I'm using

import static android.opengl.GLES32.*;

Upvotes: 0

Views: 147

Answers (1)

Rabbid76
Rabbid76

Reputation: 210877

The 4th respectively 5th parameter of glVertexAttribPointer have to be the stride between consecutive attributes respectively the offset to the first component in bytes rather than the number of elements.
Size the size of a float element is 4, it has to be:

glVertexAttribPointer(vextexInLocation, 3, GL_FLOAT, false, 5*4, 0);
glEnableVertexAttribArray(vextexInLocation);

glVertexAttribPointer(textureInLocation, 2, GL_FLOAT, false, 5*4, 3*4);
glEnableVertexAttribArray(textureInLocation);

Upvotes: 1

Related Questions