在Android OpenGL中渲染简单正方形

时间:2019-10-31 00:03:35

标签: java android opengl-es

这是我画一个正方形的坐标:

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

然后我的初始化代码是:

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

这就是我的渲染方式:

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

这是EGL上​​下文创建

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

这是我的着色器

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";

    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";

从着色器可以看到,我应该看到一个红色正方形,但是在屏幕上却看到很多随机像素。如果使用glClearColor,我可以看到放置在其中的颜色,但是什么也没发生。

我的顶点数组出问题了吗?

更新:

我正在使用

import static android.opengl.GLES32.*;

1 个答案:

答案 0 :(得分:1)

glVertexAttribPointer的第4个或第5个参数必须是连续属性之间的跨度,分别是第一个分量的偏移量以字节为单位,而不是元素的数量。
float元素的大小为4,必须为:

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

glVertexAttribPointer(textureInLocation, 2, GL_FLOAT, false, 5*4, 3*4);
glEnableVertexAttribArray(textureInLocation);
相关问题