2010-03-14 123 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的第一步,我无法确定任何事情。

不要犹豫,要求更多的信息。

谢谢堆栈O.

+0

我会研究亮度以生成好的灰度图像:http://en.wikipedia.org/wiki/Luma_%28video%29 – Luca 2010-03-15 06:46:47

回答

0

纹理采样器必须设置为活动纹理单元的数量。因此,例如对于glActiveTexture(GL_TEXTURE3),采样器也必须设置为3。在你的情况下,数字应该为0.

相关问题