Advertisement
Fonix

Effects.mm

Sep 4th, 2012
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //
  2. //  Effects.m
  3. //  DiceRoller
  4. //
  5. //  Created by Jacques Questiaux on 2012/06/18.
  6. //  Copyright (c) 2012 j.questiaux@gmail.com. All rights reserved.
  7. //
  8.  
  9. #import "Effects.h"
  10.  
  11. @interface Effects (){
  12.  
  13. }
  14.  
  15. @end
  16.  
  17.  
  18. @implementation Effects
  19.  
  20. - (id) init {
  21.    
  22.     if([super init]){
  23.        
  24.         cameraLookAt = GLKVector3Make(0, 0, 0);
  25.         cameraUp = GLKVector3Make(0, 1, 0);
  26.        
  27.         lightPosition = GLKVector3Make(1, 1, 3);
  28.         lightDiffuseColour = GLKVector4Make(0.7, 0.7, 0.7, 1);
  29.         lightSpecularColour = GLKVector4Make(2, 2, 2, 1);
  30.         lightAmbientColour = GLKVector4Make(0.85, 0.85, 0.85, 1);
  31.         numberColour = GLKVector4Make(0, 0, 0, 1);
  32.         faceColour = GLKVector4Make(1, 1, 1, 1);
  33.        
  34.         outlineColour = GLKVector4Make(1, 0, 0, 1);
  35.        
  36.         [self setupTexture];
  37.         [self loadShaders];
  38.         [self loadToonShaders];
  39.        
  40.         return self;
  41.     }
  42.    
  43.     return nil;
  44. }
  45.  
  46. - (void) prepareToDraw {
  47.    
  48.     glUseProgram(TexAndLighting);
  49.    
  50.     camModelViewMatrix = GLKMatrix4Multiply(cameraMatrix, modelViewMatrix);
  51.    
  52.     modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, camModelViewMatrix);
  53.    
  54.     GLKMatrix3 normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
  55.    
  56.     glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, modelViewProjectionMatrix.m);
  57.     glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, normalMatrix.m);
  58.    
  59.    
  60.     float* lp = [self vec3ToFloat:lightPosition];
  61.     glUniform3fv(uniforms[UNIFORM_VEC3_lightPosition], 1, lp);
  62.     delete lp;
  63.    
  64.     float* ldc = [self vec4ToFloat:lightDiffuseColour];
  65.     glUniform4fv(uniforms[UNIFORM_VEC4_lightDiffuseColour], 1, ldc);
  66.     delete ldc;
  67.    
  68.     float* lsc = [self vec4ToFloat:lightSpecularColour];
  69.     glUniform4fv(uniforms[UNIFORM_VEC4_lightSpecularColour], 1, lsc);
  70.     delete lsc;
  71.    
  72.     GLKVector3 lightHalfVec = GLKVector3Normalize(GLKVector3Add(cameraPosition, lightPosition));
  73.     float* lhv = [self vec3ToFloat:lightHalfVec];
  74.     glUniform3fv(uniforms[UNIFORM_VEC3_lightHalfVector], 1, lhv);
  75.     delete lhv;
  76.    
  77.     float* nc = [self vec4ToFloat:numberColour];
  78.     glUniform4fv(uniforms[UNIFORM_VEC4_NumberColour], 1, nc);
  79.     delete nc;
  80.    
  81.     float* fc = [self vec4ToFloat:faceColour];
  82.     glUniform4fv(uniforms[UNIFORM_VEC4_FaceColour], 1, fc);
  83.     delete fc;
  84.  
  85.    
  86.     glActiveTexture(GL_TEXTURE0);
  87.     glBindTexture(GL_TEXTURE_2D, texture);
  88.     glUniform1i(uniforms[UNIFORM_Texture], 0);
  89. }
  90.  
  91. - (void) drawOutline {
  92.    
  93.     glUseProgram(Toon);
  94.    
  95.     camModelViewMatrix = GLKMatrix4Multiply(cameraMatrix, modelViewMatrix);
  96.    
  97.     modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, camModelViewMatrix);;
  98.    
  99.     glUniformMatrix4fv(toon_mvp, 1, 0, modelViewProjectionMatrix.m);
  100.    
  101.     float* oc = [self vec4ToFloat:outlineColour];
  102.     glUniform4fv(toon_outline, 1, oc);
  103.     delete oc;
  104. }
  105.  
  106. - (void) setCameraPosition:(GLKVector3)cp {
  107.    
  108.     cameraPosition = cp;
  109.    
  110.     cameraMatrix = GLKMatrix4MakeLookAt(cameraPosition.x, cameraPosition.y, cameraPosition.z, cameraLookAt.x, cameraLookAt.y, cameraLookAt.z, cameraUp.x, cameraUp.y, cameraUp.z);
  111.    
  112.     //cameraMatrix = GLKMatrix4MakeTranslation(cameraPosition.x, cameraPosition.y, cameraPosition.z);
  113. }
  114.  
  115. - (GLKVector3) cameraPosition {
  116.    
  117.     return cameraPosition;
  118. }
  119.  
  120. - (void) setCameraLookAt:(GLKVector3)cla {
  121.    
  122.     cameraLookAt = cla;
  123.    
  124.     cameraMatrix = GLKMatrix4MakeLookAt(cameraPosition.x, cameraPosition.y, cameraPosition.z, cameraLookAt.x, cameraLookAt.y, cameraLookAt.z, cameraUp.x, cameraUp.y, cameraUp.z);
  125. }
  126.  
  127. - (GLKVector3) cameraLookAt {
  128.    
  129.     return cameraLookAt;
  130. }
  131.  
  132. - (void) setupTexture {    
  133.    
  134.     CGImageRef spriteImage = [UIImage imageNamed:@"texture.png"].CGImage;
  135.  
  136.     if (!spriteImage) {
  137.         NSLog(@"Failed to load image");
  138.         //exit(1);
  139.     }
  140.    
  141.     size_t width = CGImageGetWidth(spriteImage);
  142.     size_t height = CGImageGetHeight(spriteImage);
  143.    
  144.     GLubyte * spriteData = (GLubyte *) calloc(width*height*4, sizeof(GLubyte));
  145.     CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width*4, CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast);    
  146.     CGContextDrawImage(spriteContext, CGRectMake(0, 0, width, height), spriteImage);
  147.     CGContextRelease(spriteContext);
  148.    
  149.     //texture gets read in upside down, need to manually flip it
  150.     GLubyte * spriteData2 = (GLubyte *) calloc(width*height*4, sizeof(GLubyte));
  151.    
  152.     for(int i = 0; i < width*4; i++){
  153.         for(int j = 0; j < height; j++){
  154.            
  155.             spriteData2[j*width*4+i] = spriteData[(height-1-j)*width*4+i];
  156.            
  157.         }
  158.     }
  159.  
  160.     glGenTextures(1, &texture);
  161.     glBindTexture(GL_TEXTURE_2D, texture);
  162.    
  163.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  164.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); //IMPORTANT FOR NON POWER OF 2 TEXTURES
  165.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  166.    
  167.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData2);
  168.    
  169.     free(spriteData);    
  170.     free(spriteData2);
  171.    
  172.    
  173.     //texture = texName;    
  174. }
  175.  
  176. - (BOOL)loadShaders
  177. {
  178.    
  179.     GLuint vertShader, fragShader;
  180.     NSString *vertShaderPathname, *fragShaderPathname;
  181.    
  182.     // Create shader program.
  183.     TexAndLighting = glCreateProgram();
  184.    
  185.     // Create and compile vertex shader.
  186.     vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
  187.    
  188.     if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
  189.         NSLog(@"Failed to compile vertex shader");
  190.         return NO;
  191.     }
  192.    
  193.     // Create and compile fragment shader.
  194.     fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
  195.     if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
  196.         NSLog(@"Failed to compile fragment shader");
  197.         return NO;
  198.     }
  199.    
  200.     // Attach vertex shader to program.
  201.     glAttachShader(TexAndLighting, vertShader);
  202.    
  203.     // Attach fragment shader to program.
  204.     glAttachShader(TexAndLighting, fragShader);
  205.    
  206.     // Bind attribute locations.
  207.     // This needs to be done prior to linking.
  208.     //glBindAttribLocation(_program, ATTRIB_VERTEX, "position");
  209.     //glBindAttribLocation(_program, ATTRIB_NORMAL, "normal");
  210.    
  211.    
  212.     // Link program.
  213.     if (![self linkProgram:TexAndLighting]) {
  214.         NSLog(@"Failed to link program: %d", TexAndLighting);
  215.        
  216.         if (vertShader) {
  217.             glDeleteShader(vertShader);
  218.             vertShader = 0;
  219.         }
  220.         if (fragShader) {
  221.             glDeleteShader(fragShader);
  222.             fragShader = 0;
  223.         }
  224.         if (TexAndLighting) {
  225.             glDeleteProgram(TexAndLighting);
  226.             TexAndLighting = 0;
  227.         }
  228.        
  229.         return NO;
  230.     }
  231.    
  232.     // Get uniform locations.
  233.     uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(TexAndLighting, "modelViewProjectionMatrix");
  234.     uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(TexAndLighting, "normalMatrix");
  235.     uniforms[UNIFORM_VEC3_lightPosition] = glGetUniformLocation(TexAndLighting, "lightPosition");
  236.     uniforms[UNIFORM_VEC4_lightDiffuseColour] = glGetUniformLocation(TexAndLighting, "lightDiffuseColour");
  237.     uniforms[UNIFORM_VEC4_lightSpecularColour] = glGetUniformLocation(TexAndLighting, "lightSpecularColour");
  238.     uniforms[UNIFORM_VEC4_lightAmbientColour] = glGetUniformLocation(TexAndLighting, "lightAmbientColour");
  239.     uniforms[UNIFORM_VEC3_lightHalfVector] = glGetUniformLocation(TexAndLighting, "lightHalfVector");
  240.     uniforms[UNIFORM_Texture] = glGetUniformLocation(TexAndLighting, "Texture");
  241.     uniforms[UNIFORM_VEC4_NumberColour] = glGetUniformLocation(TexAndLighting, "numberColour");
  242.     uniforms[UNIFORM_VEC4_FaceColour] = glGetUniformLocation(TexAndLighting, "faceColour");
  243.    
  244.     texCoord = glGetAttribLocation(TexAndLighting, "TexCoordIn");
  245.     vertCoord = glGetAttribLocation(TexAndLighting, "position");
  246.     normal = glGetAttribLocation(TexAndLighting, "normal");
  247.     //glEnableVertexAttribArray(texCoord);
  248.    
  249.    
  250.     // Release vertex and fragment shaders.
  251.     if (vertShader) {
  252.         glDetachShader(TexAndLighting, vertShader);
  253.         glDeleteShader(vertShader);
  254.     }
  255.     if (fragShader) {
  256.         glDetachShader(TexAndLighting, fragShader);
  257.         glDeleteShader(fragShader);
  258.     }
  259.    
  260.     return YES;
  261. }
  262.  
  263. - (BOOL)loadToonShaders
  264. {
  265.    
  266.     GLuint vertShader, fragShader;
  267.     NSString *vertShaderPathname, *fragShaderPathname;
  268.    
  269.     // Create shader program.
  270.     Toon = glCreateProgram();
  271.    
  272.     // Create and compile vertex shader.
  273.     vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Toon" ofType:@"vsh"];
  274.    
  275.     if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
  276.         NSLog(@"Failed to compile vertex shader");
  277.         return NO;
  278.     }
  279.    
  280.     // Create and compile fragment shader.
  281.     fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Toon" ofType:@"fsh"];
  282.     if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
  283.         NSLog(@"Failed to compile fragment shader");
  284.         return NO;
  285.     }
  286.    
  287.     // Attach vertex shader to program.
  288.     glAttachShader(Toon, vertShader);
  289.    
  290.     // Attach fragment shader to program.
  291.     glAttachShader(Toon, fragShader);
  292.    
  293.     // Bind attribute locations.
  294.     // This needs to be done prior to linking.
  295.     //glBindAttribLocation(Toon, vertCoord, "position");
  296.     //glBindAttribLocation(_program, effect->normal, "normal");
  297.    
  298.    
  299.     // Link program.
  300.     if (![self linkProgram:Toon]) {
  301.         NSLog(@"Failed to link program: %d", Toon);
  302.        
  303.         if (vertShader) {
  304.             glDeleteShader(vertShader);
  305.             vertShader = 0;
  306.         }
  307.         if (fragShader) {
  308.             glDeleteShader(fragShader);
  309.             fragShader = 0;
  310.         }
  311.         if (Toon) {
  312.             glDeleteProgram(Toon);
  313.             Toon = 0;
  314.         }
  315.        
  316.         return NO;
  317.     }
  318.    
  319.     // Get uniform locations.
  320.     toon_mvp = glGetUniformLocation(Toon, "modelViewProjectionMatrix");
  321.     toon_outline = glGetUniformLocation(Toon, "outlineColour");
  322.    
  323.     toon_vertCoord = glGetAttribLocation(Toon, "position");
  324.    
  325.    
  326.     // Release vertex and fragment shaders.
  327.     if (vertShader) {
  328.         glDetachShader(Toon, vertShader);
  329.         glDeleteShader(vertShader);
  330.     }
  331.     if (fragShader) {
  332.         glDetachShader(Toon, fragShader);
  333.         glDeleteShader(fragShader);
  334.     }
  335.    
  336.     return YES;
  337. }
  338.  
  339. - (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
  340. {
  341.     GLint status;
  342.     const GLchar *source;
  343.    
  344.     source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
  345.     if (!source) {
  346.         NSLog(@"Failed to load vertex shader");
  347.         return NO;
  348.     }
  349.    
  350.     *shader = glCreateShader(type);
  351.     glShaderSource(*shader, 1, &source, NULL);
  352.     glCompileShader(*shader);
  353.    
  354. #if defined(DEBUG)
  355.     GLint logLength;
  356.     glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
  357.     if (logLength > 0) {
  358.         GLchar *log = (GLchar *)malloc(logLength);
  359.         glGetShaderInfoLog(*shader, logLength, &logLength, log);
  360.         NSLog(@"Shader compile log:\n%s", log);
  361.         free(log);
  362.     }
  363. #endif
  364.    
  365.     glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
  366.     if (status == 0) {
  367.         glDeleteShader(*shader);
  368.         return NO;
  369.     }
  370.    
  371.     return YES;
  372. }
  373.  
  374. - (BOOL)linkProgram:(GLuint)prog
  375. {
  376.     GLint status;
  377.     glLinkProgram(prog);
  378.    
  379. #if defined(DEBUG)
  380.     GLint logLength;
  381.     glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
  382.     if (logLength > 0) {
  383.         GLchar *log = (GLchar *)malloc(logLength);
  384.         glGetProgramInfoLog(prog, logLength, &logLength, log);
  385.         NSLog(@"Program link log:\n%s", log);
  386.         free(log);
  387.     }
  388. #endif
  389.    
  390.     glGetProgramiv(prog, GL_LINK_STATUS, &status);
  391.     if (status == 0) {
  392.         return NO;
  393.     }
  394.    
  395.     return YES;
  396. }
  397.  
  398. - (BOOL)validateProgram:(GLuint)prog
  399. {
  400.     GLint logLength, status;
  401.    
  402.     glValidateProgram(prog);
  403.     glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
  404.     if (logLength > 0) {
  405.         GLchar *log = (GLchar *)malloc(logLength);
  406.         glGetProgramInfoLog(prog, logLength, &logLength, log);
  407.         NSLog(@"Program validate log:\n%s", log);
  408.         free(log);
  409.     }
  410.    
  411.     glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
  412.     if (status == 0) {
  413.         return NO;
  414.     }
  415.    
  416.     return YES;
  417. }
  418.  
  419. - (float*) vec3ToFloat: (GLKVector3) v {
  420.     float * f = new float[3];
  421.     f[0] = v.x;
  422.     f[1] = v.y;
  423.     f[2] = v.z;
  424.    
  425.     return f;
  426. }
  427.  
  428. - (float*) vec4ToFloat: (GLKVector4) v {
  429.     float * f = new float[4];
  430.     f[0] = v.x;
  431.     f[1] = v.y;
  432.     f[2] = v.z;
  433.     f[3] = v.w;
  434.    
  435.     return f;
  436. }
  437.  
  438. @end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement