Frage

Ich versuche, einige Post-Processing-Fähigkeiten zu einem Programm hinzuzufügen. Das Rendering mit OpenGL gemacht. Ich will nur das Programm ermöglichen, einige hausgemachte Fragment-Shader zu laden und sie auf dem Video-Stream.

Ich schrieb ein kleines Stück Shader „OpenGL Shader Builder“ verwenden, die nur eine Textur in Graustufen verwandelt. Die Shader funktionieren gut im Shader-Builder, aber ich kann es im Hauptprogramm nicht funktioniert. Die Bildschirm bleibt alles schwarz.

Hier ist das Setup:

@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;
}

Und hier ist die "Render-Bildschirm" Funktion Weicht im Grunde ... den Bildschirm macht.

- (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];

}

und schließlich hier ist der Shader.

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;
 }

Das Laden und Shadern der Verwendung arbeitet seit ich in der Lage bin der Bildschirm alle mit diesem Shader

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

Wenn der Shader einen Syntaxfehler enthält eine Fehlermeldung von der LoadShader Funktion erhalten usw. Wenn ich die Verwendung des Shaders entfernen, alles funktioniert normal.

Ich denke, das Problem aus dem kommt, was „die Textur als einheitliche Parameter übergeben“. Aber das ist meine sehr Premieren mit openGL Schritt und ich kann nicht sicher sein, nichts.

Zögern Sie nicht, für weitere Informationen zu fragen.

Danke Stapel O.

War es hilfreich?

Lösung

Texture Sampler hat auf die Anzahl der aktiven Textureinheit eingestellt werden. So zum Beispiel mit glActiveTexture (GL_TEXTURE3) der Probenehmer muss auch auf 3 gesetzt werden. In Ihrem Fall sollte die Zahl 0 sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top