【问题标题】:How do I blit pixel data to the screen using OpenGL ES?如何使用 OpenGL ES 将像素数据传送到屏幕上?
【发布时间】:2012-01-02 20:59:14
【问题描述】:

我目前正在学习适用于 iPhone 的 OpenGL ES,我想知道如何获取一组 RGB 像素数据并将其 blit 到屏幕上,到目前为止,我发现的所有教程都涵盖了将预先存在的图像加载到纹理并显示它。

以下是我使用 Core Graphics 完成它的方法,方法是创建一个 imageref,然后使用 UIImage 和 UIImageView:

int screenWidth = (int)[[UIScreen mainScreen] bounds].size.width;
int screenHeight = (int)[[UIScreen mainScreen] bounds].size.height;

//Create blank image
CGImageRef blankImageRef = [self createBlankImageRef];
CFDataRef m_DataRef; 
m_DataRef = CGDataProviderCopyData(CGImageGetDataProvider(blankImageRef)); 
UInt8* bufferData = CFDataGetBytePtr(m_DataRef); 


//Manipulate the image here
for(int x=0; x < screenWidth-1; x++)
{
    int y = x;//*2;

    [self setPixel:bufferData width:screenWidth x:x y:y r:255 g:0 b:0];
}


//Paint the image to the screen
CGImageRef imageRef = blankImageRef; 
CGContextRef ctx; 
ctx = CGBitmapContextCreate(bufferData, 
                            CGImageGetWidth( imageRef ), 
                            CGImageGetHeight( imageRef ), 
                            8, 
                            CGImageGetBytesPerRow( imageRef ), 
                            CGImageGetColorSpace( imageRef ), 
                            kCGImageAlphaPremultipliedLast ); 
screenImage = [UIImage imageWithCGImage:CGBitmapContextCreateImage (ctx)]; 
CGContextRelease(ctx); 

[imageView setImage:screenImage];

free(bufferData);

...

- (CGImageRef) createBlankImageRef
{
CGFloat imageScale = (CGFloat)1.0;
CGFloat width = [[UIScreen mainScreen] bounds].size.width;
CGFloat height = [[UIScreen mainScreen] bounds].size.height;

// Create a bitmap graphics context of the given size
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, width * imageScale, height * imageScale, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);

// Draw ...
CGContextSetRGBFillColor(context, (CGFloat)0.0, (CGFloat)0.0, (CGFloat)0.0, (CGFloat)1.0 );

// Get your image
CGImageRef cgImage = CGBitmapContextCreateImage(context);

CGColorSpaceRelease(colorSpace);
CGContextRelease(context);

return cgImage;
}

-(void)setPixel:(UInt8*)buffer width:(int)width x:(int)x y:(int)y r:(int)r g:(int)g b:(int)b
{
buffer[x*4 + y*(width*4)] = r;
buffer[x*4 + y*(width*4)+1] = g;
buffer[x*4 + y*(width*4)+2] = b;
buffer[x*4 + y*(width*4)+3] = 255;
}

有什么想法可以使用 OpenGL ES(当前使用 1.0)而不是 Core Graphics 来完成此任务吗?

【问题讨论】:

  • 创建一个全屏四边形,并编写一个小着色器,将您的像素数据作为 Texture2D 并在没有光照的情况下填充它。

标签: iphone objective-c opengl-es pixels


【解决方案1】:

您可以使用 glTexImage2D (http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml) 或 glTexSubImage2D (http://www.opengl.org) 创建纹理/sdk/docs/man/xhtml/glTexSubImage2D.xml)。 glTexSubImage2D主要用于实时更新贴图。

例如对于 RGBA 纹理:

GLubyte texBuffer[4*texWidth*texHeight];
GLuint texName;
glGenTextures(1, &texName) ;
glBindTexture(GL_TEXTURE_2D, texName) ;
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, texBuffer);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

如果您使用的是 ES 1.x,您也可以使用 glDrawPixels (http://www.opengl.org/sdk/docs/man/xhtml/glDrawPixels.xml)。

【讨论】:

  • texBuffer 可以是 GLuint 格式还是必须是 Glubyte?
  • 好吧,你可以将 texBuffer 声明为GLuint texBuffer[texWidth*texHeight] - 关键是大小等于sizeof(GLubyte) * 4 * texWidth * texHeight。 (在这种情况下为 4,假设您需要 4 个组件 - 即 RGBA)。当您在调用 glTexImage2D 之前填充 texBuffer 时会出现差异(在将像素设置在缓冲区中之前,您需要将 4 个组件打包到一个 uint 中)。请注意,您将保持 glTexImage2D 调用相同。
猜你喜欢
  • 1970-01-01
  • 2023-04-11
  • 1970-01-01
  • 2011-10-02
  • 1970-01-01
  • 1970-01-01
  • 2014-03-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多