mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
111 lines
2.9 KiB
Objective-C
111 lines
2.9 KiB
Objective-C
#import "TGPaintTexture.h"
|
|
|
|
#import <LegacyComponents/TGPaintUtils.h>
|
|
|
|
@interface TGPaintTexture ()
|
|
{
|
|
GLuint _textureName;
|
|
|
|
GLubyte *_data;
|
|
GLsizei _size;
|
|
GLuint _width;
|
|
GLuint _height;
|
|
GLenum _type;
|
|
GLenum _format;
|
|
GLuint _rowByteSize;
|
|
GLuint _unpackAlign;
|
|
}
|
|
@end
|
|
|
|
@implementation TGPaintTexture
|
|
|
|
+ (instancetype)textureWithImage:(UIImage *)image forceRGB:(bool)forceRGB
|
|
{
|
|
return [[TGPaintTexture alloc] initWithCGImage:image.CGImage forceRGB:forceRGB];
|
|
}
|
|
|
|
- (instancetype)initWithCGImage:(CGImageRef)imageRef forceRGB:(bool)forceRGB
|
|
{
|
|
self = [super init];
|
|
if (self != nil)
|
|
{
|
|
[self _loadTextureFromCGImage:imageRef forceRGB:forceRGB];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
if (_data != NULL)
|
|
free(_data);
|
|
|
|
TGPaintHasGLError();
|
|
}
|
|
|
|
- (void)cleanResources
|
|
{
|
|
if (_textureName == 0)
|
|
return;
|
|
|
|
glDeleteTextures(1, &_textureName);
|
|
_textureName = 0;
|
|
}
|
|
|
|
- (void)_loadTextureFromCGImage:(CGImageRef)image forceRGB:(bool)forceRGB
|
|
{
|
|
bool isAlpha = forceRGB ? false : CGImageGetBitsPerPixel(image) == 8;
|
|
|
|
_width = (GLuint) CGImageGetWidth(image);
|
|
_height = (GLuint) CGImageGetHeight(image);
|
|
_unpackAlign = isAlpha ? 1 : 4;
|
|
_rowByteSize = _width * _unpackAlign;
|
|
_data = malloc(_height * _rowByteSize);
|
|
_type = GL_UNSIGNED_BYTE;
|
|
_format = isAlpha ? GL_ALPHA : GL_RGBA;
|
|
|
|
CGColorSpaceRef colorSpaceRef = isAlpha ? CGColorSpaceCreateDeviceGray() : CGColorSpaceCreateDeviceRGB();
|
|
CGContextRef context = CGBitmapContextCreate(_data, _width, _height, 8, _rowByteSize, colorSpaceRef, (isAlpha ? kCGImageAlphaNone : kCGImageAlphaPremultipliedLast));
|
|
CGContextSetBlendMode(context, kCGBlendModeCopy);
|
|
CGContextDrawImage(context, CGRectMake(0.0, 0.0, _width, _height), image);
|
|
CGContextRelease(context);
|
|
|
|
CGColorSpaceRelease(colorSpaceRef);
|
|
}
|
|
|
|
static bool isPOT(int x)
|
|
{
|
|
return (x & (x - 1)) == 0;
|
|
}
|
|
|
|
- (GLuint)textureName
|
|
{
|
|
if (_textureName == 0)
|
|
{
|
|
TGPaintHasGLError();
|
|
|
|
glGenTextures(1, &_textureName);
|
|
glBindTexture(GL_TEXTURE_2D, _textureName);
|
|
|
|
bool mipMappable = isPOT(_width) && isPOT(_height);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipMappable ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
|
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, _unpackAlign);
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, _format, _width, _height, 0, _format, _type, _data);
|
|
TGPaintHasGLError();
|
|
|
|
if (mipMappable)
|
|
{
|
|
glGenerateMipmap(GL_TEXTURE_2D);
|
|
TGPaintHasGLError();
|
|
}
|
|
}
|
|
|
|
return _textureName;
|
|
}
|
|
|
|
@end
|