OpenGL ES 2.0 を使用して単純なテクスチャ ストリーム レンダリング プログラムを作成しています。このプログラムはデスクトップでは動作しますが、Mali400 GPU を搭載した組み込みプラットフォームでは失敗します。LCD が黒くなり、上部の数行が点滅します。コードの何が問題なのかわかりません。私は OK である他の OpenGL ES 2.0 プログラムをいくつか試したので、問題は私のコードにあるはずです。どんな助けでも大歓迎です。ありがとう。
main.c
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <sys/stat.h>
static EGLDisplay display;
static EGLSurface surface;
static void render_target_init(EGLNativeWindowType nativeWindow)
{
assert((display = eglGetDisplay(EGL_DEFAULT_DISPLAY)) != EGL_NO_DISPLAY);
EGLint majorVersion;
EGLint minorVersion;
assert(eglInitialize(display, &majorVersion, &minorVersion) == EGL_TRUE);
EGLConfig config;
EGLint numConfigs;
const EGLint configAttribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_DEPTH_SIZE, 24,
EGL_NONE
};
assert(eglChooseConfig(display, configAttribs, &config, 1, &numConfigs) == EGL_TRUE);
const EGLint attribList[] = {
EGL_RENDER_BUFFER, EGL_BACK_BUFFER,
EGL_NONE
};
assert((surface = eglCreateWindowSurface(display, config, nativeWindow, attribList)) != EGL_NO_SURFACE);
EGLContext context;
const EGLint contextAttribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
assert((context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs)) != EGL_NO_CONTEXT);
assert(eglMakeCurrent(display, surface, surface, context) == EGL_TRUE);
}
static GLuint LoadShader(const char *name, GLenum type)
{
FILE *f;
int size;
char *buff;
GLuint shader;
GLint compiled;
const char *source[1];
assert((f = fopen(name, "r")) != NULL);
// get file size
fseek(f, 0, SEEK_END);
size = ftell(f);
fseek(f, 0, SEEK_SET);
assert((buff = malloc(size)) != NULL);
assert(fread(buff, 1, size, f) == size);
source[0] = buff;
fclose(f);
shader = glCreateShader(type);
glShaderSource(shader, 1, source, &size);
glCompileShader(shader);
free(buff);
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
GLint infoLen = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen > 1) {
char *infoLog = malloc(infoLen);
glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
fprintf(stderr, "Error compiling shader %s:\n%s\n", name, infoLog);
free(infoLog);
}
glDeleteShader(shader);
return 0;
}
return shader;
}
static void init_GLES(int width, int height)
{
GLint linked;
GLuint program;
GLuint vertexShader;
GLuint fragmentShader;
assert((vertexShader = LoadShader("vert.glsl", GL_VERTEX_SHADER)) != 0);
assert((fragmentShader = LoadShader("frag.glsl", GL_FRAGMENT_SHADER)) != 0);
assert((program = glCreateProgram()) != 0);
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &linked);
if (!linked) {
GLint infoLen = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen > 1) {
char *infoLog = malloc(infoLen);
glGetProgramInfoLog(program, infoLen, NULL, infoLog);
fprintf(stderr, "Error linking program:\n%s\n", infoLog);
free(infoLog);
}
glDeleteProgram(program);
exit(1);
}
glClearColor(0.15f, 0.15f, 0.15f, 0.15f);
glViewport(0, 0, width, height);
glEnable(GL_DEPTH_TEST);
glUseProgram(program);
GLfloat vertex[] = {
1, 0, 0,
0, 1, 0,
-1, 0, 0,
0, -1, 0,
};
GLfloat texcoord[] = {
1, 1,
0, 1,
0, 0,
1, 0,
};
GLushort index[] = {
0, 1, 2,
0, 3, 2,
};
GLuint VBO[3];
glGenBuffers(3, VBO);
GLint pos = glGetAttribLocation(program, "positionIn");
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(GLfloat) * 3, vertex, GL_STATIC_DRAW);
glEnableVertexAttribArray(pos);
glVertexAttribPointer(pos, 3, GL_FLOAT, 0, 0, 0);
GLint tex = glGetAttribLocation(program, "texcoordIn");
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(GLfloat) * 2, texcoord, GL_STATIC_DRAW);
glEnableVertexAttribArray(tex);
glVertexAttribPointer(tex, 2, GL_FLOAT, 0, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO[2]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(GLushort), index, GL_STATIC_DRAW);
GLuint texid;
GLint texMap = glGetUniformLocation(program, "texMap");
glUniform1i(texMap, 0); // GL_TEXTURE0
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &texid);
glBindTexture(GL_TEXTURE_2D, texid);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
assert(glGetError() == 0);
}
#ifdef _X_WINDOW_SYSTEM_
#include <X11/Xlib.h>
static EGLNativeWindowType CreateNativeWindow(void)
{
assert((display = XOpenDisplay(NULL)) != NULL);
int screen = DefaultScreen(display);
Window root = DefaultRootWindow(display);
Window window = XCreateWindow(display, root, 0, 0, 600, 480, 0,
DefaultDepth(display, screen), InputOutput,
DefaultVisual(display, screen),
0, NULL);
XMapWindow(display, window);
XFlush(display);
return window;
}
#endif
int display_init(int width, int height)
{
#ifdef _X_WINDOW_SYSTEM_
render_target_init(CreateNativeWindow());
#else
struct mali_native_window window;
window.width = width;
window.height = height;
render_target_init(&window);
#endif
init_GLES(width, height);
}
void render_frame(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
//glDrawArrays(GL_TRIANGLES, 0, 3);
eglSwapBuffers(display, surface);
}
void update_texture(void *data, int width, int height)
{
static int first_time = 1;
if (first_time) {
printf("create texture %d %d\n", width, height);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
first_time = 0;
}
else {
printf("update texture %d %d\n", width, height);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);
}
assert(glGetError() == 0);
}
int main(void)
{
int i;
void *texture[2] = {0};
int fd = open("0.rgb", O_RDONLY);
struct stat st;
fstat(fd, &st);
texture[0] = malloc(st.st_size);
read(fd, texture[0], st.st_size);
close(fd);
fd = open("1.rgb", O_RDONLY);
fstat(fd, &st);
texture[1] = malloc(st.st_size);
read(fd, texture[1], st.st_size);
close(fd);
display_init(600, 480);
for (i = 0; i < 200; i++) {
update_texture(texture[i%2], 720, 576);
render_frame();
usleep(20000);
}
return 0;
}
vert.glsl
attribute vec3 positionIn;
attribute vec2 texcoordIn;
varying vec2 texcoord;
void main()
{
gl_Position = vec4(positionIn, 1);
texcoord = texcoordIn;
}
frag.glsl
precision mediump float;
uniform sampler2D texMap;
varying vec2 texcoord;
void main() {
vec3 color = texture2D(texMap, texcoord).rgb;
gl_FragColor = vec4(color, 1);
}