2012-07-19 4 views
3

기본 OpenGL 뷰 (UIView의 하위 클래스)에 텍스처를 표시하려고하지만 사용하는 텍스처에 관계없이 검정색으로 표시됩니다.OpenGL ES 2.0 텍스처가 매핑되었지만 검은 색으로 표시됩니다.

@implementation SymGLView 

typedef struct { 
    float Position[3]; 
    float Color[4]; 
    float TexCoord[2]; 
} Vertex; 

const Vertex Vertices[] = { 
    {{1, -1, 0}, {1, 0, 0, 1}, {0, 0}}, 
    {{1, 1, 0}, {0, 1, 0, 1}, {0, 1}}, 
    {{-1, 1, 0}, {0, 0, 1, 1}, {1, 1}}, 
    {{-1, -1, 0}, {0, 0, 0, 1}, {1, 0}} 
}; 

const GLubyte Indices[] = { 
    0, 1, 2, 
    2, 3, 0 
}; 

+ (Class)layerClass { 
    return [CAEAGLLayer class]; 
} 

- (void)setupLayer { 
    _eaglLayer = (CAEAGLLayer*) self.layer; 
    _eaglLayer.opaque = YES; 
} 

- (void)setupContext { 
    EAGLRenderingAPI api = kEAGLRenderingAPIOpenGLES2; 
    _context = [[EAGLContext alloc] initWithAPI:api]; 
    if (!_context) { 
     NSLog(@"Failed to initialize OpenGLES 2.0 context"); 
     exit(1); 
    } 

    if (![EAGLContext setCurrentContext:_context]) { 
     NSLog(@"Failed to set current OpenGL context"); 
     exit(1); 
    } 
} 

- (void)setupRenderBuffer { 
    glGenRenderbuffers(1, &_colorRenderBuffer); 
    glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer);   
    [_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:_eaglLayer];  
} 

- (void)setupDepthBuffer { 
    glGenRenderbuffers(1, &_depthRenderBuffer); 
    glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderBuffer); 
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, self.frame.size.width, self.frame.size.height);  
} 

- (void)setupFrameBuffer {  
    GLuint framebuffer; 
    glGenFramebuffers(1, &framebuffer); 
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); 
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorRenderBuffer); 
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer); 
} 

- (GLuint)compileShader:(NSString*)shaderName withType:(GLenum)shaderType { 

    NSString* shaderPath = [[NSBundle mainBundle] pathForResource:shaderName ofType:@"glsl"]; 
    NSError* error; 
    NSString* shaderString = [NSString stringWithContentsOfFile:shaderPath encoding:NSUTF8StringEncoding error:&error]; 
    if (!shaderString) { 
     NSLog(@"Error loading shader: %@", error.localizedDescription); 
     exit(1); 
    } 

    GLuint shaderHandle = glCreateShader(shaderType);  

    const char * shaderStringUTF8 = [shaderString UTF8String];  
    int shaderStringLength = [shaderString length]; 
    glShaderSource(shaderHandle, 1, &shaderStringUTF8, &shaderStringLength); 

    glCompileShader(shaderHandle); 

    GLint compileSuccess; 
    glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &compileSuccess); 
    if (compileSuccess == GL_FALSE) { 
     GLchar messages[256]; 
     glGetShaderInfoLog(shaderHandle, sizeof(messages), 0, &messages[0]); 
     NSString *messageString = [NSString stringWithUTF8String:messages]; 
     NSLog(@"%@", messageString); 
     exit(1); 
    } 

    return shaderHandle; 

} 

- (void)compileShaders { 

    GLuint vertexShader = [self compileShader:@"SimpleVertex" withType:GL_VERTEX_SHADER]; 
    GLuint fragmentShader = [self compileShader:@"SimpleFragment" withType:GL_FRAGMENT_SHADER]; 

    GLuint programHandle = glCreateProgram(); 
    glAttachShader(programHandle, vertexShader); 
    glAttachShader(programHandle, fragmentShader); 
    glLinkProgram(programHandle); 

    GLint linkSuccess; 
    glGetProgramiv(programHandle, GL_LINK_STATUS, &linkSuccess); 
    if (linkSuccess == GL_FALSE) { 
     GLchar messages[256]; 
     glGetProgramInfoLog(programHandle, sizeof(messages), 0, &messages[0]); 
     NSString *messageString = [NSString stringWithUTF8String:messages]; 
     NSLog(@"%@", messageString); 
     exit(1); 
    } 

    glUseProgram(programHandle); 

    _positionSlot = glGetAttribLocation(programHandle, "Position"); 
    _colorSlot = glGetAttribLocation(programHandle, "SourceColor"); 
    glEnableVertexAttribArray(_positionSlot); 
    glEnableVertexAttribArray(_colorSlot); 

    _modelViewUniform = glGetUniformLocation(programHandle, "Modelview"); 

    _texCoordSlot = glGetAttribLocation(programHandle, "TexCoordIn"); 
    glEnableVertexAttribArray(_texCoordSlot); 
    _textureUniform = glGetUniformLocation(programHandle, "Texture"); 
} 

