add a pure x11 + egl simple demo
This commit is contained in:
parent
4e271b7943
commit
a6e5e145e3
|
@ -22,7 +22,7 @@ include_directories(
|
|||
link_directories(
|
||||
"/usr/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)
|
||||
|
||||
# 查找对应的第三方库
|
||||
|
|
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/eglext.h"
|
||||
|
||||
#define XORG_SHOW
|
||||
// #define XORG_SHOW
|
||||
|
||||
#include <libdrm/drm.h>
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user