Advertisement
Guest User

Untitled

a guest
Jul 27th, 2017
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.   create an Apple default GL project  from the template
  3.  replace shaders,  and ES2Renderer.m with the following:
  4. */
  5.  
  6. //
  7. //  Shader.fsh
  8. //  helloGL
  9. //
  10. //  Created by Pi on 17/02/2011.
  11. //  Copyright 2011 __MyCompanyName__. All rights reserved.
  12. //
  13.  
  14. precision mediump float;
  15.  
  16. uniform sampler2D S0;              
  17.  
  18. varying vec2 V0;               
  19. varying vec4 V1;                   
  20.  
  21. void                               
  22. main( void )                       
  23. {                                  
  24.     gl_FragColor = vec4( V1 *      
  25.                         texture2D( S0, V0 ) )
  26. }
  27.  
  28.  
  29. // ---------------------------
  30.  
  31.  
  32. //
  33. //  Shader.vsh
  34. //  helloGL
  35. //
  36. //  Created by Pi on 17/02/2011.
  37. //  Copyright 2011 __MyCompanyName__. All rights reserved.
  38. //
  39.  
  40. attribute vec4 A0;      // A0 = gl_Vertex,         
  41. attribute vec2 A1;      // A1 = glMultiTexCoord0.st    
  42. attribute vec4 A2;      // A2 = gl_Color           
  43.  
  44. varying vec2 V0;                   
  45. varying vec4 V1;                   
  46.  
  47. uniform mat4 M0;                   
  48.  
  49. void main( void )                  
  50. {                                  
  51.     V0 = vec2( A1 );               
  52.     V1 = vec4( A2 );               
  53.    
  54.     gl_Position = vec4( M0 * A0 )
  55. }
  56.  
  57.  
  58. // ---------------------------
  59.  
  60. //
  61. //  ES2Renderer.m
  62. //  helloGL
  63. //
  64. //  Created by Pi on 17/02/2011.
  65. //  Copyright 2011 __MyCompanyName__. All rights reserved.
  66. //
  67.  
  68.  
  69. #import "ES2Renderer.h"
  70.  
  71. #define STRIDE              (     sizeof( GLfloat ) * ( 2 + 2 + 4 )     )
  72. #define OFFSET( P )         ( ( const GLvoid * ) ( sizeof( GLfloat ) * ( P ) ) )
  73.  
  74. #define eglGetError         while (glGetError() != GL_NO_ERROR) printf("Error!\n")
  75. // #import "error.h"
  76.  
  77. // = = =
  78.  
  79. // uniform index
  80. enum {
  81.     UNIFORM_TRANSLATE,
  82.     NUM_UNIFORMS
  83. };
  84. GLint uniforms[NUM_UNIFORMS];
  85.  
  86. // attribute index
  87. enum {
  88.     ATTRIB_VERTEX_XY,
  89.     ATTRIB_TEXCOORD_ST,
  90.     ATTRIB_COLOR_RGBA,
  91.     NUM_ATTRIBUTES
  92. };
  93.  
  94. // = = =
  95.  
  96. @interface ES2Renderer (PrivateMethods)
  97. - (BOOL)loadShaders;
  98. - (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file;
  99. - (BOOL)linkProgram:(GLuint)prog;
  100. - (BOOL)validateProgram:(GLuint)prog;
  101. @end
  102.  
  103. // = = =
  104.  
  105. @implementation ES2Renderer
  106.  
  107. // - - -
  108.  
  109. // Create an OpenGL ES 2.0 context
  110. - (id)init
  111. {
  112.     self = [super init];
  113.     if (! self)
  114.         return nil;
  115.        
  116.     context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2];
  117.        
  118.     // loadShaders sets up the programmable pipeline, ie
  119.     // - Generates a program object + vertex & fragment shader
  120.     // - compiles & links program  ( i.e.  )
  121.     {
  122.         if (!context
  123.             || ![EAGLContext setCurrentContext:context]
  124.             || ![self loadShaders])
  125.         {
  126.             [self release];
  127.             return nil;
  128.         }
  129.     }
  130.    
  131.     // Setup framebuffers
  132.     {  
  133.         // Create default framebuffer object. The backing will be
  134.         // allocated for the current layer in -resizeFromLayer
  135.         glGenFramebuffers(1, & defaultFramebuffer);
  136.         glGenRenderbuffers(1, & colorRenderbuffer);
  137.        
  138.         // attach renderBuffer to our frameBuffer
  139.         // NOTE: we could alternatively attach a texture to our FBO with
  140.         //       glFramebufferTexture2D
  141.         glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
  142.         glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
  143.         glFramebufferRenderbuffer(GL_FRAMEBUFFER,
  144.                                   GL_COLOR_ATTACHMENT0,
  145.                                   GL_RENDERBUFFER,
  146.                                   colorRenderbuffer);
  147.     }
  148.    
  149.     {
  150.         // Ask GL to give us a texture-ID for us to use
  151.         glGenTextures( 1, & greyscaleTexture );
  152.     }  
  153.        
  154.     return self;
  155. }
  156.  
  157. // - - -
  158.  
  159. - (void) render
  160. {      
  161.     // first pass works no errors!
  162.     static int abc = 0;
  163.     if (abc)
  164.         return;
  165.     abc++;
  166.    
  167.    
  168.     // CREATE A GREYSCALE TEXTURE
  169.     {
  170.         GLuint W = backingWidth, H = backingHeight;
  171.        
  172.         printf("Rendering @ (%d, %d)\n", W, H);
  173.        
  174.         // Create a pretty greyscale pixel pattern
  175.         GLubyte *P = calloc( 1, ( W * H * 4 * sizeof( GLubyte ) ) );
  176.        
  177.         for ( GLuint i = 0; ( i < H ); ++i )
  178.         {
  179.             for ( GLuint j = 0; ( j < W ); ++j )
  180.             {
  181.                 P[( ( i * W + j ) * 4  +  0 )] =
  182.                 P[( ( i * W + j ) * 4  +  1 )] =
  183.                 P[( ( i * W + j ) * 4  +  2 )] =
  184.                 P[( ( i * W + j ) * 4  +  3 )] = ( i ^ j );
  185.             }
  186.         }      
  187.        
  188.         // make it the ACTIVE texture, ie functions like glTexImage2D will
  189.         // automatically know to use THIS texture
  190.         glBindTexture( GL_TEXTURE_2D, greyscaleTexture );
  191.        
  192.         // set some params on the ACTIVE texture
  193.         glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  194.         glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  195.        
  196.         // WRITE/COPY from P into active texture  
  197.         glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, W, H, 0, GL_RGBA, GL_UNSIGNED_BYTE, P );
  198.        
  199.         free( P );
  200.        
  201.         eglGetError;
  202.     }
  203.    
  204.     // - - -    
  205.    
  206.     // (c) setup your vertex state (i.e. vertex array,
  207.     //     vertex buffer + index buffer if you need that)
  208.     {
  209.         // Vertex Array: Assumes interleaved  { ..., X, Y, S, T, R, G, B, A, ... }
  210.         static const GLfloat  VA[ ] =
  211.         {
  212.             // X      Y      S      T        R      G      B      A
  213.             -1.0f, -1.0f,  0.0f,  1.0f,    1.0f,  0.0f,  0.0f,  1.0f,  // Bottom Left: Red
  214.             1.0f, -1.0f,  1.0f,  1.0f,    0.0f,  1.0f,  0.0f,  1.0f,
  215.             -1.0f,  1.0f,  0.0f,  0.0f,    1.0f,  0.0f,  0.0f,  1.0f,  
  216.             1.0f,  1.0f,  1.0f,  0.0f,    0.0f,  1.0f,  0.0f,  1.0f,
  217.         };
  218.         GLuint vertexArrayBufferID;
  219.         glBindBuffer( GL_ARRAY_BUFFER, vertexArrayBufferID );
  220.         glBufferData( GL_ARRAY_BUFFER, sizeof( VA ), VA, GL_STATIC_DRAW );                      
  221.        
  222.         glVertexAttribPointer( ATTRIB_VERTEX_XY, 2, GL_FLOAT, GL_FALSE, STRIDE, OFFSET( 0 ) ); // X Y
  223.         glVertexAttribPointer( ATTRIB_TEXCOORD_ST, 2, GL_FLOAT, GL_FALSE, STRIDE, OFFSET( 2 ) ); // S T    
  224.         glVertexAttribPointer( ATTRIB_COLOR_RGBA, 4, GL_FLOAT, GL_FALSE, STRIDE, OFFSET( 4 ) ); // R G B A
  225.        
  226.         glEnableVertexAttribArray( ATTRIB_VERTEX_XY );
  227.         glEnableVertexAttribArray( ATTRIB_TEXCOORD_ST );
  228.         glEnableVertexAttribArray( ATTRIB_COLOR_RGBA );        
  229.                
  230.         // - - -
  231.        
  232.         // Index Array: this represents a strip of TWO triangles: {V[0], V[1], V[2]} and {V[1], V[2], V[3]}
  233.         const GLushort IA[ ] =
  234.         {
  235.             0, 1, 2, 3,
  236.         };
  237.         GLuint vertexIndexArrayBufID;
  238.         glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vertexIndexArrayBufID );
  239.         glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( IA ), IA, GL_STATIC_DRAW );                                                              
  240.     }
  241.    
  242.    
  243.    
  244.    
  245.     // Update uniform value
  246.     // glUniform1f(uniforms[UNIFORM_TRANSLATE], (GLfloat)transY);
  247.     // transY += 0.075f;   
  248.     //
  249.    
  250.     static const GLfloat M[ ] = // Assumes ( MV * P ) matrix.
  251.     {
  252.         1.0f,  0.0f,  0.0f,  0.0f,  
  253.         0.0f,  1.0f,  0.0f,  0.0f,
  254.         0.0f,  0.0f,  1.0f,  0.0f,  
  255.         0.0f,  0.0f,  0.0f,  1.0f
  256.     };
  257.    
  258.     // Setup uniform (matrix, sampler) state.
  259.     glUniformMatrix4fv( glGetUniformLocation( uniforms[UNIFORM_TRANSLATE], "M0" ), 1, GL_FALSE, M );                
  260.    
  261.    
  262.    
  263.     // - - - APPLES TEMPLATE CODE
  264.    
  265.     // This application only creates a single context which is already set current at this point.
  266.     // This call is redundant, but needed if dealing with multiple contexts.
  267.     [EAGLContext setCurrentContext:context];
  268.    
  269.     glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
  270.     glViewport(0, 0, backingWidth, backingHeight);
  271.    
  272.     // - -
  273.    
  274.     // 1) clear the COLOR buffer <-- WORKS!!! Screen goes red!
  275.     glClearColor(0.5f, 0.0f, 0.0f, 1.0f);
  276.     glClear(GL_COLOR_BUFFER_BIT);
  277.    
  278.     // - -
  279.    
  280.     glBindTexture(GL_TEXTURE_2D, greyscaleTexture);
  281.    
  282.     // make this program the ACTIVE program
  283.     glUseProgram(program);
  284.    
  285.     // Validate program before drawing. This is a good check, but only really necessary in a debug build.
  286.     // DEBUG macro must be defined in your debug configurations if that's not already the case.
  287. #if defined(DEBUG)
  288.     if (![self validateProgram:program])
  289.     {
  290.         NSLog(@"Failed to validate program: %d", program);
  291.         return;
  292.     }
  293. #endif 
  294.    
  295.     glDrawElements( GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, NULL );    
  296.     if (0)
  297.         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  298.    
  299.     // - -
  300.    
  301.     // This application only creates a single color renderbuffer
  302.     //    which is already bound at this point.
  303.     // This call is redundant, but needed if dealing with multiple renderbuffers.
  304.     glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
  305.    
  306.     [context presentRenderbuffer: GL_RENDERBUFFER];
  307. }
  308.  
  309. // - - -
  310.  
  311. - (BOOL)compileShader:(GLuint *)shader
  312.                  type:(GLenum)type
  313.                  file:(NSString *)file
  314. {
  315.     GLint status;
  316.     const GLchar *source;
  317.    
  318.     source = (GLchar *)[[NSString stringWithContentsOfFile:file
  319.                                                   encoding:NSUTF8StringEncoding
  320.                                                      error:nil]
  321.                         UTF8String];
  322.     if (!source)
  323.     {
  324.         NSLog(@"Failed to load vertex shader");
  325.         return FALSE;
  326.     }
  327.    
  328.     *shader = glCreateShader(type);
  329.     glShaderSource(*shader, 1, &source, NULL);
  330.     glCompileShader(*shader);
  331.    
  332. #if defined(DEBUG)
  333.     GLint logLength;
  334.     glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
  335.     if (logLength > 0)
  336.     {
  337.         GLchar *log = (GLchar *)malloc(logLength);
  338.         glGetShaderInfoLog(*shader, logLength, &logLength, log);
  339.         NSLog(@"Shader compile log:\n%s", log);
  340.         free(log);
  341.     }
  342. #endif
  343.    
  344.     glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
  345.     if (status == 0)
  346.     {
  347.         glDeleteShader(*shader);
  348.         return FALSE;
  349.     }
  350.    
  351.     return TRUE;
  352. }
  353.  
  354. // - - -
  355.  
  356. - (BOOL)linkProgram:(GLuint)prog
  357. {
  358.     GLint status;
  359.    
  360.     glLinkProgram(prog);
  361.    
  362. #if defined(DEBUG)
  363.     GLint logLength;
  364.     glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
  365.     if (logLength > 0)
  366.     {
  367.         GLchar *log = (GLchar *)malloc(logLength);
  368.         glGetProgramInfoLog(prog, logLength, &logLength, log);
  369.         NSLog(@"Program link log:\n%s", log);
  370.         free(log);
  371.     }
  372. #endif
  373.    
  374.     glGetProgramiv(prog, GL_LINK_STATUS, &status);
  375.     if (status == 0)
  376.         return FALSE;
  377.    
  378.     return TRUE;
  379. }
  380.  
  381. // - - -
  382.  
  383. - (BOOL)validateProgram:(GLuint)prog
  384. {
  385.     GLint logLength, status;
  386.    
  387.     glValidateProgram(prog);
  388.     glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
  389.     if (logLength > 0)
  390.     {
  391.         GLchar *log = (GLchar *)malloc(logLength);
  392.         glGetProgramInfoLog(prog, logLength, &logLength, log);
  393.         NSLog(@"Program validate log:\n%s", log);
  394.         free(log);
  395.     }
  396.    
  397.     glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
  398.     if (status == 0)
  399.         return FALSE;
  400.    
  401.     return TRUE;
  402. }
  403.  
  404. // - - -
  405.  
  406. - (BOOL)loadShaders
  407. {
  408.     GLuint vertShader, fragShader;
  409.     NSString *vertShaderPathname, *fragShaderPathname;
  410.    
  411.     // Create shader program
  412.     program = glCreateProgram();
  413.    
  414.     // Create and compile vertex shader
  415.     vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
  416.     if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname])
  417.     {
  418.         NSLog(@"Failed to compile vertex shader");
  419.         return FALSE;
  420.     }
  421.    
  422.     // Create and compile fragment shader
  423.     fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
  424.     if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname])
  425.     {
  426.         NSLog(@"Failed to compile fragment shader");
  427.         return FALSE;
  428.     }
  429.    
  430.     // Attach vertex shader to program
  431.     glAttachShader(program, vertShader);
  432.    
  433.     // Attach fragment shader to program
  434.     glAttachShader(program, fragShader);
  435.    
  436.     // Bind attribute locations
  437.     // this needs to be done prior to linking
  438.     glBindAttribLocation(program, ATTRIB_VERTEX_XY, "A0");
  439.     glBindAttribLocation(program, ATTRIB_TEXCOORD_ST, "A1");
  440.     glBindAttribLocation(program, ATTRIB_COLOR_RGBA, "A2");
  441.    
  442.     // Link program
  443.     if (![self linkProgram:program])
  444.     {
  445.         NSLog(@"Failed to link program: %d", program);
  446.        
  447.         if (vertShader)
  448.         {
  449.             glDeleteShader(vertShader);
  450.             vertShader = 0;
  451.         }
  452.         if (fragShader)
  453.         {
  454.             glDeleteShader(fragShader);
  455.             fragShader = 0;
  456.         }
  457.         if (program)
  458.         {
  459.             glDeleteProgram(program);
  460.             program = 0;
  461.         }
  462.        
  463.         return FALSE;
  464.     }
  465.    
  466.     // Get uniform locations
  467.     uniforms[UNIFORM_TRANSLATE] = glGetUniformLocation(program, "M0");
  468.    
  469.     // Release vertex and fragment shaders
  470.     if (vertShader)
  471.         glDeleteShader(vertShader);
  472.     if (fragShader)
  473.         glDeleteShader(fragShader);
  474.    
  475.     return TRUE;
  476. }
  477.  
  478. // - - -
  479.  
  480. - (BOOL) resizeFromLayer: (CAEAGLLayer *) layer
  481. {
  482.     // Allocate color buffer backing based on the current layer size
  483.     glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
  484.    
  485.     [context renderbufferStorage: GL_RENDERBUFFER
  486.                     fromDrawable: layer];
  487.    
  488.     glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, & backingWidth);
  489.     glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, & backingHeight);
  490.    
  491.     if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
  492.     {
  493.         NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
  494.         return NO;
  495.     }
  496.    
  497.     return YES;
  498. }
  499.  
  500. // - - -
  501.  
  502. - (void)dealloc
  503. {
  504.     // Tear down GL
  505.     if (defaultFramebuffer)
  506.     {
  507.         glDeleteFramebuffers(1, & defaultFramebuffer);
  508.         defaultFramebuffer = 0;
  509.     }
  510.    
  511.     if (colorRenderbuffer)
  512.     {
  513.         glDeleteRenderbuffers(1, & colorRenderbuffer);
  514.         colorRenderbuffer = 0;
  515.     }
  516.    
  517.     if (program)
  518.     {
  519.         glDeleteProgram(program);
  520.         program = 0;
  521.     }
  522.    
  523.     // Tear down context
  524.     if ([EAGLContext currentContext] == context)
  525.         [EAGLContext setCurrentContext:nil];
  526.    
  527.     [context release];
  528.     context = nil;
  529.    
  530.     [super dealloc];
  531. }
  532.  
  533. @end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement