В моем проекте opengl мне нужно преобразовать UIImage в текстуру; какой способ сделать это? Можете ли вы мне помочь?
Преобразование UIImage в текстуру
Ответ 1
Я не тестировал следующее, но я разложу преобразование в 3 этапа:
-
Извлеките информацию для своего изображения:
UIImage* image = [UIImage imageNamed:@"imageToApplyAsATexture.png"]; CGImageRef imageRef = [image CGImage]; int width = CGImageGetWidth(imageRef); int height = CGImageGetHeight(imageRef);
-
Выделите a
textureData
с указанными выше свойствами:GLubyte* textureData = (GLubyte *)malloc(width * height * 4); // if 4 components per pixel (RGBA) CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); NSUInteger bytesPerPixel = 4; NSUInteger bytesPerRow = bytesPerPixel * width; NSUInteger bitsPerComponent = 8; CGContextRef context = CGBitmapContextCreate(textureData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); CGColorSpaceRelease(colorSpace); CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); CGContextRelease(context);
-
Настройка текстуры:
GLuint textureID; glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D, textureID); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
EDIT:
Прочитайте this tut; все объясняется из преобразования одного изображения в текстуру и применения текстуры в среде iOS.
Ответ 2
Другой способ сделать это с помощью оболочки GLKit:
//Path to image
NSString *path = [[NSBundle mainBundle] pathForResource:@"textureImage" ofType:@"png"];
//Set eaglContext
[EAGLContext setCurrentContext:[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]];
//Create texture
NSError *theError;
GLKTextureInfo *texture = [GLKTextureLoader textureWithContentsOfFile:filePath options:nil error:&theError];
glBindTexture(texture.target, texture.name);
texture.name
- это имя контекста OpenGL для текстуры.
Ответ 3
Вот быстрая версия получения текстуры из UIImage
func setupTexture(sourceImage: UIImage) -> GLuint {
guard let textureImage = sourceImage.cgImage else {
print("Failed to load image")
return 0
}
let width = textureImage.width
let height = textureImage.height
/*
it will write one byte each for red, green, blue, and alpha – so 4 bytes in total.
*/
let textureData = calloc(width * height * 4, MemoryLayout<GLubyte>.size) //4 components per pixel (RGBA)
let spriteContext = CGContext(data: textureData,
width: width,
height: height,
bitsPerComponent: 8,
bytesPerRow: width * 4,
space: textureImage.colorSpace!,
bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)
spriteContext?.draw(textureImage, in: CGRect(x: 0, y: 0, width: width, height: height))
var textName = GLuint()
glGenTextures(1, &textName)
glBindTexture(GLenum(GL_TEXTURE_2D), textName)
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MIN_FILTER), GL_NEAREST)
glTexImage2D(GLenum(GL_TEXTURE_2D), 0, GL_RGBA, GLsizei(width),
GLsizei(height), 0, GLenum(GL_RGBA), GLenum(GL_UNSIGNED_BYTE), textureData)
return textName
}
Примечание. Необходимо иметь в виду, что Core Graphics переворачивает изображения при их загрузке.