SimpleGL example
mr_smiley (Talk | contribs)
(New page: #include <stdio.h> #include <stdlib.h> #include <X11/Xatom.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #include <GLES2/gl2.h> #include <EGL/egl.h> #include <math.h> #include <...)
Newer edit →
(New page: #include <stdio.h> #include <stdlib.h> #include <X11/Xatom.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #include <GLES2/gl2.h> #include <EGL/egl.h> #include <math.h> #include <...)
Newer edit →
Revision as of 11:27, 21 December 2009
#include <stdio.h> #include <stdlib.h> #include <X11/Xatom.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #include <GLES2/gl2.h> #include <EGL/egl.h> #include <math.h> #include <sys/time.h> #include <unistd.h> #include <string.h> const char* vertexSrc = "attribute vec4 position; varying mediump vec2 pos; uniform vec4 offset; void main() { gl_Position = position + offset; pos = position.xy; }"; const char* fragmentSrc = "varying mediump vec2 pos; uniform mediump float phase; void main() { gl_FragColor = vec4(1, 1, 1, 1) * sin((pos.x * pos.x + pos.y * pos.y) * 40.0 + phase); }"; void printShaderInfoLog(GLuint shader) { GLint length; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length); if(length) { char* buffer = new char[length]; glGetShaderInfoLog(shader, length, NULL, buffer); printf("%s", buffer); delete [] buffer; GLint success; glGetShaderiv(shader, GL_COMPILE_STATUS, &success); if(success != GL_TRUE) { exit(1); } } } GLuint createShader(GLenum type, const char* pSource) { GLuint shader = glCreateShader(type); glShaderSource(shader, 1, &pSource, NULL); glCompileShader(shader); printShaderInfoLog(shader); return shader; } Display* dpy; Window win; EGLDisplay edpy; EGLContext ectxt; int phaseLocation; GLfloat norm_x; GLfloat norm_y; GLfloat offset_x = 0.0; GLfloat offset_y = 0.0; GLfloat p1_pos_x; GLfloat p1_pos_y; GLint offset; EGLSurface esfc; bool update_pos = false; const float vertexArray[] = { -0.85, -1, 0, 1, -1, -0.7, 0, 1, -0.7, -0.7, 0, 1 }; void render() { static float offset_blah = 0; static int donesetup=0; static XWindowAttributes gwa; // draw if (!donesetup) { XWindowAttributes gwa; XGetWindowAttributes(dpy, win, &gwa); glViewport(0, 0, gwa.width, gwa.height); glClearColor(0, 1, 0, 1); donesetup = 1; } glClear(GL_COLOR_BUFFER_BIT); glUniform1f(phaseLocation, offset_blah); if (update_pos) { GLfloat old_offset_x = offset_x; GLfloat old_offset_y = offset_y; offset_x = norm_x - p1_pos_x; offset_y = norm_y - p1_pos_y; p1_pos_x = norm_x; p1_pos_y = norm_y; offset_x += old_offset_x; offset_y += old_offset_y; update_pos = false; } glUniform4f(offset, offset_x, offset_y, 0, 0); glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, vertexArray); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); eglSwapBuffers(edpy, esfc); offset_blah = fmodf(offset_blah + 0.5, 2*3.141f); } int main() { dpy = XOpenDisplay(NULL); if(dpy == NULL) { printf("cannot connect to X server\n"); return 1; } Window root = DefaultRootWindow(dpy); XSetWindowAttributes swa; swa.event_mask = ExposureMask | PointerMotionMask; win = XCreateWindow(dpy, root, 0, 0, 600, 400, 0, CopyFromParent, InputOutput, CopyFromParent, CWEventMask, &swa); XSetWindowAttributes xattr; Atom atom; int one = 1; xattr.override_redirect = False; XChangeWindowAttributes(dpy, win, CWOverrideRedirect, &xattr); atom = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", True); XChangeProperty(dpy, win, XInternAtom(dpy, "_NET_WM_STATE", True), XA_ATOM, 32, PropModeReplace, (unsigned char *) &atom, 1); XChangeProperty(dpy, win, XInternAtom(dpy, "_HILDON_NON_COMPOSITED_WINDOW", True), XA_INTEGER, 32, PropModeReplace, (unsigned char *) &one, 1); XMapWindow(dpy, win); XStoreName(dpy, win, "GL test"); Atom wm_state = XInternAtom(dpy, "_NET_WM_STATE", False); Atom fullscreen = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); XEvent xev; memset(&xev, 0, sizeof(xev)); xev.type = ClientMessage; xev.xclient.window = win; xev.xclient.message_type = wm_state; xev.xclient.format = 32; xev.xclient.data.l[0] = 1; xev.xclient.data.l[1] = fullscreen; XSendEvent(dpy, DefaultRootWindow(dpy), False, SubstructureNotifyMask, &xev); edpy = eglGetDisplay((EGLNativeDisplayType)dpy); if(edpy == EGL_NO_DISPLAY) { printf("Got no EGL display\n"); return 1; } if(!eglInitialize(edpy, NULL, NULL)) { printf("Unable to initialize EGL\n"); return 1; } EGLint attr[] = { EGL_BUFFER_SIZE, 16, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE }; EGLConfig ecfg; EGLint num_config; if(!eglChooseConfig(edpy, attr, &ecfg, 1, &num_config)) { printf("Failed to choose config (%x)\n", eglGetError()); return 1; } if(num_config != 1) { printf("Didn't get exactly one config, but %d\n", num_config); return 1; } esfc = eglCreateWindowSurface(edpy, ecfg, (void*)win, NULL); if(esfc == EGL_NO_SURFACE) { printf("Unable to create EGL surface (%x)\n", eglGetError()); return 1; } EGLint ctxattr[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; ectxt = eglCreateContext(edpy, ecfg, EGL_NO_CONTEXT, ctxattr); if(ectxt == EGL_NO_CONTEXT) { printf("Unable to create EGL context (%x)\n", eglGetError()); return 1; } eglMakeCurrent(edpy, esfc, esfc, ectxt); GLuint shaderProgram = glCreateProgram(); GLuint vertexShader = createShader(GL_VERTEX_SHADER, vertexSrc); GLuint fragmentShader = createShader(GL_FRAGMENT_SHADER, fragmentSrc); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); glUseProgram(shaderProgram); phaseLocation = glGetUniformLocation(shaderProgram, "phase"); offset = glGetUniformLocation(shaderProgram, "offset"); if(phaseLocation < 0) { printf("Unable to get uniform location\n"); return 1; } bool quit = false; timeval startTime; timezone tz; gettimeofday(&startTime, &tz); int numFrames = 0; float window_width = 800.0; float window_height = 480.0; norm_x = -0.85; norm_y = -1; p1_pos_x = -0.85; p1_pos_y = -1; while(!quit) { while(XPending(dpy)) { XEvent xev; XNextEvent(dpy, &xev); if(xev.type == MotionNotify) { //printf("move to: (%d,%d)\n", xev.xmotion.x, xev.xmotion.y); GLfloat window_y = (window_height - xev.xmotion.y) - window_height / 2.0; norm_y = window_y / (window_height / 2.0); GLfloat window_x = xev.xmotion.x - window_width / 2.0; norm_x = window_x / (window_width / 2.0); update_pos = true; //quit = true; } } render(); numFrames++; if(numFrames % 100 == 0) { timeval now; gettimeofday(&now, &tz); float delta = now.tv_sec - startTime.tv_sec + (now.tv_usec - startTime.tv_usec) * 0.000001f; printf("fps: %f\n", numFrames / delta); } usleep(1000*30); } eglDestroyContext(edpy, ectxt); eglDestroySurface(edpy, esfc); eglTerminate(edpy); XDestroyWindow(dpy, win); XCloseDisplay(dpy); return 0; }