Raspberry Pi 3 上只有 OpenGL ES 1.1 而不是 2.0
Only OpenGL ES 1.1 and not 2.0 on Raspberry Pi 3
我正在尝试为 Raspberry Pi 3 (Raspbian Jessie) 编写 OpenGL ES 2.0 应用程序。我安装了以下软件包:
sudo apt install mesa-utils libgl1-mesa-dri libgles2-mesa-dev libglfw-dev
我编写的应用程序创建了一个帧缓冲区,将数据加载到其中并读回数据 (texture.c on github):
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <EGL/egl.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#define GL_CHECK(x) \
x; \
{ \
GLenum glError = glGetError(); \
if(glError != GL_NO_ERROR) { \
printf("glGetError() = %i (0x%.8x) at %s:%i\n", glError, glError, __FILE__, __LINE__); \
exit(1); \
} \
}
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
static const EGLint context_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
static const EGLint config_attribs[] = {
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_DEPTH_SIZE, 1,
EGL_RENDERABLE_TYPE,
EGL_OPENGL_ES2_BIT,
EGL_NONE
};
static const EGLint pbufferAttribs[] = {
EGL_WIDTH, 9, EGL_HEIGHT, 9, EGL_NONE,
};
int main(int argc, char **argv) {
printf("start texture\n");
int i;
int texSize = 2;
EGLint major, minor;
EGLDisplay eglDisplay;
EGLContext eglContext;
EGLSurface eglSurface;
EGLConfig eglConfig;
EGLint eglConfigCount;
Display *dpy = NULL;
char *dpyName = NULL;
Window window;
// open display
dpy = XOpenDisplay (dpyName);
if(!dpy) {
fprintf (stderr, "\nERROR: could not open display\n");
exit (1);
}
// create window
window = XCreateSimpleWindow(dpy, RootWindow (dpy, DefaultScreen (dpy)), 1, 1, WINDOW_WIDTH, WINDOW_HEIGHT, 0, BlackPixel (dpy,DefaultScreen(dpy)), BlackPixel (dpy, DefaultScreen (dpy)));
XStoreName(dpy, window, "texture");
XMapWindow(dpy, window);
// move window to upper left corner
XMoveWindow(dpy, window, 0, 0);
XSync(dpy, 0);
// setup egl
eglDisplay = eglGetDisplay(dpy);
if(!eglInitialize(eglDisplay, &major, &minor)) {
fprintf(stderr, "\nError: failed to initialize EGL\n");
exit(1);
}
printf("Display used %p & EGL versions are %d.%d\n", eglDisplay, major, minor);
printf("EGL version: %s\n", eglQueryString(eglDisplay, EGL_VERSION));
printf("EGL vendor: %s\n", eglQueryString(eglDisplay, EGL_VENDOR));
if(!eglChooseConfig(eglDisplay, config_attribs, &eglConfig, 1, &eglConfigCount)) {
fprintf(stderr, "\nError: could not get an EGL visual config\n");
exit(1);
}
assert(eglConfig);
assert(eglConfigCount > 0);
eglSurface = eglCreatePbufferSurface(eglDisplay, eglConfig, pbufferAttribs);
if(!eglBindAPI(EGL_OPENGL_ES_API)) {
fprintf (stderr, "\nError: failed to bind api EGL_OPENGL_ES_API\n");
exit(1);
}
eglContext = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, NULL);
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
// check OpenGL vendor
printf("OpenGL vendor: %s\n", glGetString(GL_VENDOR));
// check OpenGL vendor
printf("OpenGL vendor: %s\n", glGetString(GL_RENDERER));
// check of OpenGL version
printf("OpenGL version: %s\n", glGetString(GL_VERSION));
// check for OpenGL extensions
//printf("OpenGL extensions: %s\n", glGetString(GL_EXTENSIONS));
uint8_t* data = (uint8_t*) malloc(4*texSize*texSize*sizeof(uint8_t));
uint8_t* result = (uint8_t*) malloc(4*texSize*texSize*sizeof(uint8_t));
// fill data
for(i = 0; i < texSize*texSize*4; i++) {
data[i] = i;
result[i] = 0;
}
// create framebuffer and bind it (that is used as offscreen render target)
GLuint fb;
GL_CHECK(glGenFramebuffers(1, &fb));
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, fb));
// create texture
GLuint tex;
GL_CHECK(glGenTextures(1, &tex));
GL_CHECK(glBindTexture(GL_TEXTURE_2D, tex));
// set texture parameters
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
// define texture with RGBA format with 8Bit (GL_UNSIGNED_BYTE)
GL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texSize, texSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0));
// attach texture
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0));
// transfer data to texture
GL_CHECK(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texSize, texSize, GL_RGBA, GL_UNSIGNED_BYTE, data));
// check if framebuffer is complete
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
fprintf (stderr, "\nError: framebuffer not complete\n");
exit(1);
}
// read back texture into result
GL_CHECK(glReadPixels(0, 0, texSize, texSize, GL_RGBA, GL_UNSIGNED_BYTE, result));
// print data and result
printf("data, result:\n");
for(i = 0; i < texSize*texSize*4; i++) {
printf("%d, %d\n", data[i], result[i]);
}
// clean up
free(data);
free(result);
GL_CHECK(glDeleteFramebuffers(1, &fb));
eglBindAPI(EGL_OPENGL_ES_API);
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglContext);
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(eglDisplay, eglContext);
eglDestroySurface(eglDisplay, eglSurface);
eglTerminate(dpy);
return 0;
}
我编译它:
gcc texture.c -o texture -lEGL -lX11 -lGLESv2
当我 运行 应用程序时,我得到以下输出:
start texture
Display used 0x6d2168 & EGL versions are 1.4
EGL version: 1.4 (DRI2)
EGL vendor: Mesa Project
OpenGL vendor: Broadcom
OpenGL vendor: Gallium 0.4 on VC4 V3D 2.1
OpenGL version: OpenGL ES-CM 1.1 Mesa 13.0.0
data, result:
0, 0
1, 1
2, 2
3, 3
4, 4
5, 5
6, 6
7, 7
8, 8
9, 9
10, 10
11, 11
12, 12
13, 13
14, 14
15, 15
帧缓冲区的纹理写入和读取似乎有效,但是,我只得到 OpenGL ES-CM 1.1 Mesa 13.0.0
。当我 运行 glxinfo
我得到 OpenGL 2.1 Mesa 13.0.0
。我使用 GL Full KMS
驱动程序并将 GPU 的内存拆分设置为 256。
如何使用 OpenGL ES 2.0 而不是 OpenGL ES 1.1?
您没有请求任何特定的上下文。您定义了 context_attribs
数组,但您从未使用它并将 NULL 传递给 eglCreateContext
.
eglContext = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, NULL);
^^
将最后一个参数更改为 context_attribs
,它应该可以工作。
我正在尝试为 Raspberry Pi 3 (Raspbian Jessie) 编写 OpenGL ES 2.0 应用程序。我安装了以下软件包:
sudo apt install mesa-utils libgl1-mesa-dri libgles2-mesa-dev libglfw-dev
我编写的应用程序创建了一个帧缓冲区,将数据加载到其中并读回数据 (texture.c on github):
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <EGL/egl.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#define GL_CHECK(x) \
x; \
{ \
GLenum glError = glGetError(); \
if(glError != GL_NO_ERROR) { \
printf("glGetError() = %i (0x%.8x) at %s:%i\n", glError, glError, __FILE__, __LINE__); \
exit(1); \
} \
}
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
static const EGLint context_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
static const EGLint config_attribs[] = {
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_DEPTH_SIZE, 1,
EGL_RENDERABLE_TYPE,
EGL_OPENGL_ES2_BIT,
EGL_NONE
};
static const EGLint pbufferAttribs[] = {
EGL_WIDTH, 9, EGL_HEIGHT, 9, EGL_NONE,
};
int main(int argc, char **argv) {
printf("start texture\n");
int i;
int texSize = 2;
EGLint major, minor;
EGLDisplay eglDisplay;
EGLContext eglContext;
EGLSurface eglSurface;
EGLConfig eglConfig;
EGLint eglConfigCount;
Display *dpy = NULL;
char *dpyName = NULL;
Window window;
// open display
dpy = XOpenDisplay (dpyName);
if(!dpy) {
fprintf (stderr, "\nERROR: could not open display\n");
exit (1);
}
// create window
window = XCreateSimpleWindow(dpy, RootWindow (dpy, DefaultScreen (dpy)), 1, 1, WINDOW_WIDTH, WINDOW_HEIGHT, 0, BlackPixel (dpy,DefaultScreen(dpy)), BlackPixel (dpy, DefaultScreen (dpy)));
XStoreName(dpy, window, "texture");
XMapWindow(dpy, window);
// move window to upper left corner
XMoveWindow(dpy, window, 0, 0);
XSync(dpy, 0);
// setup egl
eglDisplay = eglGetDisplay(dpy);
if(!eglInitialize(eglDisplay, &major, &minor)) {
fprintf(stderr, "\nError: failed to initialize EGL\n");
exit(1);
}
printf("Display used %p & EGL versions are %d.%d\n", eglDisplay, major, minor);
printf("EGL version: %s\n", eglQueryString(eglDisplay, EGL_VERSION));
printf("EGL vendor: %s\n", eglQueryString(eglDisplay, EGL_VENDOR));
if(!eglChooseConfig(eglDisplay, config_attribs, &eglConfig, 1, &eglConfigCount)) {
fprintf(stderr, "\nError: could not get an EGL visual config\n");
exit(1);
}
assert(eglConfig);
assert(eglConfigCount > 0);
eglSurface = eglCreatePbufferSurface(eglDisplay, eglConfig, pbufferAttribs);
if(!eglBindAPI(EGL_OPENGL_ES_API)) {
fprintf (stderr, "\nError: failed to bind api EGL_OPENGL_ES_API\n");
exit(1);
}
eglContext = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, NULL);
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
// check OpenGL vendor
printf("OpenGL vendor: %s\n", glGetString(GL_VENDOR));
// check OpenGL vendor
printf("OpenGL vendor: %s\n", glGetString(GL_RENDERER));
// check of OpenGL version
printf("OpenGL version: %s\n", glGetString(GL_VERSION));
// check for OpenGL extensions
//printf("OpenGL extensions: %s\n", glGetString(GL_EXTENSIONS));
uint8_t* data = (uint8_t*) malloc(4*texSize*texSize*sizeof(uint8_t));
uint8_t* result = (uint8_t*) malloc(4*texSize*texSize*sizeof(uint8_t));
// fill data
for(i = 0; i < texSize*texSize*4; i++) {
data[i] = i;
result[i] = 0;
}
// create framebuffer and bind it (that is used as offscreen render target)
GLuint fb;
GL_CHECK(glGenFramebuffers(1, &fb));
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, fb));
// create texture
GLuint tex;
GL_CHECK(glGenTextures(1, &tex));
GL_CHECK(glBindTexture(GL_TEXTURE_2D, tex));
// set texture parameters
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
// define texture with RGBA format with 8Bit (GL_UNSIGNED_BYTE)
GL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texSize, texSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0));
// attach texture
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0));
// transfer data to texture
GL_CHECK(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texSize, texSize, GL_RGBA, GL_UNSIGNED_BYTE, data));
// check if framebuffer is complete
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
fprintf (stderr, "\nError: framebuffer not complete\n");
exit(1);
}
// read back texture into result
GL_CHECK(glReadPixels(0, 0, texSize, texSize, GL_RGBA, GL_UNSIGNED_BYTE, result));
// print data and result
printf("data, result:\n");
for(i = 0; i < texSize*texSize*4; i++) {
printf("%d, %d\n", data[i], result[i]);
}
// clean up
free(data);
free(result);
GL_CHECK(glDeleteFramebuffers(1, &fb));
eglBindAPI(EGL_OPENGL_ES_API);
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglContext);
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(eglDisplay, eglContext);
eglDestroySurface(eglDisplay, eglSurface);
eglTerminate(dpy);
return 0;
}
我编译它:
gcc texture.c -o texture -lEGL -lX11 -lGLESv2
当我 运行 应用程序时,我得到以下输出:
start texture
Display used 0x6d2168 & EGL versions are 1.4
EGL version: 1.4 (DRI2)
EGL vendor: Mesa Project
OpenGL vendor: Broadcom
OpenGL vendor: Gallium 0.4 on VC4 V3D 2.1
OpenGL version: OpenGL ES-CM 1.1 Mesa 13.0.0
data, result:
0, 0
1, 1
2, 2
3, 3
4, 4
5, 5
6, 6
7, 7
8, 8
9, 9
10, 10
11, 11
12, 12
13, 13
14, 14
15, 15
帧缓冲区的纹理写入和读取似乎有效,但是,我只得到 OpenGL ES-CM 1.1 Mesa 13.0.0
。当我 运行 glxinfo
我得到 OpenGL 2.1 Mesa 13.0.0
。我使用 GL Full KMS
驱动程序并将 GPU 的内存拆分设置为 256。
如何使用 OpenGL ES 2.0 而不是 OpenGL ES 1.1?
您没有请求任何特定的上下文。您定义了 context_attribs
数组,但您从未使用它并将 NULL 传递给 eglCreateContext
.
eglContext = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, NULL);
^^
将最后一个参数更改为 context_attribs
,它应该可以工作。