5 // Created by Giles Williams on Fri Jun 21 2002.
6 // Copyright (c) 2001 __MyCompanyName__. All rights reserved.
9 #import "OpenGLSprite.h"
12 @implementation OpenGLSprite
20 - (id) initWithImage:(NSImage *)textureImage cropRectangle:(NSRect)cropRect size:(NSSize) spriteSize
23 [self makeTextureFromImage:textureImage cropRectangle:cropRect size:spriteSize];
30 const GLuint delTextures[1] = { texName };
31 glDeleteTextures(1, delTextures); // clean up the texture from the 3d card's memory
33 [textureData release];
37 - (void)blitToX:(float)x Y:(float)y Z:(float)z
39 glEnable(GL_TEXTURE_2D);
40 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
41 glBindTexture(GL_TEXTURE_2D, texName);
44 glTexCoord2f(0.0, 1.0-textureCropRect.size.height);
45 glVertex3f(x, y+size.height, z);
47 glTexCoord2f(0.0, 1.0);
50 glTexCoord2f(textureCropRect.size.width, 1.0);
51 glVertex3f(x+size.width, y, z);
53 glTexCoord2f(textureCropRect.size.width, 1.0-textureCropRect.size.height);
54 glVertex3f(x+size.width, y+size.height, z);
57 glDisable(GL_TEXTURE_2D);
60 - (void)blitToX:(float)x Y:(float)y Z:(float)z Alpha:(float)a
63 a = 0.0; // clamp the alpha value
65 a = 1.0; // clamp the alpha value
66 glEnable(GL_TEXTURE_2D);
67 glColor4f(1.0, 1.0, 1.0, a);
68 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
69 glBindTexture(GL_TEXTURE_2D, texName);
72 glTexCoord2f(0.0, 1.0-textureCropRect.size.height);
73 glVertex3f(x, y+size.height, z);
75 glTexCoord2f(0.0, 1.0);
78 glTexCoord2f(textureCropRect.size.width, 1.0);
79 glVertex3f(x+size.width, y, z);
81 glTexCoord2f(textureCropRect.size.width, 1.0-textureCropRect.size.height);
82 glVertex3f(x+size.width, y+size.height, z);
85 glDisable(GL_TEXTURE_2D);
88 - (void)makeTextureFromImage:(NSImage *)texImage cropRectangle:(NSRect)cropRect size:(NSSize)spriteSize
90 NSBitmapImageRep* bitmapImageRep;
91 NSRect textureRect = NSMakeRect(0.0,0.0,OPEN_GL_SPRITE_MIN_WIDTH,OPEN_GL_SPRITE_MIN_HEIGHT);
98 textureCropRect = cropRect;
100 //NSLog(@"texImage size is %f %f - textureRect.size is %f %f", [texImage size].width, [texImage size].height, textureRect.size.width, textureRect.size.height);
102 // correct size for texture to a power of two
104 while (textureRect.size.width < [texImage size].width)
105 textureRect.size.width *= 2;
106 while (textureRect.size.height < [texImage size].height)
107 textureRect.size.height *= 2;
109 while (textureRect.size.width < cropRect.size.width)
110 textureRect.size.width *= 2;
111 while (textureRect.size.height < cropRect.size.height)
112 textureRect.size.height *= 2;
114 textureRect.origin= NSMakePoint(0,0);
115 textureCropRect.origin= NSMakePoint(0,0);
117 textureSize = textureRect.size;
119 image = [[NSImage alloc] initWithSize:textureRect.size];
122 [[NSColor clearColor] set];
123 NSRectFill(textureRect);
124 [texImage drawInRect:textureCropRect fromRect:cropRect operation:NSCompositeSourceOver fraction:1.0];
125 bitmapImageRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:textureRect];
129 // normalise textureCropRect size to 0.0 -> 1.0
130 textureCropRect.size.width /= textureRect.size.width;
131 textureCropRect.size.height /= textureRect.size.height;
133 //NSLog(@"Texture has :\n%d bitsPerPixel\n%d bytesPerPlane\n%d bytesPerRow",[bitmapImageRep bitsPerPixel],[bitmapImageRep bytesPerPlane],[bitmapImageRep bytesPerRow]);
134 //NSLog(@"Texture is :\n%f x %f pixels, using %f x %f",textureRect.size.width,textureRect.size.height,textureCropRect.size.width,textureCropRect.size.height);
137 [textureData autorelease];
138 textureData = [[NSData dataWithBytes:[bitmapImageRep bitmapData] length:textureRect.size.width*textureRect.size.height*4] retain];
139 [bitmapImageRep release];
141 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
142 glGenTextures(1, &texName); // get a new unique texture name
143 glBindTexture(GL_TEXTURE_2D, texName); // initialise it
145 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
146 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
147 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
148 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
150 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureRect.size.width, textureRect.size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, [textureData bytes]);
154 - (void)replaceTextureFromImage:(NSImage *)texImage cropRectangle:(NSRect)cropRect
156 NSBitmapImageRep* bitmapImageRep;
157 NSRect textureRect = NSMakeRect(0.0,0.0,OPEN_GL_SPRITE_MIN_WIDTH,OPEN_GL_SPRITE_MIN_HEIGHT);
163 textureCropRect = cropRect;
165 //NSLog(@"texImage size is %f %f - textureRect.size is %f %f", [texImage size].width, [texImage size].height, textureRect.size.width, textureRect.size.height);
167 // correct size for texture to a power of two
168 while (textureRect.size.width < cropRect.size.width)
169 textureRect.size.width *= 2;
170 while (textureRect.size.height < cropRect.size.height)
171 textureRect.size.height *= 2;
173 if ((textureRect.size.width != textureSize.width)||(textureRect.size.height != textureSize.height))
175 NSLog(@"ERROR! replacement texture isn't the same size as original texture");
176 NSLog(@"cropRect %f x %f textureSize %f x %f",textureRect.size.width, textureRect.size.height, textureSize.width, textureSize.height);
180 textureRect.origin= NSMakePoint(0,0);
181 //textureRect.size = textureSize;
182 textureCropRect.origin= NSMakePoint(0,0);
184 image = [[NSImage alloc] initWithSize:textureRect.size];
187 [[NSColor clearColor] set];
188 NSRectFill(textureRect);
189 [texImage drawInRect:textureCropRect fromRect:cropRect operation:NSCompositeSourceOver fraction:1.0];
190 bitmapImageRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:textureRect];
194 // normalise textureCropRect size to 0.0 -> 1.0
195 textureCropRect.size.width /= textureRect.size.width;
196 textureCropRect.size.height /= textureRect.size.height;
198 //NSLog(@"Texture has :\n%d bitsPerPixel\n%d bytesPerPlane\n%d bytesPerRow",[bitmapImageRep bitsPerPixel],[bitmapImageRep bytesPerPlane],[bitmapImageRep bytesPerRow]);
199 //NSLog(@"Texture is :\n%f x %f pixels, using %f x %f",textureRect.size.width,textureRect.size.height,textureCropRect.size.width,textureCropRect.size.height);
202 [textureData autorelease];
203 textureData = [[NSData dataWithBytes:[bitmapImageRep bitmapData] length:textureSize.width*textureSize.height*4] retain];
204 [bitmapImageRep release];
206 glBindTexture(GL_TEXTURE_2D, texName);
208 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, textureSize.width, textureSize.height, GL_RGBA, GL_UNSIGNED_BYTE, [textureData bytes]);
212 - (void)substituteTextureFromImage:(NSImage *)texImage
214 NSBitmapImageRep* bitmapImageRep;
215 NSRect cropRect = NSMakeRect(0.0,0.0,[texImage size].width,[texImage size].height);
216 NSRect textureRect = NSMakeRect(0.0,0.0,textureSize.width,textureSize.height);
222 image = [[NSImage alloc] initWithSize:textureSize];
225 [[NSColor clearColor] set];
226 NSRectFill(textureRect);
227 [texImage drawInRect:textureRect fromRect:cropRect operation:NSCompositeSourceOver fraction:1.0];
228 bitmapImageRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:textureRect];
232 // normalise textureCropRect size to 0.0 -> 1.0
233 textureCropRect = NSMakeRect(0.0,0.0,1.0,1.0);
235 //NSLog(@"Texture has :\n%d bitsPerPixel\n%d bytesPerPlane\n%d bytesPerRow",[bitmapImageRep bitsPerPixel],[bitmapImageRep bytesPerPlane],[bitmapImageRep bytesPerRow]);
236 //NSLog(@"Texture is :\n%f x %f pixels, using %f x %f",textureRect.size.width,textureRect.size.height,textureCropRect.size.width,textureCropRect.size.height);
238 if ([bitmapImageRep bitsPerPixel]==32)
241 [textureData autorelease];
242 textureData = [[NSData dataWithBytes:[bitmapImageRep bitmapData] length:textureSize.width*textureSize.height*4] retain];
244 glBindTexture(GL_TEXTURE_2D, texName);
246 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, textureSize.width, textureSize.height, GL_RGBA, GL_UNSIGNED_BYTE, [textureData bytes]);
248 else if ([bitmapImageRep bitsPerPixel]==24)
251 [textureData autorelease];
252 textureData = [[NSData dataWithBytes:[bitmapImageRep bitmapData] length:textureSize.width*textureSize.height*3] retain];
254 glBindTexture(GL_TEXTURE_2D, texName);
256 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, textureSize.width, textureSize.height, GL_RGB, GL_UNSIGNED_BYTE, [textureData bytes]);
258 [bitmapImageRep release];