參考資訊:
https://pandorawiki.org/GLES
main.c
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <string.h> #include <dlfcn.h> #include <unistd.h> #include <EGL/egl.h> #include <GLES2/gl2.h> #define LCD_W 800 #define LCD_H 480 const char *vShaderSrc = "attribute vec4 a_position; \n" "attribute vec2 a_texCoord; \n" "varying vec2 v_texCoord; \n" "void main() \n" "{ \n" " gl_Position = a_position; \n" " v_texCoord = a_texCoord; \n" "} \n"; const char *fShaderSrc = "precision mediump float; \n" "varying vec2 v_texCoord; \n" "uniform float s_alpha; \n" "uniform sampler2D s_texture; \n" "void main() \n" "{ \n" " vec3 tex = texture2D(s_texture, v_texCoord).bgr; \n" " gl_FragColor = vec4(tex, s_alpha); \n" "} \n"; int main(int argc, char** argv) { EGLint egl_major = 0; EGLint egl_minor = 0; EGLint num_configs = 0; EGLConfig configs = {0}; EGLDisplay display = EGL_NO_DISPLAY; EGLSurface surface = EGL_NO_SURFACE; EGLContext context = EGL_NO_CONTEXT; EGLint config_attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_ALPHA_SIZE, 0, EGL_NONE }; EGLint window_attributes[] = { EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE }; EGLint const context_attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, }; GLuint vShader = 0; GLuint fShader = 0; GLuint pObject = 0; GLint compiled = 0; int x = 0; int y = 0; uint32_t *p = NULL; GLuint texID[2] = {0}; GLubyte *buf = NULL; GLfloat vVertices[] = { -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, -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, 1.0f, 0.0f }; GLushort indices[] = {0, 1, 2, 0, 2, 3}; display = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(display, &egl_major, &egl_minor); eglChooseConfig(display, config_attribs, &configs, 1, &num_configs); surface = eglCreateWindowSurface(display, configs, 0, window_attributes); context = eglCreateContext(display, configs, EGL_NO_CONTEXT, context_attributes); eglMakeCurrent(display, surface, surface, context); vShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vShader, 1, &vShaderSrc, NULL); glCompileShader(vShader); glGetShaderiv(vShader, GL_COMPILE_STATUS, &compiled); fShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fShader, 1, &fShaderSrc, NULL); glCompileShader(fShader); glGetShaderiv(fShader, GL_COMPILE_STATUS, &compiled); pObject = glCreateProgram(); glAttachShader(pObject, vShader); glAttachShader(pObject, fShader); glLinkProgram(pObject); glUseProgram(pObject); GLint posLoc = glGetAttribLocation(pObject, "a_position"); GLint texLoc = glGetAttribLocation(pObject, "a_texCoord"); GLint samLoc = glGetUniformLocation(pObject, "s_texture"); GLint alphaLoc = glGetUniformLocation(pObject, "s_alpha"); glGenTextures(2, texID); glViewport(0, 0, LCD_W, LCD_H); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); uint32_t col[] = {0xffff0000, 0xff00ff00, 0xff0000ff}; buf = malloc(LCD_W * LCD_H * 4); p = (uint32_t *)buf; for (y = 0; y < LCD_H; y++) { for (x = 0; x < LCD_W; x++) { *p++ = col[x / (LCD_W / 3)]; } } glBindTexture(GL_TEXTURE_2D, texID[0]); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, LCD_W, LCD_H, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf); p = (uint32_t *)buf; for (y = 0; y < LCD_H; y++) { for (x = 0; x < LCD_W; x++) { *p++ = 0; } } glBindTexture(GL_TEXTURE_2D, texID[1]); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, LCD_W, LCD_H, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf); glUniform1f(alphaLoc, 1.0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texID[0]); glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vVertices); glVertexAttribPointer(texLoc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &vVertices[3]); glEnableVertexAttribArray(posLoc); glEnableVertexAttribArray(texLoc); glUniform1i(samLoc, 0); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices); vVertices[0] = 0.0; vVertices[1] = 0.0; vVertices[5] = vVertices[0]; vVertices[6] = 0.5; vVertices[10] = 0.5; vVertices[11] = vVertices[6]; vVertices[15] = vVertices[10]; vVertices[16] = vVertices[1]; glUniform1f(alphaLoc, 0.5); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texID[1]); glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vVertices); glVertexAttribPointer(texLoc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &vVertices[3]); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices); glDisable(GL_BLEND); eglSwapBuffers(display, surface); system("fbgrab main.png"); sleep(3); free(buf); glDeleteTextures(2, texID); eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(display, context); eglDestroySurface(display, surface); eglTerminate(display); return 0; }
編譯、執行
$ gcc main.c -o main -lGLESv2 -lEGL $ op_runfbapp ./main
完成