2010-03-14 4 views
1

프로그램에 몇 가지 사후 처리 기능을 추가하려고합니다. 렌더링은 OpenGL을 사용하여 수행됩니다. 프로그램이 집에서 만든 조각 쉐이더를로드하고 비디오 스트림에서 사용하도록하고 싶습니다.텍스처상의 조각 쉐이더

그레이 스케일로 텍스처를 변환하는 "OpenGL Shader Builder"를 사용하여 작은 셰이더 조각을 작성했습니다. 셰이더는 셰이더 빌더에서 잘 작동하지만 주 프로그램에서 작동하지는 못합니다. 화면이 모두 검은 색으로 유지됩니다. 여기

는 설정이다 :

@implementation PluginGLView 

- (id) initWithCoder: (NSCoder *) coder 
{ 
const GLubyte * strExt; 

if ((self = [super initWithCoder:coder]) == nil) 
    return nil; 

glLock = [[NSLock alloc] init]; 
if (nil == glLock) { 
    [self release]; 
    return nil; 
} 

// Init pixel format attribs 
NSOpenGLPixelFormatAttribute attrs[] = 
{ 
    NSOpenGLPFAAccelerated, 
    NSOpenGLPFANoRecovery, 
    NSOpenGLPFADoubleBuffer, 
    0 
}; 

// Get pixel format from OpenGL 
NSOpenGLPixelFormat* pixFmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; 
if (!pixFmt) 
{ 
    NSLog(@"No Accelerated OpenGL pixel format found\n"); 

    NSOpenGLPixelFormatAttribute attrs2[] = 
    { 
     NSOpenGLPFANoRecovery, 
     0 
    }; 

    // Get pixel format from OpenGL 
    pixFmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs2]; 
    if (!pixFmt) { 
     NSLog(@"No OpenGL pixel format found!\n"); 

     [self release]; 
     return nil; 
    } 
} 

[self setPixelFormat:[pixFmt autorelease]]; 

/* 
long swapInterval = 1 ; 
[[self openGLContext] 
     setValues:&swapInterval 
     forParameter:NSOpenGLCPSwapInterval]; 
*/ 
[glLock lock]; 
[[self openGLContext] makeCurrentContext]; 

// Init object members 
strExt = glGetString (GL_EXTENSIONS); 
texture_range = gluCheckExtension ((const unsigned char *)"GL_APPLE_texture_range", strExt) ? GL_TRUE : GL_FALSE; 
texture_hint = GL_STORAGE_SHARED_APPLE ; 
client_storage = gluCheckExtension ((const unsigned char *)"GL_APPLE_client_storage", strExt) ? GL_TRUE : GL_FALSE; 
rect_texture = gluCheckExtension((const unsigned char *)"GL_EXT_texture_rectangle", strExt) ? GL_TRUE : GL_FALSE; 

// Setup some basic OpenGL stuff 
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 
glColor4f(1.0f, 1.0f, 1.0f, 1.0f); 
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
glClear(GL_COLOR_BUFFER_BIT); 

// Loads the shaders 
shader=LoadShader(GL_FRAGMENT_SHADER,"/Users/alexandremathieu/fragment.fs"); 
program=glCreateProgram(); 
glAttachShader(program, shader); 
glLinkProgram(program); 
glUseProgram(program); 

[NSOpenGLContext clearCurrentContext]; 
[glLock unlock]; 

image_width = 1024; 
image_height = 512; 
image_depth = 16; 

image_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; 
image_base = (GLubyte *) calloc(((IMAGE_COUNT * image_width * image_height)/3) * 4, image_depth >> 3); 
if (image_base == nil) { 
    [self release]; 
    return nil; 
} 

// Create and load textures for the first time 
[self loadTextures:GL_TRUE]; 

// Init fps timer 
//gettimeofday(&cycle_time, NULL); 

drawBG = YES; 

// Call for a redisplay 
noDisplay = YES; 
PSXDisplay.Disabled = 1; 
[self setNeedsDisplay:true]; 

return self; 
} 

그리고 여기에 "화면 렌더링"기능 ... 화면을 렌더링 기본적으로 이십 기가 바이트입니다.

- (void)renderScreen 
{ 
    int bufferIndex = whichImage; 

    glBindTexture(GL_TEXTURE_RECTANGLE_EXT, bufferIndex+1); 

    glUseProgram(program); 
    int loc=glGetUniformLocation(program, "texture"); 
    glUniform1i(loc,bufferIndex+1); 

    glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, image_width, image_height, GL_BGRA, image_type, image[bufferIndex]); 


    glBegin(GL_QUADS); 
     glTexCoord2f(0.0f, 0.0f); 
     glVertex2f(-1.0f, 1.0f); 

     glTexCoord2f(0.0f, image_height); 
     glVertex2f(-1.0f, -1.0f); 

     glTexCoord2f(image_width, image_height); 
     glVertex2f(1.0f, -1.0f); 

     glTexCoord2f(image_width, 0.0f); 
     glVertex2f(1.0f, 1.0f); 
    glEnd(); 

    [[self openGLContext] flushBuffer]; 
    [NSOpenGLContext clearCurrentContext]; 
    //[glLock unlock]; 

} 

마지막으로 여기에 쉐이더가 있습니다.

uniform sampler2DRect texture; 

void main() { 
    vec4 color, texel; 
    color = gl_Color; 
    texel = texture2DRect(texture, gl_TexCoord[0].xy); 
    color *= texel; 
    // Begin Shader 
    float gray=0.0; 
    gray+=(color.r + color.g + color.b)/3.0; 
    color=vec4(gray,gray,gray,color.a); 
    // End Shader 
    gl_FragColor = color; 
} 

로딩과 나는이 쉐이더

void main(){ 
    gl_FragColor=vec4(1.0,0.0,0.0,1.0); 
} 

모든 빨간색 화면을 켤 수 있어요 이후 쉐이더 내가 LoadShader 기능에서 오류 메시지 구문 오류가 포함되어있는 경우 쉐이더의 사용하여 작동 셰이더 사용을 제거하면 모든 것이 정상적으로 작동합니다.

"문제는"균일 한 매개 변수로 텍스처 전달 "에서 오는 것이라고 생각합니다. 그러나 이것들은 OpenGL을 처음 접했을 때 나는 무엇이든 확실하지 않습니다.

주저하지 말고 더 자세한 정보를 요청하십시오.

+0

좋은 그레이 스케일 이미지를 생성하기 위해 휘도를 연구합니다 : http://en.wikipedia.org/wiki/Luma_%28video%29 – Luca

답변

0

텍스처 샘플러가 활성 텍스처 유닛의 수를 설정해야합니다 당신에게 스택 O. 감사합니다. 예를 들어 glActiveTexture (GL_TEXTURE3)의 경우 샘플러는 3으로 설정되어야합니다. 귀하의 경우 숫자는 0이어야합니다.