OpenGL ES纹理质量下降

我正在尝试将生成的核心图形图像(以屏幕分辨率)绘制到OpenGL中。 但是,图像比CG输出渲染更多的混叠(CG中禁用了抗锯齿)。 文本是纹理 (蓝色背景分别在第一张图像的Core Graphics和第二张OpenGL中绘制)。

CG输出: 嗯可爱和光滑

OpenGL渲染(在模拟器中):

EWWW

帧缓冲区设置:

context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:context];

glGenRenderbuffers(1, &onscrRenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, onscrRenderBuffer);
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:self.layer];

glGenFramebuffers(1, &onscrFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, onscrFramebuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, onscrRenderBuffer);

纹理加载代码:

-(GLuint) loadTextureFromImage:(UIImage*)image {

    CGImageRef textureImage = image.CGImage;

    size_t width = CGImageGetWidth(textureImage);
    size_t height = CGImageGetHeight(textureImage);

    GLubyte* spriteData = (GLubyte*) malloc(width*height*4);

    CGColorSpaceRef cs = CGImageGetColorSpace(textureImage);
    CGContextRef c = CGBitmapContextCreate(spriteData, width, height, 8, width*4, cs, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(cs);

    CGContextScaleCTM(c, 1, -1);
    CGContextTranslateCTM(c, 0, -CGContextGetClipBoundingBox(c).size.height);

    CGContextDrawImage(c, (CGRect){CGPointZero, {width, height}}, textureImage);
    CGContextRelease(c);

    GLuint glTex;
    glGenTextures(1, &glTex);
    glBindTexture(GL_TEXTURE_2D, glTex);

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

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);

    glBindTexture(GL_TEXTURE_2D, 0);

    free(spriteData);

    return glTex;
}

顶点:

struct vertex {
    float position[3];
    float color[4];
    float texCoord[2];
};

typedef struct vertex vertex;

const vertex bgVertices[] = {
    {{1, -1, 0}, {0, 167.0/255.0, 253.0/255.0, 1}, {1, 0}}, // BR (0)
    {{1, 1, 0}, {0, 222.0/255.0, 1.0, 1}, {1, 1}}, // TR (1)
    {{-1, 1, 0}, {0, 222.0/255.0, 1.0, 1}, {0, 1}}, // TL (2)
    {{-1, -1, 0}, {0, 167.0/255.0, 253.0/255.0, 1}, {0, 0}} // BL (3)
};

const vertex textureVertices[] = {
    {{1, -1, 0}, {0, 0, 0, 0}, {1, 0}}, // BR (0)
    {{1, 1, 0}, {0, 0, 0, 0}, {1, 1}}, // TR (1)
    {{-1, 1, 0}, {0, 0, 0, 0}, {0, 1}}, // TL (2)
    {{-1, -1, 0}, {0, 0, 0, 0}, {0, 0}} // BL (3)
};

const GLubyte indicies[] = {
    3, 2, 0, 1
};

渲染代码:

glClear(GL_COLOR_BUFFER_BIT);

GLsizei width, height;
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height);

glViewport(0, 0, width, height);

glBindBuffer(GL_ARRAY_BUFFER, bgVertexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);

glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), 0);
glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(vertex), (GLvoid*)(sizeof(float)*3));
glVertexAttribPointer(textureCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(vertex), (GLvoid*)(sizeof(float)*7));

glDrawElements(GL_TRIANGLE_STRIP, sizeof(indicies)/sizeof(indicies[0]), GL_UNSIGNED_BYTE, 0);


glBindBuffer(GL_ARRAY_BUFFER, textureVertexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(textureUniform, 0);

glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), 0);
glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(vertex), (GLvoid*)(sizeof(float)*3));
glVertexAttribPointer(textureCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(vertex), (GLvoid*)(sizeof(float)*7));

glDrawElements(GL_TRIANGLE_STRIP, sizeof(indicies)/sizeof(indicies[0]), GL_UNSIGNED_BYTE, 0);

glBindTexture(GL_TEXTURE_2D, 0);

如果与它有任何关系,我正在使用混合函数glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

任何想法的问题是?


你的GL呈现的输出看起来全部像素化,因为它具有较少的像素。 根据iOS的绘图和打印指南, CAEAGLLayer的默认比例因子是1.0,所以当您设置GL渲染缓冲区时,每个点会在缓冲区中获得一个像素。 (记住,一个点是一个UI布局单元,在具有Retina显示器的现代设备上可以用于多个硬件像素)。当您全屏渲染缓冲区时,所有内容都会放大(在iPhone 6上大约增加2.61倍s)Plus)。

要以本机屏幕分辨率进行渲染,您需要增加视图的contentScaleFactor 。 (最好在设置渲染缓冲区之前尽早完成此操作,以便从视图的图层中获取新的比例因子。)

但请注意:您希望使用UIScreen属性nativeScale ,而不是scalescale属性反映了UI渲染,在iPhone 6(s)Plus上,所有事情都以3x完成,然后稍微缩小到显示器的原始分辨率。 nativeScale属性反映了每个点的实际设备像素数量 - 如果您正在进行GPU渲染,则需要定位这一点,以便通过绘制比您需要的更多像素来消除性能。 (在“Plus”iPhone以外的当前设备上, scalenativeScale是相同的,但使用后者可能是一个很好的保险政策。)

通过让GLKView为你做渲染缓冲区设置,你可以避免很多这类问题(和其他问题)。 即使你正在编写跨平台的GL,无论如何,你的代码中的那部分必须是平台和设备相关的,所以你不妨减少你编写和维护的代码量。

(为解决问题的后续编辑,为了后人的缘故:这与多重采样或GL纹理数据的质量无关。多重采样与多边形边缘的光栅化有关 - 多边形内部的点每像素获得一个片段,但边上的点会在解析阶段获得多个颜色混合的片段,如果将纹理绑定到FBO和glReadPixels ,您会发现图像几乎与放入的图像相同。)

链接地址: http://www.djcxy.com/p/34023.html

上一篇: OpenGL ES texture degrades in quality

下一篇: Rendering "layers" in OpenGL ES