Advertisement
jdobmeier

helloPiGPU_GLESSL.c

Jun 6th, 2012
568
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.91 KB | None | 0 0
  1. //
  2. //
  3. // Author:    Joe Dobmeier
  4. // Credits:   I created this program by combining the SimpleTexture2D
  5. //        tutorial in the OpenGL ES 2.0 programming guide by
  6. //        Munshi, Ginsburg, and Shreiner with legacy GPGPU
  7. //        tutorial 0 from gpgpu.org by Harris and Weiblen.
  8. //
  9. //
  10. // This software is provided 'as-is', without any express or implied
  11. // warranty. In no event will the authors be held liable for any
  12. // damages arising from the use of this software.
  13. //
  14.  
  15. // helloPiGPU_GLESSL.c
  16. //---------------------------------------------------------------------------
  17. // GPGPU Lesson 0: "helloPiGPU_GLESSL" (a GLESSL version of "helloGPGPU" for the RPi)
  18. //---------------------------------------------------------------------------
  19. //
  20. // GPGPU CONCEPTS Introduced:
  21. //
  22. //      1.) Texture = Array
  23. //      2.) Fragment Program = Computational Kernel.
  24. //      3.) One-to-one Pixel to Texel Mapping:
  25. //          a) Data-Dimensioned Viewport, and
  26. //          b) Orthographic Projection.
  27. //      4.) Viewport-Sized Quad = Data Stream Generator.
  28. //      5.) Copy To Texture = feedback.
  29. //
  30. //      For details of each of these concepts, see the explanations in the
  31. //      inline "GPGPU CONCEPT" comments in the code below.
  32. //
  33. // APPLICATION Demonstrated: A simple post-process edge detection filter.
  34. //
  35. //---------------------------------------------------------------------------
  36. //
  37. //
  38. #include <stdlib.h>
  39. #include "esUtil.h"
  40.  
  41. typedef struct
  42. {
  43.    // Handle to a program object
  44.    GLuint programObject;
  45.  
  46.    // Attribute locations
  47.    GLint  positionLoc;
  48.    GLint  texCoordLoc;
  49.  
  50.    // Sampler location
  51.    GLint samplerLoc;
  52.  
  53.    // Texture handle
  54.    GLuint textureId;
  55.  
  56. } UserData;
  57.  
  58. ///
  59. // Create a simple 2x2 texture image with four different colors
  60. //
  61. // GPGPU CONCEPT 1: Texture = Array.
  62. // Textures are the GPGPU equivalent of arrays in standard
  63. // computation. Here we allocate a texture large enough to fit our
  64. // data (which is arbitrary in this example).
  65. GLuint CreateSimpleTexture2D( )
  66. {
  67.    // Texture object handle
  68.    GLuint textureId;
  69.  
  70.    // 2x2 Image, 3 bytes per pixel (R, G, B)
  71.    GLubyte pixels[4 * 3] =
  72.    {
  73.         255,   0,     0, // Red
  74.           0, 255,     0, // Green
  75.           0,   0,   255, // Blue
  76.         255, 255,   255  // White
  77.    };
  78.  
  79.    // Use tightly packed data
  80.    glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 );
  81.  
  82.    // Generate a texture object
  83.    glGenTextures ( 1, &textureId );
  84.  
  85.    // Bind the texture object
  86.    glBindTexture ( GL_TEXTURE_2D, textureId );
  87.  
  88.    // Load the texture
  89.    glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels );
  90.  
  91.    // Set the filtering mode
  92.    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  93.    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  94.  
  95.    return textureId;
  96.  
  97. }
  98.  
  99.  
  100. ///
  101. // Initialize the shader and program object
  102. //
  103. // GPGPU CONCEPT 2: Fragment Program = Computational Kernel.
  104. // A fragment program can be thought of as a small computational
  105. // kernel that is applied in parallel to many fragments
  106. // simultaneously.  Here we load a kernel that performs an edge
  107. // detection filter on an image.
  108. int Init ( ESContext *esContext )
  109. {
  110.    esContext->userData = malloc(sizeof(UserData));
  111.    UserData *userData = esContext->userData;
  112.    GLbyte vShaderStr[] =
  113.       "attribute vec4 a_position;   \n"
  114.       "attribute vec2 a_texCoord;   \n"
  115.       "varying vec2 v_texCoord;     \n"
  116.       "void main()                  \n"
  117.       "{                            \n"
  118.       "   gl_Position = a_position; \n"
  119.       "   v_texCoord = a_texCoord;  \n"
  120.       "}                            \n";
  121.  
  122.    GLbyte fShaderStr[] =
  123.       "precision mediump float;                            \n"
  124.       "varying vec2 v_texCoord;                            \n"
  125.       "uniform sampler2D s_texture;                        \n"
  126.       "void main()                                         \n"
  127.       "{                                                   \n"
  128.       "   const float offset = 1.0 / 256.0;\n"
  129.       "   vec4 c  = texture2D(s_texture, v_texCoord);\n"
  130.       "   vec4 bl = texture2D(s_texture, v_texCoord + vec2(-offset, -offset));\n"
  131.       "   vec4 l  = texture2D(s_texture, v_texCoord + vec2(-offset,     0.0));\n"
  132.       "   vec4 tl = texture2D(s_texture, v_texCoord + vec2(-offset,  offset));\n"
  133.       "   vec4 t  = texture2D(s_texture, v_texCoord + vec2(    0.0,  offset));\n"
  134.       "   vec4 ur = texture2D(s_texture, v_texCoord + vec2( offset,  offset));\n"
  135.       "   vec4 r  = texture2D(s_texture, v_texCoord + vec2( offset,     0.0));\n"
  136.       "   vec4 br = texture2D(s_texture, v_texCoord + vec2( offset,  offset));\n"
  137.       "   vec4 b  = texture2D(s_texture, v_texCoord + vec2(    0.0, -offset));\n"
  138.       "   gl_FragColor = 8.0 * (c + -0.125 * (bl + l + tl + t + ur + r + br + b));\n"
  139.       "}                                                   \n";
  140.  
  141.    // Load the shaders and get a linked program object
  142.    userData->programObject = esLoadProgram ( vShaderStr, fShaderStr );
  143.  
  144.    // Get the attribute locations
  145.    userData->positionLoc = glGetAttribLocation ( userData->programObject, "a_position" );
  146.    userData->texCoordLoc = glGetAttribLocation ( userData->programObject, "a_texCoord" );
  147.  
  148.    // Get the sampler location
  149.    userData->samplerLoc = glGetUniformLocation ( userData->programObject, "s_texture" );
  150.  
  151.    // Load the texture
  152.    userData->textureId = CreateSimpleTexture2D ();
  153.  
  154.    glClearColor ( 0.0f, 0.0f, 0.0f, 1.0f );
  155.    return GL_TRUE;
  156. }
  157.  
  158. ///
  159. // Draw a triangle using the shader pair created in Init()
  160. //
  161. void Draw ( ESContext *esContext )
  162. {
  163.    // Set the viewport
  164.    // GPGPU CONCEPT 3a: One-to-one Pixel to Texel Mapping: A Data-
  165.    //                   Dimensioned Viewport.
  166.    // We need a one-to-one mapping of pixels to texels in order to
  167.    // ensure every element of our texture is processed. By setting our
  168.    // viewport to the dimensions of our destination texture and drawing
  169.    // a screen-sized quad (see below), we ensure that every pixel of our
  170.    // texel is generated and processed in the fragment program.
  171.    glViewport ( 0, 0, esContext->width, esContext->height );
  172.  
  173.    // GPGPU CONCEPT 4: Viewport-Sized Quad = Data Stream Generator.
  174.    // In order to execute fragment programs, we need to generate pixels.
  175.    // Drawing a quad the size of our viewport (see above) generates a
  176.    // fragment for every pixel of our destination texture. Each fragment
  177.    // is processed identically by the fragment program. Notice that in
  178.    // the reshape() function, below, we have set the frustum to
  179.    // orthographic, and the frustum dimensions to [-1,1].  Thus, our
  180.    // viewport-sized quad vertices are at [-1,-1], [1,-1], [1,1], and
  181.    // [-1,1]: the corners of the viewport.
  182.    UserData *userData = esContext->userData;
  183.    GLfloat vVertices[] = { -1.0f,  1.0f, 0.0f,  // Position 0
  184.                             0.0f,  0.0f,        // TexCoord 0
  185.                            -1.0f, -1.0f, 0.0f,  // Position 1
  186.                             0.0f,  1.0f,        // TexCoord 1
  187.                             1.0f, -1.0f, 0.0f,  // Position 2
  188.                             1.0f,  1.0f,        // TexCoord 2
  189.                             1.0f,  1.0f, 0.0f,  // Position 3
  190.                             1.0f,  0.0f         // TexCoord 3
  191.                          };
  192.    GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
  193.  
  194.    // Clear the color buffer
  195.    glClear ( GL_COLOR_BUFFER_BIT );
  196.  
  197.    // Use the program object
  198.    glUseProgram ( userData->programObject );
  199.  
  200.    // Load the vertex position
  201.    glVertexAttribPointer ( userData->positionLoc, 3, GL_FLOAT,
  202.                            GL_FALSE, 5 * sizeof(GLfloat), vVertices );
  203.    // Load the texture coordinate
  204.    glVertexAttribPointer ( userData->texCoordLoc, 2, GL_FLOAT,
  205.                            GL_FALSE, 5 * sizeof(GLfloat), &vVertices[3] );
  206.  
  207.    glEnableVertexAttribArray ( userData->positionLoc );
  208.    glEnableVertexAttribArray ( userData->texCoordLoc );
  209.  
  210.    // Bind the texture
  211.    glActiveTexture ( GL_TEXTURE0 );
  212.    glBindTexture ( GL_TEXTURE_2D, userData->textureId );
  213.  
  214.    // Set the sampler texture unit to 0
  215.    glUniform1i ( userData->samplerLoc, 0 );
  216.  
  217.    glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices );
  218.  
  219. }
  220.  
  221. ///
  222. // Cleanup
  223. //
  224. void ShutDown ( ESContext *esContext )
  225. {
  226.    UserData *userData = esContext->userData;
  227.  
  228.    // Delete texture object
  229.    glDeleteTextures ( 1, &userData->textureId );
  230.  
  231.    // Delete program object
  232.    glDeleteProgram ( userData->programObject );
  233.  
  234.    free(esContext->userData);
  235. }
  236.  
  237. int main ( int argc, char *argv[] )
  238. {
  239.    ESContext esContext;
  240.    UserData  userData;
  241.  
  242.    esInitContext ( &esContext );
  243.    esContext.userData = &userData;
  244.  
  245.    esCreateWindow ( &esContext, "helloPiGPU_GLESSL", 256, 256, ES_WINDOW_RGB );
  246.  
  247.    if ( !Init ( &esContext ) )
  248.       return 0;
  249.  
  250.    esRegisterDrawFunc ( &esContext, Draw );
  251.  
  252.    esMainLoop ( &esContext );
  253.  
  254.    ShutDown ( &esContext );
  255. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement