add a pure x11 + egl simple demo
This commit is contained in:
parent
4e271b7943
commit
a6e5e145e3
|
@ -22,7 +22,7 @@ include_directories(
|
||||||
link_directories(
|
link_directories(
|
||||||
"/usr/lib"
|
"/usr/lib"
|
||||||
"/usr/local/lib"
|
"/usr/local/lib"
|
||||||
"/usr/lib/mali-g5x/"
|
/lib/aarch64-linux-gnu/mali
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,6 +70,13 @@ target_link_libraries(TriangleEsDemo
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
add_executable(TriangleEsX11Demo src/triangle-es2-x11.c)
|
||||||
|
target_link_libraries(TriangleEsX11Demo
|
||||||
|
${DEP_LIBS}
|
||||||
|
X11
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
add_executable(SimpleEs src/simple-es2.c)
|
add_executable(SimpleEs src/simple-es2.c)
|
||||||
|
|
||||||
# 查找对应的第三方库
|
# 查找对应的第三方库
|
||||||
|
|
461
src/triangle-es2-x11.c
Normal file
461
src/triangle-es2-x11.c
Normal file
|
@ -0,0 +1,461 @@
|
||||||
|
/*
|
||||||
|
* This code was created by Jeff Molofee '99
|
||||||
|
* (ported to Linux by Ti Leggett '01)
|
||||||
|
* (ported to i.mx51, i.mx31 and x11 by Freescale '10)
|
||||||
|
* If you've found this code useful, please let him know.
|
||||||
|
*
|
||||||
|
* Visit Jeff at http://nehe.gamedev.net/
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <threads.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include "GLES2/gl2.h"
|
||||||
|
#include "GLES2/gl2ext.h"
|
||||||
|
|
||||||
|
#include "EGL/egl.h"
|
||||||
|
#include "EGL/eglext.h"
|
||||||
|
|
||||||
|
#include <libdrm/drm.h>
|
||||||
|
#include "X11/X.h"
|
||||||
|
#include "X11/Xatom.h"
|
||||||
|
|
||||||
|
Display *x_display;
|
||||||
|
Window win;
|
||||||
|
|
||||||
|
|
||||||
|
int g_stop;
|
||||||
|
|
||||||
|
#define USE_FORMAT 0x34325258
|
||||||
|
|
||||||
|
EGLDisplay egldisplay;
|
||||||
|
EGLConfig eglconfig;
|
||||||
|
EGLSurface eglsurface;
|
||||||
|
EGLContext eglcontext;
|
||||||
|
|
||||||
|
|
||||||
|
GLuint g_hShaderProgram = 0;
|
||||||
|
GLuint g_hModelViewMatrixLoc = 0;
|
||||||
|
GLuint g_hProjMatrixLoc = 0;
|
||||||
|
GLuint g_hVertexLoc = 0;
|
||||||
|
GLuint g_hColorLoc = 1;
|
||||||
|
GLuint g_hVColor = 0;
|
||||||
|
|
||||||
|
#define ASSERT_EQ(exp1, exp2) do { auto e1 = (exp1);auto e2 = (exp2);\
|
||||||
|
if((e1) != (e2)) { \
|
||||||
|
printf("assert value: %p, %p\n", e1, e2); \
|
||||||
|
__assert_fail (#exp1 "==" #exp2, __FILE__, __LINE__, __ASSERT_FUNCTION); \
|
||||||
|
}}while(0)
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
// Name: g_strVertexShader / g_strFragmentShader
|
||||||
|
// Desc: The vertex and fragment shader programs
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const char* g_strVertexShader =
|
||||||
|
"uniform mat4 g_matModelView; \n"
|
||||||
|
"uniform mat4 g_matProj; \n"
|
||||||
|
" \n"
|
||||||
|
"attribute vec4 g_vPosition; \n"
|
||||||
|
"attribute vec3 g_vColor; \n"
|
||||||
|
" \n"
|
||||||
|
"varying vec3 g_vVSColor; \n"
|
||||||
|
" \n"
|
||||||
|
"void main() \n"
|
||||||
|
"{ \n"
|
||||||
|
" vec4 vPositionES = g_matModelView * g_vPosition; \n"
|
||||||
|
" gl_Position = g_matProj * vPositionES; \n"
|
||||||
|
" g_vVSColor = g_vColor; \n"
|
||||||
|
"} \n";
|
||||||
|
|
||||||
|
|
||||||
|
const char* g_strFragmentShader =
|
||||||
|
"#ifdef GL_FRAGMENT_PRECISION_HIGH \n"
|
||||||
|
" precision highp float; \n"
|
||||||
|
"#else \n"
|
||||||
|
" precision mediump float; \n"
|
||||||
|
"#endif \n"
|
||||||
|
" \n"
|
||||||
|
"varying vec3 g_vVSColor; \n"
|
||||||
|
" \n"
|
||||||
|
"void main() \n"
|
||||||
|
"{ \n"
|
||||||
|
" gl_FragColor = vec4( g_vVSColor, 1.0 ); \n"
|
||||||
|
"} \n";
|
||||||
|
|
||||||
|
|
||||||
|
float matModelView[16] = {0};
|
||||||
|
float matProj[16] = {0};
|
||||||
|
float color[4] = {0, 0, 0, 0};
|
||||||
|
|
||||||
|
// Define vertice for a 4-sided pyramid
|
||||||
|
float VertexPositions[] =
|
||||||
|
{
|
||||||
|
0.0f,1.0f, 0.0f,
|
||||||
|
-1.0f,-1.0f, 0.0f,
|
||||||
|
+1.0f,-1.0f, 0.0f,
|
||||||
|
1.0f, 1.0f, 0.0f,
|
||||||
|
-1.0f,1.0f, 0.0f,
|
||||||
|
1.0f, -1.0, 0.0f
|
||||||
|
};
|
||||||
|
|
||||||
|
void render(float w, float h, unsigned int framenum)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Clear the colorbuffer and depth-buffer
|
||||||
|
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||||
|
glViewport(0, 0, w, h);
|
||||||
|
#if 1
|
||||||
|
// Build a perspective projection matrix
|
||||||
|
matProj[ 0] = cosf( 0.5f ) / sinf( 0.5f );
|
||||||
|
matProj[ 5] = matProj[0] * (w/h) ;
|
||||||
|
matProj[10] = -( 10.0f ) / ( 9.0f );
|
||||||
|
matProj[11] = -1.0f;
|
||||||
|
matProj[14] = -( 10.0f ) / ( 9.0f );
|
||||||
|
|
||||||
|
glViewport(0, 0, w, h);
|
||||||
|
|
||||||
|
float zTransDelta = sinf((framenum%200) /200.0 * M_PI);
|
||||||
|
|
||||||
|
// Rotate and translate the model view matrix
|
||||||
|
matModelView[ 0] = 1.0f;
|
||||||
|
matModelView[ 2] = 0.1f;
|
||||||
|
matModelView[ 5] = 1.0f;
|
||||||
|
matModelView[ 8] = 0.0f;
|
||||||
|
matModelView[10] = 0.0f;
|
||||||
|
matModelView[14] = -5.0f + zTransDelta;//translation Z
|
||||||
|
matModelView[15] = 1.0f;
|
||||||
|
|
||||||
|
color[0] = sinf(((framenum%400) /400.0) * M_PI);
|
||||||
|
// color[1] = sinf(((framenum%300) /300.0) * M_PI);
|
||||||
|
// color[2] = sinf(((framenum%200) /200.0) * M_PI);
|
||||||
|
// color[3] = sinf((framenum%500) /500.0 * M_PI);
|
||||||
|
|
||||||
|
glUniformMatrix4fv( g_hModelViewMatrixLoc, 1, 0, matModelView );
|
||||||
|
glUniformMatrix4fv( g_hProjMatrixLoc, 1, 0, matProj );
|
||||||
|
glVertexAttrib4fv(g_hVColor, color);
|
||||||
|
|
||||||
|
// Bind the vertex attributes
|
||||||
|
glVertexAttribPointer( g_hVertexLoc, 3, GL_FLOAT, 0, 0, VertexPositions );
|
||||||
|
glEnableVertexAttribArray( g_hVertexLoc );
|
||||||
|
|
||||||
|
glDrawArrays( GL_TRIANGLES, 0, 3 );
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
glDisableVertexAttribArray( g_hVertexLoc );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void print_glinfo() {
|
||||||
|
printf("OpenGL information:\n");
|
||||||
|
printf(" version: \"%s\"\n", glGetString(GL_VERSION));
|
||||||
|
printf(" shading language version: \"%s\"\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||||
|
printf(" vendor: \"%s\"\n", glGetString(GL_VENDOR));
|
||||||
|
printf(" renderer: \"%s\"\n", glGetString(GL_RENDERER));
|
||||||
|
// printf(" extensions: \"%s\"\n", glGetString(GL_EXTENSIONS));
|
||||||
|
printf("===================================\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PRINT_CONFIG(display, config, type) \
|
||||||
|
{ int _tmp; eglGetConfigAttrib(display, config, type, &_tmp); printf("config val " #type ":0x%x\n", _tmp);}
|
||||||
|
|
||||||
|
|
||||||
|
static int matchConfigToVisual(EGLDisplay display, EGLint visualId, EGLConfig* configs, int count)
|
||||||
|
{
|
||||||
|
EGLint id = 0;
|
||||||
|
EGLint suf_type;
|
||||||
|
int retId = -1;
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!eglGetConfigAttrib(display, configs[i], EGL_NATIVE_VISUAL_ID, &id))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// PRINT_CONFIG(display, configs[i], EGL_SURFACE_TYPE);
|
||||||
|
// PRINT_CONFIG(display, configs[i], EGL_MAX_SWAP_INTERVAL);
|
||||||
|
// PRINT_CONFIG(display, configs[i], EGL_MIN_SWAP_INTERVAL);
|
||||||
|
// printf("visualid: 0x%x, str:%.*s\n=====================\n", id, 4, &id);
|
||||||
|
if (id == visualId) {
|
||||||
|
retId = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return retId;
|
||||||
|
}
|
||||||
|
|
||||||
|
int init(void)
|
||||||
|
{
|
||||||
|
EGLint count = 0;
|
||||||
|
EGLint numConfigs = 0;
|
||||||
|
|
||||||
|
x_display = XOpenDisplay (NULL);
|
||||||
|
if (!x_display) {
|
||||||
|
printf("XOpenDisplay failed!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
Window root = DefaultRootWindow( x_display );
|
||||||
|
|
||||||
|
XSetWindowAttributes swa;
|
||||||
|
swa.event_mask = ExposureMask | PointerMotionMask | KeyPressMask | StructureNotifyMask;
|
||||||
|
swa.override_redirect = True;
|
||||||
|
|
||||||
|
// 创建窗口
|
||||||
|
win = XCreateWindow ( // create a window with the provided parameters
|
||||||
|
x_display, root,
|
||||||
|
0, 0, 1000, 1000, 0,
|
||||||
|
CopyFromParent, InputOutput,
|
||||||
|
CopyFromParent,
|
||||||
|
CWEventMask | CWOverrideRedirect,
|
||||||
|
&swa );
|
||||||
|
|
||||||
|
XMapWindow ( x_display , win); // make the window visible on the screen
|
||||||
|
XStoreName ( x_display , win , "GL test"); // give the window a name
|
||||||
|
|
||||||
|
XSelectInput(x_display, win, StructureNotifyMask);
|
||||||
|
egldisplay = eglGetDisplay((EGLNativeDisplayType)x_display);
|
||||||
|
|
||||||
|
int majo, mino;
|
||||||
|
eglInitialize(egldisplay, &majo, &mino);
|
||||||
|
printf("egl ver: %d.%d\n", majo, mino);
|
||||||
|
ASSERT_EQ(eglGetError(), EGL_SUCCESS);
|
||||||
|
eglBindAPI(EGL_OPENGL_ES_API);
|
||||||
|
|
||||||
|
|
||||||
|
static const EGLint s_configAttribs[] =
|
||||||
|
{
|
||||||
|
EGL_GREEN_SIZE, 8,
|
||||||
|
EGL_BLUE_SIZE, 8,
|
||||||
|
EGL_RED_SIZE, 8,
|
||||||
|
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT,
|
||||||
|
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
eglGetConfigs(egldisplay, NULL, 0, &count);
|
||||||
|
EGLConfig* configs = malloc(count * sizeof(EGLConfig));
|
||||||
|
|
||||||
|
eglChooseConfig(egldisplay, s_configAttribs, configs, count, &numConfigs);
|
||||||
|
ASSERT_EQ(eglGetError(), EGL_SUCCESS);
|
||||||
|
printf("configs num: %d\n", numConfigs);
|
||||||
|
|
||||||
|
int indexCfg = matchConfigToVisual(egldisplay, USE_FORMAT, configs, numConfigs);
|
||||||
|
printf("configs indexCfg: %d\n", indexCfg);
|
||||||
|
if (indexCfg < 0) {
|
||||||
|
indexCfg = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
eglconfig = configs[indexCfg];
|
||||||
|
|
||||||
|
EGLint ContextAttribList[] = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE };
|
||||||
|
eglcontext = eglCreateContext( egldisplay, eglconfig, EGL_NO_CONTEXT, ContextAttribList );
|
||||||
|
ASSERT_EQ(eglGetError(), EGL_SUCCESS);
|
||||||
|
|
||||||
|
|
||||||
|
EGLint win_attrlist[] = {
|
||||||
|
EGL_NONE,
|
||||||
|
};
|
||||||
|
// 使用窗口区域创建绘制平面
|
||||||
|
eglsurface = eglCreateWindowSurface(egldisplay, eglconfig, (EGLNativeWindowType)(win), win_attrlist);
|
||||||
|
|
||||||
|
ASSERT_EQ(eglGetError(), EGL_SUCCESS);
|
||||||
|
if (eglsurface == EGL_NO_SURFACE) {
|
||||||
|
int e = eglGetError();
|
||||||
|
printf("EGL_NO_SURFACE ! error_num: %p\n", e);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
eglMakeCurrent(egldisplay, eglsurface, eglsurface, eglcontext);
|
||||||
|
ASSERT_EQ(eglGetError(), EGL_SUCCESS);
|
||||||
|
|
||||||
|
// disable refresh rate limit
|
||||||
|
if (!eglSwapInterval || !eglSwapInterval(egldisplay, 0)) {
|
||||||
|
printf("Failed to set swap interval. Results may be bounded above by refresh rate.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
print_glinfo();
|
||||||
|
|
||||||
|
{
|
||||||
|
// Compile the shaders
|
||||||
|
GLuint hVertexShader = glCreateShader( GL_VERTEX_SHADER );
|
||||||
|
glShaderSource( hVertexShader, 1, &g_strVertexShader, NULL );
|
||||||
|
glCompileShader( hVertexShader );
|
||||||
|
|
||||||
|
// Check for compile success
|
||||||
|
GLint nCompileResult = 0;
|
||||||
|
glGetShaderiv( hVertexShader, GL_COMPILE_STATUS, &nCompileResult );
|
||||||
|
if( 0 == nCompileResult )
|
||||||
|
{
|
||||||
|
char strLog[1024];
|
||||||
|
GLint nLength;
|
||||||
|
glGetShaderInfoLog( hVertexShader, 1024, &nLength, strLog );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint hFragmentShader = glCreateShader( GL_FRAGMENT_SHADER );
|
||||||
|
glShaderSource( hFragmentShader, 1, &g_strFragmentShader, NULL );
|
||||||
|
glCompileShader( hFragmentShader );
|
||||||
|
|
||||||
|
// Check for compile success
|
||||||
|
glGetShaderiv( hFragmentShader, GL_COMPILE_STATUS, &nCompileResult );
|
||||||
|
if( 0 == nCompileResult )
|
||||||
|
{
|
||||||
|
char strLog[1024];
|
||||||
|
GLint nLength;
|
||||||
|
glGetShaderInfoLog( hFragmentShader, 1024, &nLength, strLog );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach the individual shaders to the common shader program
|
||||||
|
g_hShaderProgram = glCreateProgram();
|
||||||
|
glAttachShader( g_hShaderProgram, hVertexShader );
|
||||||
|
glAttachShader( g_hShaderProgram, hFragmentShader );
|
||||||
|
|
||||||
|
// Init attributes BEFORE linking
|
||||||
|
glBindAttribLocation( g_hShaderProgram, g_hVertexLoc, "g_vPosition" );
|
||||||
|
|
||||||
|
// Link the vertex shader and fragment shader together
|
||||||
|
glLinkProgram( g_hShaderProgram );
|
||||||
|
|
||||||
|
// Check for link success
|
||||||
|
GLint nLinkResult = 0;
|
||||||
|
glGetProgramiv( g_hShaderProgram, GL_LINK_STATUS, &nLinkResult );
|
||||||
|
if( 0 == nLinkResult )
|
||||||
|
{
|
||||||
|
char strLog[1024];
|
||||||
|
GLint nLength;
|
||||||
|
glGetProgramInfoLog( g_hShaderProgram, 1024, &nLength, strLog );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get uniform locations
|
||||||
|
g_hModelViewMatrixLoc = glGetUniformLocation( g_hShaderProgram, "g_matModelView" );
|
||||||
|
g_hProjMatrixLoc = glGetUniformLocation( g_hShaderProgram, "g_matProj" );
|
||||||
|
g_hVColor = glGetAttribLocation( g_hShaderProgram, "g_vColor" );
|
||||||
|
|
||||||
|
|
||||||
|
glDeleteShader( hVertexShader );
|
||||||
|
glDeleteShader( hFragmentShader );
|
||||||
|
|
||||||
|
// Set the shader program
|
||||||
|
glUseProgram( g_hShaderProgram );
|
||||||
|
|
||||||
|
// Clear the colorbuffer and depth-buffer
|
||||||
|
glClearColor( 0.0f, 0.0f, 0.5f, 1.0f );
|
||||||
|
|
||||||
|
// Set some state
|
||||||
|
glEnable( GL_DEPTH_TEST );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void resize(int w, int h)
|
||||||
|
{
|
||||||
|
// Build a perspective projection matrix
|
||||||
|
matProj[ 0] = cosf( 0.5f ) / sinf( 0.5f );
|
||||||
|
matProj[ 5] = matProj[0] * (w/h) ;
|
||||||
|
matProj[10] = -( 10.0f ) / ( 9.0f );
|
||||||
|
matProj[11] = -1.0f;
|
||||||
|
matProj[14] = -( 10.0f ) / ( 9.0f );
|
||||||
|
|
||||||
|
glViewport(0, 0, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deinit(void)
|
||||||
|
{
|
||||||
|
printf("Cleaning up...\n");
|
||||||
|
eglMakeCurrent(egldisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
|
assert(eglGetError() == EGL_SUCCESS);
|
||||||
|
eglDestroyContext(egldisplay, eglcontext);
|
||||||
|
eglDestroySurface(egldisplay, eglsurface);
|
||||||
|
eglTerminate(egldisplay);
|
||||||
|
assert(eglGetError() == EGL_SUCCESS);
|
||||||
|
eglReleaseThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
int event_handle(void* arg) {
|
||||||
|
printf("start event loop\n");
|
||||||
|
while (1) {
|
||||||
|
XEvent xevent;
|
||||||
|
// XWindowEvent(x_display, win, StructureNotifyMask, &xevent);
|
||||||
|
XNextEvent(x_display, &xevent);
|
||||||
|
if (xevent.type == DestroyNotify) {
|
||||||
|
printf("DestroyNotify \n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_sig(int sig) {
|
||||||
|
printf("recieve sig: %d\n", sig);
|
||||||
|
g_stop = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_signal() {
|
||||||
|
signal(SIGABRT, handle_sig);
|
||||||
|
signal(SIGHUP, handle_sig);
|
||||||
|
signal(SIGINT, handle_sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
long GetNowMillis() {
|
||||||
|
struct timeval t;
|
||||||
|
gettimeofday(&t, NULL);
|
||||||
|
return t.tv_sec*1000 + t.tv_usec/1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
EGLint width = 600;
|
||||||
|
EGLint height = 600;
|
||||||
|
int ret;
|
||||||
|
ret = init();
|
||||||
|
if (ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
init_signal();
|
||||||
|
|
||||||
|
eglQuerySurface(egldisplay, eglsurface, EGL_WIDTH, &width);
|
||||||
|
eglQuerySurface(egldisplay, eglsurface, EGL_HEIGHT, &height);
|
||||||
|
|
||||||
|
printf("w=%d h=%d\n",width,height);
|
||||||
|
|
||||||
|
thrd_t thr;
|
||||||
|
thrd_create(&thr, event_handle, NULL);
|
||||||
|
|
||||||
|
long lastTime = GetNowMillis();
|
||||||
|
unsigned int framenum = 0;
|
||||||
|
while (!g_stop) {
|
||||||
|
render(width, height, framenum);
|
||||||
|
eglSwapBuffers(egldisplay, eglsurface);
|
||||||
|
|
||||||
|
//usleep(1*1000);
|
||||||
|
framenum++;
|
||||||
|
|
||||||
|
if (!(framenum%100)) {
|
||||||
|
long now = GetNowMillis();
|
||||||
|
printf("frame num:%d, fps: %.1f\n", framenum, 100/((now-lastTime)/1000.0));
|
||||||
|
lastTime = now;
|
||||||
|
}
|
||||||
|
if (framenum > 100000) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -26,7 +26,7 @@
|
||||||
#include "EGL/egl.h"
|
#include "EGL/egl.h"
|
||||||
#include "EGL/eglext.h"
|
#include "EGL/eglext.h"
|
||||||
|
|
||||||
#define XORG_SHOW
|
// #define XORG_SHOW
|
||||||
|
|
||||||
#include <libdrm/drm.h>
|
#include <libdrm/drm.h>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user