Advertisement
Guest User

gl example

a guest
Mar 31st, 2013
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 14.87 KB | None | 0 0
  1. /**************************************************************************
  2.  *
  3.  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
  4.  * All Rights Reserved.
  5.  *
  6.  **************************************************************************/
  7.  
  8. /*
  9.  * Draw a triangle with X/EGL and OpenGL ES 2.x
  10.  */
  11.  
  12. #define USE_FULL_GL 0
  13.  
  14.  
  15.  
  16. #include <assert.h>
  17. #include <math.h>
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <X11/Xlib.h>
  22. #include <X11/Xutil.h>
  23. #include <X11/keysym.h>
  24. #if USE_FULL_GL
  25. #include "gl_wrap.h"  /* use full OpenGL */
  26. #else
  27. #include <GLES2/gl2.h>  /* use OpenGL ES 2.x */
  28. #endif
  29. #include <EGL/egl.h>
  30.  
  31.  
  32. #define FLOAT_TO_FIXED(X)   ((X) * 65535.0)
  33.  
  34.  
  35.  
  36. static GLfloat view_rotx = 0.0, view_roty = 0.0;
  37.  
  38. static GLint u_matrix = -1;
  39. static GLint attr_pos = 0, attr_color = 1;
  40.  
  41.  
  42. static void make_x_rot_matrix(GLfloat angle, GLfloat *m)
  43. {
  44.    float c = cos(angle * M_PI / 180.0);
  45.    float s = sin(angle * M_PI / 180.0);
  46.    int i;
  47.    for (i = 0; i < 16; i++)
  48.       m[i] = 0.0;
  49.    m[0] = m[5] = m[10] = m[15] = 1.0;
  50.  
  51.    m[5] = c;
  52.    m[6] = s;
  53.    m[9] = -s;
  54.    m[10] = c;
  55. }
  56.  
  57. static void make_y_rot_matrix(GLfloat angle, GLfloat *m)
  58. {
  59.    float c = cos(angle * M_PI / 180.0);
  60.    float s = sin(angle * M_PI / 180.0);
  61.    int i;
  62.    for (i = 0; i < 16; i++)
  63.       m[i] = 0.0;
  64.    m[0] = m[5] = m[10] = m[15] = 1.0;
  65.  
  66.    m[0] = c;
  67.    m[3] = s;
  68.    m[8] = -s;
  69.    m[10] = c;
  70. }
  71.  
  72. static void
  73. make_scale_matrix(GLfloat xs, GLfloat ys, GLfloat zs, GLfloat *m)
  74. {
  75.    int i;
  76.    for (i = 0; i < 16; i++)
  77.       m[i] = 0.0;
  78.    m[0] = xs;
  79.    m[5] = ys;
  80.    m[10] = zs;
  81.    m[15] = 1.0;
  82. }
  83.  
  84.  
  85. static void
  86. mul_matrix(GLfloat *prod, const GLfloat *a, const GLfloat *b)
  87. {
  88. #define A(row,col)  a[(col<<2)+row]
  89. #define B(row,col)  b[(col<<2)+row]
  90. #define P(row,col)  p[(col<<2)+row]
  91.    GLfloat p[16];
  92.    GLint i;
  93.    for (i = 0; i < 4; i++) {
  94.       const GLfloat ai0=A(i,0),  ai1=A(i,1),  ai2=A(i,2),  ai3=A(i,3);
  95.       P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0);
  96.       P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1);
  97.       P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2);
  98.       P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3);
  99.    }
  100.    memcpy(prod, p, sizeof(p));
  101. #undef A
  102. #undef B
  103. #undef PROD
  104. }
  105.  
  106.  
  107. static void
  108. draw(void)
  109. {
  110.    static const GLfloat verts[4][3] = {
  111.       {  1,  1,  1 },
  112.       { -1,  1, -1 },
  113.       { -1, -1,  1 },
  114.       {  1, -1, -1 }
  115.    };
  116.    static GLfloat colors[12][3] = {
  117.       { 1, 0, 0 },
  118.       { 0, 1, 0 },
  119.       { 0, 0, 1 },
  120.  
  121.       { 1, 0, 0 },
  122.       { 0, 0, 1 },
  123.       { 0, 1, 0 },
  124.  
  125.       { 1, 0, 0 },
  126.       { 0, 1, 0 },
  127.       { 0, 0, 1 },
  128.  
  129.       { 1, 0, 0 },
  130.       { 0, 0, 1 },
  131.       { 0, 1, 0 },
  132.    };
  133.    GLfloat mat[16], rot[16], x_rot[16], y_rot[16], scale[16];
  134.  
  135.    /* Set modelview/projection matrix */
  136.    make_x_rot_matrix(view_rotx, x_rot);
  137.    make_y_rot_matrix(view_roty, y_rot);
  138.    make_scale_matrix(0.5, 0.5, 0.5, scale);
  139.    mul_matrix(rot, y_rot, x_rot);
  140.    mul_matrix(mat, rot, scale);
  141.    glUniformMatrix4fv(u_matrix, 1, GL_FALSE, mat);
  142.  
  143.    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  144.  
  145.    {
  146.       static GLfloat tri_verts[3][3] = {0};
  147.       int i = 0;
  148.       for (; i < 2; ++i) {
  149.       glVertexAttribPointer(attr_color, 3, GL_FLOAT, GL_FALSE, 0, colors + i*3);
  150.       glEnableVertexAttribArray(attr_color);
  151.  
  152.        
  153.         memcpy(tri_verts[0], verts[i], 3*sizeof(GLfloat));
  154.         memcpy(tri_verts[1], verts[i], 3*sizeof(GLfloat));
  155.         memcpy(tri_verts[2], verts[i], 3*sizeof(GLfloat));
  156.         tri_verts[1][0] = -tri_verts[0][0];
  157.         tri_verts[2][1] = -tri_verts[0][1];
  158.         glVertexAttribPointer(attr_pos, 3, GL_FLOAT, GL_FALSE, 0, tri_verts);
  159.         glEnableVertexAttribArray(attr_pos);
  160.         glDrawArrays(GL_TRIANGLES, 0, 3);
  161.         glDisableVertexAttribArray(attr_pos);
  162.         tri_verts[1][0] = tri_verts[0][0];
  163.         tri_verts[2][1] = tri_verts[0][1];
  164.  
  165.         tri_verts[1][0] = -tri_verts[0][0];
  166.         tri_verts[2][2] = -tri_verts[0][2];
  167.         glVertexAttribPointer(attr_pos, 3, GL_FLOAT, GL_FALSE, 0, tri_verts);
  168.         glEnableVertexAttribArray(attr_pos);
  169.         glDrawArrays(GL_TRIANGLES, 0, 3);
  170.         glDisableVertexAttribArray(attr_pos);
  171.         tri_verts[1][0] = tri_verts[0][0];
  172.         tri_verts[2][2] = tri_verts[0][2];
  173.  
  174.         tri_verts[1][1] = -tri_verts[0][1];
  175.         tri_verts[2][2] = -tri_verts[0][2];
  176.         glVertexAttribPointer(attr_pos, 3, GL_FLOAT, GL_FALSE, 0, tri_verts);
  177.         glEnableVertexAttribArray(attr_pos);
  178.         glDrawArrays(GL_TRIANGLES, 0, 3);
  179.         glDisableVertexAttribArray(attr_pos);
  180.  
  181.         glDisableVertexAttribArray(attr_color);
  182.       }
  183.      
  184.    }
  185. }
  186.  
  187.  
  188. /* new window size or exposure */
  189. static void
  190. reshape(int width, int height)
  191. {
  192.    glViewport(0, 0, (GLint) width, (GLint) height);
  193. }
  194.  
  195.  
  196. static void
  197. create_shaders(void)
  198. {
  199.    static const char *fragShaderText =
  200.       "varying vec4 v_color;\n"
  201.       "void main() {\n"
  202.       "   gl_FragColor = v_color;\n"
  203.       "}\n";
  204.    static const char *vertShaderText =
  205.       "uniform mat4 modelviewProjection;\n"
  206.       "attribute vec4 pos;\n"
  207.       "attribute vec4 color;\n"
  208.       "varying vec4 v_color;\n"
  209.       "void main() {\n"
  210.       "   gl_Position = modelviewProjection * pos;\n"
  211.       "   v_color = color;\n"
  212.       "}\n";
  213.  
  214.    GLuint fragShader, vertShader, program;
  215.    GLint stat;
  216.  
  217.    fragShader = glCreateShader(GL_FRAGMENT_SHADER);
  218.    glShaderSource(fragShader, 1, (const char **) &fragShaderText, NULL);
  219.    glCompileShader(fragShader);
  220.    glGetShaderiv(fragShader, GL_COMPILE_STATUS, &stat);
  221.    if (!stat) {
  222.       printf("Error: fragment shader did not compile!\n");
  223.       exit(1);
  224.    }
  225.  
  226.    vertShader = glCreateShader(GL_VERTEX_SHADER);
  227.    glShaderSource(vertShader, 1, (const char **) &vertShaderText, NULL);
  228.    glCompileShader(vertShader);
  229.    glGetShaderiv(vertShader, GL_COMPILE_STATUS, &stat);
  230.    if (!stat) {
  231.       printf("Error: vertex shader did not compile!\n");
  232.       exit(1);
  233.    }
  234.  
  235.    program = glCreateProgram();
  236.    glAttachShader(program, fragShader);
  237.    glAttachShader(program, vertShader);
  238.    glLinkProgram(program);
  239.  
  240.    glGetProgramiv(program, GL_LINK_STATUS, &stat);
  241.    if (!stat) {
  242.       char log[1000];
  243.       GLsizei len;
  244.       glGetProgramInfoLog(program, 1000, &len, log);
  245.       printf("Error: linking:\n%s\n", log);
  246.       exit(1);
  247.    }
  248.  
  249.    glUseProgram(program);
  250.  
  251.    if (1) {
  252.       /* test setting attrib locations */
  253.       glBindAttribLocation(program, attr_pos, "pos");
  254.       glBindAttribLocation(program, attr_color, "color");
  255.       glLinkProgram(program);  /* needed to put attribs into effect */
  256.    }
  257.    else {
  258.       /* test automatic attrib locations */
  259.       attr_pos = glGetAttribLocation(program, "pos");
  260.       attr_color = glGetAttribLocation(program, "color");
  261.    }
  262.  
  263.    u_matrix = glGetUniformLocation(program, "modelviewProjection");
  264.    printf("Uniform modelviewProjection at %d\n", u_matrix);
  265.    printf("Attrib pos at %d\n", attr_pos);
  266.    printf("Attrib color at %d\n", attr_color);
  267. }
  268.  
  269.  
  270. static void
  271. init(void)
  272. {
  273.    typedef void (*proc)();
  274.  
  275. #if 1 /* test code */
  276.    proc p = eglGetProcAddress("glMapBufferOES");
  277.    assert(p);
  278. #endif
  279.  
  280.    glClearColor(0.4, 0.4, 0.4, 0.0);
  281.    glCullFace(GL_BACK);
  282.  
  283.    create_shaders();
  284. }
  285.  
  286.  
  287. /*
  288.  * Create an RGB, double-buffered X window.
  289.  * Return the window and context handles.
  290.  */
  291. static void
  292. make_x_window(Display *x_dpy, EGLDisplay egl_dpy,
  293.               const char *name,
  294.               int x, int y, int width, int height,
  295.               Window *winRet,
  296.               EGLContext *ctxRet,
  297.               EGLSurface *surfRet)
  298. {
  299.    static const EGLint attribs[] = {
  300.       EGL_RED_SIZE, 1,
  301.       EGL_GREEN_SIZE, 1,
  302.       EGL_BLUE_SIZE, 1,
  303.       EGL_DEPTH_SIZE, 1,
  304.       EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
  305.       EGL_NONE
  306.    };
  307. #if USE_FULL_GL
  308.    static const EGLint ctx_attribs[] = {
  309.        EGL_NONE
  310.    };
  311. #else
  312.    static const EGLint ctx_attribs[] = {
  313.       EGL_CONTEXT_CLIENT_VERSION, 2,
  314.       EGL_NONE
  315.    };
  316. #endif
  317.  
  318.    int scrnum;
  319.    XSetWindowAttributes attr;
  320.    unsigned long mask;
  321.    Window root;
  322.    Window win;
  323.    XVisualInfo *visInfo, visTemplate;
  324.    int num_visuals;
  325.    EGLContext ctx;
  326.    EGLConfig config;
  327.    EGLint num_configs;
  328.    EGLint vid;
  329.  
  330.    scrnum = DefaultScreen( x_dpy );
  331.    root = RootWindow( x_dpy, scrnum );
  332.  
  333.    if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) {
  334.       printf("Error: couldn't get an EGL visual config\n");
  335.       exit(1);
  336.    }
  337.  
  338.    assert(config);
  339.    assert(num_configs > 0);
  340.  
  341.    if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
  342.       printf("Error: eglGetConfigAttrib() failed\n");
  343.       exit(1);
  344.    }
  345.  
  346.    /* The X window visual must match the EGL config */
  347.    visTemplate.visualid = vid;
  348.    visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals);
  349.    if (!visInfo) {
  350.       printf("Error: couldn't get X visual\n");
  351.       exit(1);
  352.    }
  353.  
  354.    /* window attributes */
  355.    attr.background_pixel = 0;
  356.    attr.border_pixel = 0;
  357.    attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone);
  358.    attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
  359.    mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
  360.  
  361.    win = XCreateWindow( x_dpy, root, 0, 0, width, height,
  362.                 0, visInfo->depth, InputOutput,
  363.                 visInfo->visual, mask, &attr );
  364.  
  365.    /* set hints and properties */
  366.    {
  367.       XSizeHints sizehints;
  368.       sizehints.x = x;
  369.       sizehints.y = y;
  370.       sizehints.width  = width;
  371.       sizehints.height = height;
  372.       sizehints.flags = USSize | USPosition;
  373.       XSetNormalHints(x_dpy, win, &sizehints);
  374.       XSetStandardProperties(x_dpy, win, name, name,
  375.                               None, (char **)NULL, 0, &sizehints);
  376.    }
  377.  
  378. #if USE_FULL_GL /* XXX fix this when eglBindAPI() works */
  379.    eglBindAPI(EGL_OPENGL_API);
  380. #else
  381.    eglBindAPI(EGL_OPENGL_ES_API);
  382. #endif
  383.  
  384.    ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, ctx_attribs );
  385.    if (!ctx) {
  386.       printf("Error: eglCreateContext failed\n");
  387.       exit(1);
  388.    }
  389.  
  390. #if !USE_FULL_GL
  391.    /* test eglQueryContext() */
  392.    {
  393.       EGLint val;
  394.       eglQueryContext(egl_dpy, ctx, EGL_CONTEXT_CLIENT_VERSION, &val);
  395.       assert(val == 2);
  396.    }
  397. #endif
  398.  
  399.    *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL);
  400.    if (!*surfRet) {
  401.       printf("Error: eglCreateWindowSurface failed\n");
  402.       exit(1);
  403.    }
  404.  
  405.    /* sanity checks */
  406.    {
  407.       EGLint val;
  408.       eglQuerySurface(egl_dpy, *surfRet, EGL_WIDTH, &val);
  409.       assert(val == width);
  410.       eglQuerySurface(egl_dpy, *surfRet, EGL_HEIGHT, &val);
  411.       assert(val == height);
  412.       assert(eglGetConfigAttrib(egl_dpy, config, EGL_SURFACE_TYPE, &val));
  413.       assert(val & EGL_WINDOW_BIT);
  414.    }
  415.  
  416.    XFree(visInfo);
  417.  
  418.    *winRet = win;
  419.    *ctxRet = ctx;
  420. }
  421.  
  422.  
  423. static void
  424. event_loop(Display *dpy, Window win,
  425.            EGLDisplay egl_dpy, EGLSurface egl_surf)
  426. {
  427.    while (1) {
  428.       int redraw = 0;
  429.       XEvent event;
  430.  
  431.       XNextEvent(dpy, &event);
  432.  
  433.       switch (event.type) {
  434.       case Expose:
  435.          redraw = 1;
  436.          break;
  437.       case ConfigureNotify:
  438.          reshape(event.xconfigure.width, event.xconfigure.height);
  439.          break;
  440.       case KeyPress:
  441.          {
  442.             char buffer[10];
  443.             int r, code;
  444.             code = XLookupKeysym(&event.xkey, 0);
  445.             if (code == XK_Left) {
  446.                view_roty += 5.0;
  447.             }
  448.             else if (code == XK_Right) {
  449.                view_roty -= 5.0;
  450.             }
  451.             else if (code == XK_Up) {
  452.                view_rotx += 5.0;
  453.             }
  454.             else if (code == XK_Down) {
  455.                view_rotx -= 5.0;
  456.             }
  457.             else {
  458.                r = XLookupString(&event.xkey, buffer, sizeof(buffer),
  459.                                  NULL, NULL);
  460.                if (buffer[0] == 27) {
  461.                   /* escape */
  462.                   return;
  463.                }
  464.             }
  465.          }
  466.          redraw = 1;
  467.          break;
  468.       default:
  469.          ; /*no-op*/
  470.       }
  471.  
  472.       if (redraw) {
  473.          draw();
  474.          eglSwapBuffers(egl_dpy, egl_surf);
  475.       }
  476.    }
  477. }
  478.  
  479.  
  480. static void
  481. usage(void)
  482. {
  483.    printf("Usage:\n");
  484.    printf("  -display <displayname>  set the display to run on\n");
  485.    printf("  -info                   display OpenGL renderer info\n");
  486. }
  487.  
  488.  
  489. int
  490. main(int argc, char *argv[])
  491. {
  492.    const int winWidth = 300, winHeight = 300;
  493.    Display *x_dpy;
  494.    Window win;
  495.    EGLSurface egl_surf;
  496.    EGLContext egl_ctx;
  497.    EGLDisplay egl_dpy;
  498.    char *dpyName = NULL;
  499.    GLboolean printInfo = GL_FALSE;
  500.    EGLint egl_major, egl_minor;
  501.    int i;
  502.    const char *s;
  503.  
  504.    for (i = 1; i < argc; i++) {
  505.       if (strcmp(argv[i], "-display") == 0) {
  506.          dpyName = argv[i+1];
  507.          i++;
  508.       }
  509.       else if (strcmp(argv[i], "-info") == 0) {
  510.          printInfo = GL_TRUE;
  511.       }
  512.       else {
  513.          usage();
  514.          return -1;
  515.       }
  516.    }
  517.  
  518.    x_dpy = XOpenDisplay(dpyName);
  519.    if (!x_dpy) {
  520.       printf("Error: couldn't open display %s\n",
  521.          dpyName ? dpyName : getenv("DISPLAY"));
  522.       return -1;
  523.    }
  524.  
  525.    egl_dpy = eglGetDisplay(x_dpy);
  526.    if (!egl_dpy) {
  527.       printf("Error: eglGetDisplay() failed\n");
  528.       return -1;
  529.    }
  530.  
  531.    if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) {
  532.       printf("Error: eglInitialize() failed\n");
  533.       return -1;
  534.    }
  535.  
  536.    s = eglQueryString(egl_dpy, EGL_VERSION);
  537.    printf("EGL_VERSION = %s\n", s);
  538.  
  539.    s = eglQueryString(egl_dpy, EGL_VENDOR);
  540.    printf("EGL_VENDOR = %s\n", s);
  541.  
  542.    s = eglQueryString(egl_dpy, EGL_EXTENSIONS);
  543.    printf("EGL_EXTENSIONS = %s\n", s);
  544.  
  545.    s = eglQueryString(egl_dpy, EGL_CLIENT_APIS);
  546.    printf("EGL_CLIENT_APIS = %s\n", s);
  547.  
  548.    make_x_window(x_dpy, egl_dpy,
  549.                  "OpenGL ES 2.x tri", 0, 0, winWidth, winHeight,
  550.                  &win, &egl_ctx, &egl_surf);
  551.  
  552.    XMapWindow(x_dpy, win);
  553.    if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) {
  554.       printf("Error: eglMakeCurrent() failed\n");
  555.       return -1;
  556.    }
  557.  
  558.    if (printInfo) {
  559.       printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
  560.       printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
  561.       printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
  562.       printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
  563.    }
  564.  
  565.    init();
  566.  
  567.    /* Set initial projection/viewing transformation.
  568.     * We can't be sure we'll get a ConfigureNotify event when the window
  569.     * first appears.
  570.     */
  571.    reshape(winWidth, winHeight);
  572.  
  573.    event_loop(x_dpy, win, egl_dpy, egl_surf);
  574.  
  575.    eglDestroyContext(egl_dpy, egl_ctx);
  576.    eglDestroySurface(egl_dpy, egl_surf);
  577.    eglTerminate(egl_dpy);
  578.  
  579.  
  580.    XDestroyWindow(x_dpy, win);
  581.    XCloseDisplay(x_dpy);
  582.  
  583.    return 0;
  584. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement