ios - 将大纹理渲染到较小的渲染缓冲区

标签 ios opengl-es

我有一个 852x640 的渲染缓冲区和一个 1280x720 的纹理。当我渲染纹理时,它会被裁剪,而不仅仅是拉伸(stretch)。我知道长宽比需要校正,但如何才能获得它以便在渲染缓冲区中显示完整的纹理?

//-------------------------------------
    glGenFramebuffers(1, &frameBufferHandle);
    glBindFramebuffer(GL_FRAMEBUFFER, frameBufferHandle);

    glGenRenderbuffers(1, &renderBufferHandle);
    glBindRenderbuffer(GL_RENDERBUFFER, renderBufferHandle);

    [oglContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];

    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &renderBufferWidth);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &renderBufferHeight);

    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderBufferHandle);
//-------------------------------------


static const GLfloat squareVertices[] = {
    -1.0f, 1.0f,
    1.0f, 1.0f,
    -1.0f,  -1.0f,
    1.0f,  -1.0f
};

static const GLfloat horizontalFlipTextureCoordinates[] = {
    0.0f, 1.0f,
    1.0f, 1.0f,
    0.0f,  0.0f,
    1.0f,  0.0f,
};

size_t frameWidth = CVPixelBufferGetWidth(pixelBuffer);
size_t frameHeight = CVPixelBufferGetHeight(pixelBuffer);

CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, 
                                                            videoTextureCache,
                                                            pixelBuffer,
                                                            NULL,
                                                            GL_TEXTURE_2D,
                                                            GL_RGBA,
                                                            frameWidth,
                                                            frameHeight,
                                                            GL_BGRA,
                                                            GL_UNSIGNED_BYTE,
                                                            0,
                                                            &texture);


if (!texture || err) {
    NSLog(@"CVOpenGLESTextureCacheCreateTextureFromImage failed (error: %d)", err);  
    return;
}

glBindTexture(CVOpenGLESTextureGetTarget(texture), CVOpenGLESTextureGetName(texture));

glViewport(0, 0, renderBufferWidth, renderBufferHeight); // setting this to 1280x720 fixes the aspect ratio but still crops

glBindFramebuffer(GL_FRAMEBUFFER, frameBufferHandle);

glUseProgram(shaderPrograms[PASSTHROUGH]);

// Update attribute values.
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_FLOAT, 0, 0, horizontalFlipTextureCoordinates);
glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

// Present
glBindRenderbuffer(GL_RENDERBUFFER, renderBufferHandle);
[oglContext presentRenderbuffer:GL_RENDERBUFFER];

编辑

我仍然遇到问题。我已经包含了更多来源。基本上,我需要整个原始输入纹理在宽屏幕上显示,同时还将原始纹理写入磁盘。

当渲染到较小的纹理时,事物会自动缩放,这不是渲染缓冲区的情况吗?

我想我可以再次传递到较小的纹理,但这会减慢速度。

最佳答案

首先,将 glViewport(0, 0, renderBufferWidth, renderBufferHeight); 保留为 852x640。 问题出在您的 squareVertices 中 - 看起来它保留了代表纹理大小的坐标。您需要将其设置为等于渲染缓冲区大小。

这个想法是将纹理映射到您的 squareVertices 矩形上。因此,您可以渲染映射到任何大小的矩形的任何大小的纹理 - 纹理图像将缩放以适合矩形。

[更新:方形顶点]

在你的情况下应该是:

{
0.0f, (float)renderBufferWidth/frameHeight,
(float)renderBufferWidth/frameWidth, (float)renderBufferHeight/frameHeight,
0.0f,  0.0f,
(float)renderBufferWidth/frameWidth,  0.0f,
};

但这并不是一个好的共同解决方案。从理论上讲,屏幕上矩形的大小是由顶点位置和变换矩阵决定的。每个顶点在渲染到屏幕上之前都会与矩阵相乘。看起来你没有设置 OpenGL projection matrix 。通过正确的正交投影,您的顶点应该具有像素等效的位置。

关于ios - 将大纹理渲染到较小的渲染缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12432609/

相关文章:

ios - 有人可以解释一下苹果评论指南吗?

java - openGL以伪3D视角绘制扭曲的 Sprite (图像)

iphone - 如何用 GLKit 的 OpenGL View 替换 OpenGL ES 1.1 EAGLLayer View ?

android - 没有 setZOrderOnTop(true) 的透明 SurfaceView

iphone - 如何使用 OpenGL ES 2.0 旋转对象?

opengl-es - OpenGL ES 中顶点属性指针是否持久?

ios - Unity 到 iOS,info.plist 在 PostProcessBuild 后被覆盖

ios - 从 iOS 应用程序中的证书文件获取公钥信息

ios - 游戏中心挑战

android - 短信电话号码验证的替代方案 - 全局