- (void)setupVBOs { 

    GLuint vertexBuffer; 
    glGenBuffers(1, &vertexBuffer); 
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW); 

    GLuint indexBuffer; 
    glGenBuffers(1, &indexBuffer); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW); 

} 

- (void)render { 
    glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0); 
    glClear(GL_COLOR_BUFFER_BIT); 

    glViewport(0, 0, self.frame.size.width, self.frame.size.height); 

    glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, 
          sizeof(Vertex), 0); 
    glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, 
          sizeof(Vertex), (GLvoid*) (sizeof(float) * 3)); 

    glVertexAttribPointer(_texCoordSlot, 2, GL_FLOAT, GL_FALSE, 
          sizeof(Vertex), (GLvoid*) (sizeof(float) * 7));  

    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, _floorTexture); 
    glUniform1i(_textureUniform, 0);  

    glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), 
        GL_UNSIGNED_BYTE, 0);  

    [_context presentRenderbuffer:GL_RENDERBUFFER]; 
} 


- (GLuint)setupTexture:(NSString *)fileName {  

    CGImageRef spriteImage = [UIImage imageNamed:fileName].CGImage; 
    if (!spriteImage) { 
     NSLog(@"Failed to load image %@", fileName); 
     exit(1); 
    } 

    size_t width = CGImageGetWidth(spriteImage); 
    size_t height = CGImageGetHeight(spriteImage); 

    GLubyte * spriteData = (GLubyte *) calloc(width*height*4, sizeof(GLubyte)); 

    CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width*4, 
                 CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast);  

    CGContextDrawImage(spriteContext, CGRectMake(0, 0, width, height), spriteImage); 

    CGContextRelease(spriteContext); 

    GLuint texName; 
    glGenTextures(1, &texName); 
    glBindTexture(GL_TEXTURE_2D, texName); 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, spriteData); 

    free(spriteData); 

    return texName;  
} 


- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 

    if (self) {   
     [self setupLayer];   
     [self setupContext];  
     [self setupDepthBuffer]; 
     [self setupRenderBuffer];   
     [self setupFrameBuffer];  
     [self compileShaders]; 
     [self setupVBOs]; 
     [self render];   
    } 
    _floorTexture = [self setupTexture:@"tile_floor.png"]; 
    return self; 
} 


@end 

버텍스 쉐이더 :

attribute vec4 Position; 

attribute vec2 TexCoordIn; 
varying vec2 TexCoordOut; 

void main(void) { 
    gl_Position = Position; 
    TexCoordOut = TexCoordIn; 
} 

조각 쉐이더 : 내보기에 대한 코드는 다음과 같다 내가 gl_FragColor의 값을 변경하여 그라데이션을 만들 수 있습니다

varying lowp vec2 TexCoordOut; 
uniform sampler2D Texture; 

void main(void) { 
    gl_FragColor = texture2D(Texture, TexCoordOut); 
} 

을하지만 몇 가지 다른 질감을 시도했으며 손실이 있습니다.

+0

쉐이더를 사용하지 않는 경우 텍스처가 가시적입니까? 문제가 텍스처 또는 텍스처 표시 여부를 확인하려고합니다. –

답변

5

것은 이것은 당신의 텍스처 일부의 OpenGL 드라이버가이에 이상한 방법으로 반응 2 (즉, 512 × 512)의 전력

하지 않은 사실에 따라 수, 일부 다른 사람은 가장 가까운 전원에 텍스처의 재 슬캘링을 수행 2 크기. 당신은 OpenGL을 골드 도서,는 OpenGL ES 2.0에 아주 좋은 설명 찾을 수 있습니다

:

는 OpenGL ES 2.0은 텍스처가 가질 수있는 당신이 아래 찾을 수 OpenGL은 골드 책에서

non-power-of-two (npot) 치수입니다. 즉, 너비와 높이가 두 배인 일 필요는 없습니다. 그러나 OpenGL ES 2.0에는 텍스처 크기가 의 두 가지가 아닌 경우 사용할 수있는 랩 모드 인 에 대한 제한 사항이 있습니다. 즉, npot 텍스처의 경우 랩 모드는 GL_CLAMP_TO_EDGE이고 만료 필터는 GL_NEAREST 또는 GL_LINEAR (즉, 밉 매핑되지 않음) 일 수 있습니다. GL_OES_texture_npot은 이러한 제한을 완화하고 GL_REPEAT 및 GL_MIRRORED_REPEAT의 랩 모드 을 허용하고 에 대한 npot 텍스처를 전체 축소 필터 집합으로 밉 매핑 할 수 있습니다.

이 정보가 도움이되기를 바랍니다.

건배

+0

도움이되었습니다. iOS에서 texture2D()는 NPOT 크기의 텍스처와 클램프 이외의 래핑 모드로 사용될 때 검정색을 반환합니다. –

관련 문제