读取GL_SHADER_STORAGE_BUFFER会降低帧速率

时间:2015-02-16 13:47:20

标签: glsl

我从着色器存储缓冲区读回数据后得到的帧速率非常低,即使我只读取一次数据。

这就是我绑定它的方式:

glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, posBuf);
glBufferData(GL_SHADER_STORAGE_BUFFER, numPoints*4* sizeof(GLfloat),&points[0][0], GL_DYNAMIC_Draw);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, NULL);

并阅读:

GLfloat * temp = new GLfloat[numPoints*4];
glBindBuffer(GL_SHADER_STORAGE_BUFFER, posBuf);
glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, numPoints* 4 * sizeof(GLfloat), temp);
glBindBuffer( GL_SHADER_STORAGE_BUFFER, 0 );

在帧速率从200下降到15之后执行此操作。

有什么办法可以避免吗?

谢谢!

2 个答案:

答案 0 :(得分:0)

对不起该语言,但这是保存.PNG文件的Objective C方法的快速直接复制。我相信你可以收集显着的代码。

// ****************************************** High Resolution Image With Alpha *********************************************

- (void) saveHiResFileWithAlpha
{    
    // ************************************** Save the Current Viewport Size

    GLint screenViewPort[4];
    glGetIntegerv(GL_VIEWPORT, screenViewPort);

    // ***************************** Define a Second Output Buffer and Bind it for Writing

    glGenFramebuffersEXT(1, wispSecondOutputBuffer);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, wispSecondOutputBuffer[0]);

    // ******************************* Set the Viewport to the Texture Size and Reshape

    glViewport(0,0,TEXTUREWIDTH, TEXTUREHEIGHT); // Texture is 6000 X 4000
    [self resizeTextureGL]; // Calculate Model View and Projection Matrices

    // ************************************** Create the Output Imgage Texture

    glGenTextures( 1, wispOutputTexture);
    glBindTexture(GL_TEXTURE_2D, wispOutputTexture[0]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)TEXTUREWIDTH, (GLsizei)TEXTUREHEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    // ********************************* Attach the Output Texture to the Frame Buffer

    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, wispOutputTexture[0], 0);

    GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0};
    glDrawBuffers(1, DrawBuffers);

    // ************************************ Check that the Frame Buffer is Complete

    GLenum frameBufferStatus;

    frameBufferStatus = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);

    if(frameBufferStatus != GL_FRAMEBUFFER_COMPLETE_EXT) NSLog(@"There is a problem with the output frame buffer");

    // ****************************************** Render to the Texture

    [self runTextureShaders]; // Render the image
    [self runTextureShaders2];

    // ************************************ Reset the Viewport and Frame Buffer

    glViewport(screenViewPort[0],screenViewPort[1],(GLsizei)screenViewPort[2], (GLsizei)screenViewPort[3]);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

    // ***************************************** Create a bitmap Image Rep

    NSBitmapImageRep* bitmapImageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:(unsigned char **)NULL
                                                                               pixelsWide:(int)TEXTUREWIDTH
                                                                           pixelsHigh:(int)TEXTUREHEIGHT
                                                                        bitsPerSample:(int)8
                                                                      samplesPerPixel:(int)4
                                                                             hasAlpha:(BOOL)YES
                                                                             isPlanar:(BOOL)NO
                                                                       colorSpaceName:(NSString *)NSDeviceRGBColorSpace
                                                                          bytesPerRow:(int)(TEXTUREWIDTH * sizeof(AlphaPixelBytes))
                                                                         bitsPerPixel:(int)0];

    // ******************************* Copy the Texture Data Into the Bitmap Image

    glBindTexture(GL_TEXTURE_2D, wispOutputTexture[0]);
    glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmapImageRep.bitmapData);

    // ******************************* Multiply the RGB data by the Alpha Component

    AlphaPixelBytes *outputPixel = (AlphaPixelBytes*)[bitmapImageRep bitmapData];
    float floatOutputPixel, floatOutputAlpha;

    for(int i = 0; i < NUMTEXTUREPOINTS; i++)
    {
        floatOutputAlpha = (float)outputPixel[i].alpha / 255.0;

        floatOutputPixel = (float)outputPixel[i].red * floatOutputAlpha;
        outputPixel[i].red = (unsigned char) floatOutputPixel;

        floatOutputPixel = (float)outputPixel[i].green * floatOutputAlpha;
        outputPixel[i].green = (unsigned char) floatOutputPixel;

        floatOutputPixel = (float)outputPixel[i].blue * floatOutputAlpha;
        outputPixel[i].blue = (unsigned char) floatOutputPixel;
    }

    // ********************************************* Set the File Name

    NSMutableString *highResPath = [NSMutableString stringWithString:appController->appDelegate->fileLoaded];

    NSUInteger fileNameLength = highResPath.length;
    NSRange deleteRange;
    deleteRange.location = fileNameLength-3;
    deleteRange.length = 3;
    [highResPath deleteCharactersInRange:deleteRange];
    [highResPath appendString:@"png"];

    // ******************************************* Set the Save Panel

    NSSavePanel *fileSavePanel = [NSSavePanel savePanel];
    NSArray* allowedFileTypes = [[NSArray alloc] initWithObjects:@"png", nil];
    NSURL *saveDirectoryURL = [NSURL fileURLWithPath:appController->appDelegate->wispUserImageFileDirectory isDirectory:YES];
    [fileSavePanel setAllowedFileTypes:allowedFileTypes];
    [fileSavePanel setTitle:@"Wisp3D File Manager"];
    [fileSavePanel setNameFieldStringValue:highResPath];
    [fileSavePanel setDirectoryURL:saveDirectoryURL];

    // *********************************** Write the Data Out to Disk - No Compression

    NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:1.0]
                                                       forKey: NSImageCompressionFactor];
    NSData *outputImageData = [bitmapImageRep representationUsingType: NSPNGFileType properties:imageProps];

    NSUInteger result = [fileSavePanel runModal];

    if (result == NSFileHandlingPanelOKButton)
    {
        BOOL saveStatus = NO;
        NSURL *theFile = [fileSavePanel URL];

        // ********************************** Update the Default Directory

        NSString *theNewFileName = [NSString stringWithString:[theFile lastPathComponent]];
        NSUInteger theNewFileLength = theNewFileName.length;
        NSMutableString *theNewPath = [NSMutableString stringWithString:[theFile path]];
        NSUInteger theNewPathLength = theNewPath.length;
        deleteRange.location = theNewPathLength-theNewFileLength-1;
        deleteRange.length = theNewFileLength+1;
        [theNewPath deleteCharactersInRange:deleteRange];

        [appController->appDelegate->wispUserImageFileDirectory setString:theNewPath];

        // ***************************************** Write the File

        saveStatus = [outputImageData writeToURL:theFile atomically:YES];

        NSAlert *fileSavedAlert = [[NSAlert alloc] init];
        [fileSavedAlert addButtonWithTitle:@"OK"];

        if(saveStatus)
        {
            [fileSavedAlert setMessageText:@"File Save was Successful"];

        }else{
            [fileSavedAlert setMessageText:@"File Save failed"];
        }

        [fileSavedAlert runModal];
    }

    // ******************************************* Cleanup Memory

    glDeleteTextures(1, wispOutputTexture);
    glDeleteFramebuffersEXT(1, wispSecondOutputBuffer);

    return;
}

AlphaPixelBytes定义为:

typedef struct
{
    unsigned char red;
    unsigned char green;
    unsigned char blue;
    unsigned char alpha;

} AlphaPixelBytes;

答案 1 :(得分:0)

我在使用glGetBufferSubData之前将数据复制到GL_COPY_READ_BUFFER。它工作,我没有帧速率下降。我仍然不明白为什么,但至少它是有效的...非常感谢你的帮助!

glBindBuffer(GL_SHADER_STORAGE_BUFFER, _positionBuffer);
glBindBuffer(GL_COPY_READ_BUFFER, _outputBuffer);
glCopyBufferSubData(GL_SHADER_STORAGE_BUFFER, GL_COPY_READ_BUFFER,0,0, _vertexCount* 4 * sizeof(GLfloat));
GLfloat temp [_vertexCount][4];
glBindBuffer(GL_COPY_READ_BUFFER, _outputBuffer);
glGetBufferSubData(GL_COPY_READ_BUFFER, 0, _vertexCount* 4 * sizeof(GLfloat), &temp[0][0]);
glBindBuffer( GL_COPY_READ_BUFFER, NULL );
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
glBindBuffer(GL_COPY_READ_BUFFER, 0);