使用帖子 [RFC] ApiTrace (glx/egl) 的 C 源代码编写功能,我成功获得了 Android 上正在运行的应用程序的跟踪,并为该跟踪生成了 C 代码。此代码构建于 Linux (Ubuntu 14.04) 上,但不幸的是它无法运行/出现段错误。下面的代码是问题的最小“工作”示例。
我首先注意到
glBindBuffer
上的段错误,该帖子(glGenBuffers 因分段错误而崩溃)归咎于未初始化的 glewInit
。所以我尝试添加glewInit
,但是:
glewInit()
出现在 eglMakeCurrent()
之前,则 err
不是 GLEW_OK
,最终导致 glBindBuffer
段错误:glew初始化失败 程序收到信号 SIGSEGV,分段错误。 0x00000000 在 ?? () (gdb) BT #0 0x00000000 在 ?? () #1 0x08048b43 在 myegltestmain.c:29 的frame_0 () 中 #2 0x08048b6a 在 myegltestmain.c:36 的 run_trace () 中 #3 0x08048f42 在 main (argc=1, argv=0xbffff044) 在 myegltestmain.c:126
glewInit()
出现在 eglMakeCurrent()
之前(如下面的代码所示),那么我会在以下堆栈跟踪中遇到段错误:程序接收信号SIGSEGV,分段错误。 /usr/lib/i386-linux-gnu/libX11.so.6 中的 XQueryExtension () 中的 0xb7e12f6a (gdb) BT 来自 /usr/lib/i386-linux-gnu/libX11.so.6 的 XQueryExtension () 中的 #0 0xb7e12f6a #1 0xb7e0722e 在 XInitExtension () 中,来自 /usr/lib/i386-linux-gnu/libX11.so.6 #2 0xb7bbdd54 在 ?? () 来自 /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/mesa/libGL.so.1 中的 glXQueryVersion () 中的 #3 0xb7bb9785 /usr/lib/i386-linux-gnu/libGLEW.so.1.10 中的 glxewContextInit () 中的 #4 0xb7f857d7 来自 /usr/lib/i386-linux-gnu/libGLEW.so.1.10 的 glewInit () 中的 #5 0xb7f8bf44 myegltestmain.c:115 的 main 中的 #6 0x08048ee6 (argc=1, argv=0xbffff044)
是否可以在桌面 Linux 版本上将 GLEW 与 OpenGL ES 一起使用(显然,它适用于 Android)——如果可以,如何使用;我可以对下面的示例进行哪些修改才能运行?
myegltestmain.c
// gcc -Wall -ansi --std=c99 -g -O0 myegltestmain.c -o myegltestmain -lGLEW -lEGL -lGLESv1_CM -lX11
#include <stdio.h>
#include <stdlib.h>
#define GL_GLEXT_PROTOTYPES 1
#include <string.h>
#include <math.h>
#include <GL/glew.h> // added for GL_VERTEX_SHADER
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
unsigned int _buffers_1 = 1;
unsigned int* _buffers_1_p = &_buffers_1;
const int screensize0[2] = { 600 ,976 };
int egl_config_params0[] = { 12352, 4, 12324, 8, 12323, 8, 12322, 8, 12321, 8, 12325, 0, 12326, 0, 12339, 4, 12344, 0 };
int egl_context_params0[] = { 12440, 2, 12344, 0 };
Display *dpy;
EGLDisplay display;
EGLContext context;
EGLSurface surface;
void frame_0(){
glViewport(0, 0, 600, 976);
glScissor(0, 0, 600, 976);
glGenBuffers(1, _buffers_1_p); // line 29
glBindBuffer(GL_ARRAY_BUFFER, *_buffers_1_p);
}
static void run_trace()
{
frame_0();
return;
}
static Bool WaitForNotify( Display *dpy, XEvent *event, XPointer arg ) {
return (event->type == MapNotify) && (event->xmap.window == (Window) arg);
(void)dpy;
}
int main( int argc, char *argv[] )
{
Window xWin;
XEvent event;
XSetWindowAttributes swa;
EGLConfig ecfg;
EGLint num_config;
//load_all_blobs;
dpy = XOpenDisplay(NULL);
if (dpy == NULL) {
printf("Not able to connect to X server\n");
exit(EXIT_FAILURE);
}
swa.event_mask = StructureNotifyMask;
xWin = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, screensize0[0], screensize0[1],
0, CopyFromParent, InputOutput, CopyFromParent,
CWEventMask, &swa);
XMapWindow(dpy, xWin);
XIfEvent(dpy, &event, WaitForNotify, (XPointer)xWin);
display = eglGetDisplay((EGLNativeDisplayType)dpy);
if (display == EGL_NO_DISPLAY) {
fprintf(stderr, "Got no EGL display.\n");
exit(EXIT_FAILURE);
}
if (!eglInitialize(display, NULL, NULL)) {
fprintf(stderr, "Unable to initialize EGL\n");
exit(EXIT_FAILURE);
}
eglBindAPI(EGL_OPENGL_ES_API);//EGL_OPENGL_API);//EGL_OPENGL_ES_API);//egl_api_bind0);
if (!eglChooseConfig(display, egl_config_params0, &ecfg, 1,
&num_config)) {
fprintf(stderr, "Failed to choose config (eglError: 0x%x)\n",
eglGetError());
exit(EXIT_FAILURE);
}
if (num_config != 1) {
fprintf(stderr, "Didn't get just one config, but %d\n", num_config);
exit(EXIT_FAILURE);
}
surface = eglCreateWindowSurface(display, ecfg, xWin, NULL);
if (surface == EGL_NO_SURFACE) {
fprintf(stderr, "Not able to create EGL surface (eglError: 0x%x)\n",
eglGetError());
exit(EXIT_FAILURE);
}
context = eglCreateContext (display, ecfg, EGL_NO_CONTEXT,
egl_context_params0);
if (context == EGL_NO_CONTEXT) {
fprintf(stderr, "Not able to create EGL context (eglError: 0x%x)\n",
eglGetError());
exit(EXIT_FAILURE);
}
eglMakeCurrent(display, surface, surface, context);
GLenum err=glewInit();
if(err!=GLEW_OK) {
fprintf(stderr, "glewInit failed\n");
} else {
fprintf(stderr, "glewInit OK\n");
}
/*
* Setup done. Now go to the trace.
*/
run_trace();
eglDestroyContext(display, context);
eglDestroySurface(display, surface);
eglTerminate(display);
XDestroyWindow(dpy, xWin);
XCloseDisplay(dpy);
//free_all_blobs;
exit(EXIT_SUCCESS);
(void)argc;
(void)argv;
}
如果您不使用 X11 并通过 Android 表面支架进行绘制,例如 https://svn.blender.org/svnroot/bf-blender/branches/soc-2012-swiss_cheese/intern/ghost/intern/GHOST_WindowAndroid.cpp