用于视网膜显示的OpenGL ES 2.0纹理? [英] OpenGL ES 2.0 textures for retina display?

查看:305
本文介绍了用于视网膜显示的OpenGL ES 2.0纹理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个GLKView,我尝试在其中绘制几个多维数据集,并从视图中创建纹理并将其映射到多维数据集上.但是,当我在视网膜设备上启动该应用程序时,纹理的大小正确,但是看起来很糟糕.我试图将GLKView的contentScaleFactor设置为主屏幕的比例-无济于事.我还尝试将缓冲区的尺寸乘以比例,这导致纹理看起来清晰,但仅为原始大小的1/4 ...

事不宜迟,我可以向您介绍我所做的事情(没有上面指出的乘法):

GLKView

- (void)setupGL {

    UIScreen *mainScreen = [UIScreen mainScreen];
    const CGFloat scale = mainScreen.scale;
    self.contentScaleFactor = scale;
    self.layer.contentsScale = scale;

    glGenFramebuffers(1, &defaultFrameBuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, defaultFrameBuffer);

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

    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, self.bounds.size.width, self.bounds.size.height);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);

    glGenRenderbuffers(1, &colorBuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, self.bounds.size.width, self.bounds.size.height);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ARRAY, GL_RENDERBUFFER, colorBuffer);

    glEnable(GL_DEPTH_TEST);

}

在这里加载纹理

// make space for an RGBA image of the view
 GLubyte *pixelBuffer = (GLubyte *)malloc(
                                         4 *
                                         cV.bounds.size.width * 
                                         cV.bounds.size.height);

// create a suitable CoreGraphics context
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context =
CGBitmapContextCreate(pixelBuffer,
                      cV.bounds.size.width, cV.bounds.size.height,
                      8, 4*cV.bounds.size.width,
                      colourSpace,
                      kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colourSpace);

// draw the view to the buffer
[cV.layer renderInContext:context];

// upload to OpenGL
glTexImage2D(GL_TEXTURE_2D, 0,
             GL_RGBA,
             cV.bounds.size.width, cV.bounds.size.height, 0,
             GL_RGBA, GL_UNSIGNED_BYTE, pixelBuffer);



glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

解决方案

此问题的答案可在此处找到

如何创建一个CGBitmapContext用于视网膜显示并且不浪费空间用于常规显示?

我基本上要做的是将纹理和缓冲区乘以屏幕的比例因子,因为这只能产生大小的1/4的纹理,所以我也必须将上下文乘以比例因子./p>

CGContextScaleCTM(context, scaleFactor, scaleFactor);

I have got a GLKView, where I try to draw a couple of cubes and I create textures from a view and map them onto the cubes. However, when I start the app on a retina device, the textures are correctly sized but they look terrible. I have tried to set the contentScaleFactor of the GLKView to the scale of the main screen - to no avail. I have also tried to multiply the the buffers dimensions by the scale, which resulted in textures that looked crisp, but were only 1/4 of the original size...

Without further ado, I may present you what I have done (without above indicated multiplication):

GLKView

- (void)setupGL {

    UIScreen *mainScreen = [UIScreen mainScreen];
    const CGFloat scale = mainScreen.scale;
    self.contentScaleFactor = scale;
    self.layer.contentsScale = scale;

    glGenFramebuffers(1, &defaultFrameBuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, defaultFrameBuffer);

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

    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, self.bounds.size.width, self.bounds.size.height);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);

    glGenRenderbuffers(1, &colorBuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, self.bounds.size.width, self.bounds.size.height);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ARRAY, GL_RENDERBUFFER, colorBuffer);

    glEnable(GL_DEPTH_TEST);

}

Here I load the textures

// make space for an RGBA image of the view
 GLubyte *pixelBuffer = (GLubyte *)malloc(
                                         4 *
                                         cV.bounds.size.width * 
                                         cV.bounds.size.height);

// create a suitable CoreGraphics context
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context =
CGBitmapContextCreate(pixelBuffer,
                      cV.bounds.size.width, cV.bounds.size.height,
                      8, 4*cV.bounds.size.width,
                      colourSpace,
                      kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colourSpace);

// draw the view to the buffer
[cV.layer renderInContext:context];

// upload to OpenGL
glTexImage2D(GL_TEXTURE_2D, 0,
             GL_RGBA,
             cV.bounds.size.width, cV.bounds.size.height, 0,
             GL_RGBA, GL_UNSIGNED_BYTE, pixelBuffer);



glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

解决方案

The answer to this question can be found here

How to create a CGBitmapContext which works for Retina display and not wasting space for regular display?

What I basically did, is to multiply the texture and the buffer by the screen's scale factor and because this only yielded a texture that was 1/4 of the size, I had to multiply the context by the scale factor as well

CGContextScaleCTM(context, scaleFactor, scaleFactor);

这篇关于用于视网膜显示的OpenGL ES 2.0纹理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