2013-05-21 3 views
1

Я создал программу, которая позволяет мне отображать 3D objects, и теперь я хочу сделать cut по отношению к другому объекту. Вот мой результат: screen.Shader не работает - OpenGL ES

Экран показывает, что мы видим сквозь разрезную часть. Поэтому я решил использовать shader для заполнения этой отрезанной части.

Я попытался загрузить shader, а затем использовать его в glUniform3f, но это не сработает. Я сделал несколько поисков в Интернете, без каких-либо результатов.

Вот мой класс, чтобы загрузить shader:

- (id)initWithVertexShaderFilename:(NSString *)vShaderFilename 
     fragmentShaderFilename:(NSString *)fShaderFilename 
{ 
NSLog(fShaderFilename); 
if (self = [super init]) 
{ 
    attributes = [[NSMutableArray alloc] init]; 
    NSString *vertShaderPathname, *fragShaderPathname; 
    program = glCreateProgram(); 

    vertShaderPathname =[[NSBundle mainBundle] 
         pathForResource:vShaderFilename 
         ofType:@"vsh" 
         inDirectory:@"Shader"]; 

    if (![self compileShader:&vertShader 
         type:GL_VERTEX_SHADER 
         file:vertShaderPathname]) 
     NSLog(@"Failed to compile vertex shader"); 
    else 
     NSLog(@"Vertex Shader OK"); 

    fragShaderPathname = [[NSBundle mainBundle] 
          pathForResource:fShaderFilename 
          ofType:@"fsh" 
          inDirectory:@"Shader"]; 

    if (![self compileShader:&fragShader 
         type:GL_FRAGMENT_SHADER 
         file:fragShaderPathname]) 
     NSLog(@"Failed to compile fragment shader"); 
    else 
     NSLog(@"Fragment shader OK"); 
    glAttachShader(program, vertShader); 
    glAttachShader(program, fragShader); 
} 

return self; 
} 

- (BOOL)compileShader:(GLuint *)shader 
      type:(GLenum)type 
      file:(NSString *)file 
{ 
    NSLog(@"bonjour"); 
    GLint status; 
    const GLchar *source; 

    source = 
    (GLchar *)[[NSString stringWithContentsOfFile:file 
            encoding:NSUTF8StringEncoding 
             error:nil] UTF8String]; 
    if (!source) 
    { 
     NSLog(@"Failed to load vertex shader"); 
     return NO; 
    } 

    *shader = glCreateShader(type); 
    glShaderSource(*shader, 1, &source, NULL); 
    glCompileShader(*shader); 

    glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); 
    NSString *intString = [NSString stringWithFormat:@"%d", status]; 
    return status = GL_TRUE; 
} 

#pragma mark - 
- (void)addAttribute:(NSString *)attributeName 
{ 
    if (![attributes containsObject:attributeName]) 
    { 
     [attributes addObject:attributeName]; 
     glBindAttribLocation(program, 
         [attributes indexOfObject:attributeName], 
         [attributeName UTF8String]); 
    } 
} 

- (GLuint)attributeIndex:(NSString *)attributeName 
{ 
    return [attributes indexOfObject:attributeName]; 
} 

- (GLuint)uniformIndex:(NSString *)uniformName 
{ 
    return glGetUniformLocation(program, [uniformName UTF8String]); 
} 

#pragma mark - 
- (BOOL)link 
{ 
    GLint status; 

    glLinkProgram(program); 
    glValidateProgram(program); 

    glGetProgramiv(program, GL_LINK_STATUS, &status); 
    if (status == GL_FALSE) 
     return NO; 

    if (vertShader) 
     glDeleteShader(vertShader); 
    if (fragShader) 
     glDeleteShader(fragShader); 

    return YES; 
} 

- (void)use 
{ 
    glUseProgram(program); 
} 

Вот функция для инициализации мой shaders в главном классе:

- (void)setup 
{ 
    GLShader *theProgram = [[GLShader alloc] initWithVertexShaderFilename:@"shader" 
               fragmentShaderFilename:@"shader"]; 
    self.program = theProgram; 

    [self.program addAttribute:@"position"]; 
    [self.program addAttribute:@"textureCoordinates"]; 

    if (![self.program link]) 
    { 
     NSLog(@"Link failed"); 

     NSString *progLog = [self.program programLog]; 
     NSLog(@"Program Log: %@", progLog); 

     NSString *fragLog = [self.program fragmentShaderLog]; 
     NSLog(@"Frag Log: %@", fragLog); 

     NSString *vertLog = [self.program vertexShaderLog]; 
     NSLog(@"Vert Log: %@", vertLog); 

     //[(GLView *)self.view stopAnimation]; 
     self.program = nil; 
    } 

    textureCoordinateAttribute = [program attributeIndex:@"textureCoordinates"]; 
    colorUniform = [program uniformIndex:@"uColor"]; 
    textureUniform = [program uniformIndex:@"texture"]; 
    //colorUniform = glGetUniformLocation(self.program, "uColor"); 

    glEnable(GL_DEPTH_TEST); 
    glEnable(GL_CULL_FACE); 
    glEnable(GL_TEXTURE_2D); 
    glEnable(GL_BLEND); 
    glBlendFunc(GL_ONE, GL_ZERO);  
} 

Вот функция, где я хочу использовать shader:

-(void) draw 
{ 
    [self.program use]; 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 
    glDepthMask(true); 
    lUniform3f(colorUniform,1.0, 1.0, 0.5); 
    [self drawSubtraction:image1 with:image2]; 

} 

Адрес: fragment shader:

precision highp float; 

uniform vec3 uColor; 
uniform vec3 uLight; 

varying vec3 vNormal; 

const float alpha = 0.7; 
void main(void) { 
float val = dot(vNormal, uLight) * 0.4 + 0.6; 

gl_FragColor = vec4(uColor * val, alpha); 
} 

Я что-то не так? У кого-то есть идея, которая может мне помочь?

Спасибо.

+0

Я вижу 'lUniform3f', а не 'glUniform3f'. Поскольку все, что вы говорите, это «не работает», я думаю, что это проблема. – AbleArcher

ответ

0

Ваш шейдерный код выглядит нормально. Убедитесь, что вы правильно передаете атрибут «textureCoordinates» вершинному шейдеру. Вам нужно будет позвонить glEnableVertexAttribArray() и glVertexAttribPointer() в какой-то момент инициализации. В зависимости от того, как вы рендерите модели, вам может понадобиться убедиться, что вы тоже правильно проходите в вершинах.

Также я принимаю [self drawSubtraction:image1 with:image2] звонки glDrawArrays() или glDrawElements() в какой-то момент.

Иконный проект OpenGL по умолчанию для Xcode - отличное место для начала загрузки шейдеров, если вы хотите сравнить проект.

Смежные вопросы