5 // Created by Giles Williams on Fri Jun 21 2002.
6 // Copyright (c) 2001 __MyCompanyName__. All rights reserved.
9 #import "OpenGLSprite.h"
11 @implementation OpenGLSprite
19 - (id) initWithImage:(NSImage *)textureImage cropRectangle:(NSRect)cropRect size:(NSSize) spriteSize
22 [self makeTextureFromImage:textureImage cropRectangle:cropRect size:spriteSize];
29 const GLuint delTextures[1] = { texName };
30 glDeleteTextures(1, delTextures); // clean up the texture from the 3d card's memory
32 [textureData release];
36 - (void)blitToX:(float)x Y:(float)y Z:(float)z
38 glEnable(GL_TEXTURE_2D);
39 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
40 glBindTexture(GL_TEXTURE_2D, texName);
43 glTexCoord2f(0.0, 1.0-textureCropRect.size.height);
44 glVertex3f(x, y+size.height, z);
46 glTexCoord2f(0.0, 1.0);
49 glTexCoord2f(textureCropRect.size.width, 1.0);
50 glVertex3f(x+size.width, y, z);
52 glTexCoord2f(textureCropRect.size.width, 1.0-textureCropRect.size.height);
53 glVertex3f(x+size.width, y+size.height, z);
56 glDisable(GL_TEXTURE_2D);
59 - (void)blitToX:(float)x Y:(float)y Z:(float)z Alpha:(float)a
62 a = 0.0; // clamp the alpha value
64 a = 1.0; // clamp the alpha value
65 glEnable(GL_TEXTURE_2D);
66 glColor4f(1.0, 1.0, 1.0, a);
67 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
68 glBindTexture(GL_TEXTURE_2D, texName);
71 glTexCoord2f(0.0, 1.0-textureCropRect.size.height);
72 glVertex3f(x, y+size.height, z);
74 glTexCoord2f(0.0, 1.0);
77 glTexCoord2f(textureCropRect.size.width, 1.0);
78 glVertex3f(x+size.width, y, z);
80 glTexCoord2f(textureCropRect.size.width, 1.0-textureCropRect.size.height);
81 glVertex3f(x+size.width, y+size.height, z);
84 glDisable(GL_TEXTURE_2D);
87 - (void)makeTextureFromImage:(NSImage *)texImage cropRectangle:(NSRect)cropRect size:(NSSize)spriteSize
89 NSBitmapImageRep* bitmapImageRep;
90 NSRect textureRect = NSMakeRect(0.0,0.0,OPEN_GL_SPRITE_MIN_WIDTH,OPEN_GL_SPRITE_MIN_HEIGHT);
97 textureCropRect = cropRect;
99 //NSLog(@"texImage size is %f %f - textureRect.size is %f %f", [texImage size].width, [texImage size].height, textureRect.size.width, textureRect.size.height);
101 // correct size for texture to a power of two
103 while (textureRect.size.width < [texImage size].width)
104 textureRect.size.width *= 2;
105 while (textureRect.size.height < [texImage size].height)
106 textureRect.size.height *= 2;
108 while (textureRect.size.width < cropRect.size.width)
109 textureRect.size.width *= 2;
110 while (textureRect.size.height < cropRect.size.height)
111 textureRect.size.height *= 2;
113 textureRect.origin= NSMakePoint(0,0);
114 textureCropRect.origin= NSMakePoint(0,0);
116 textureSize = textureRect.size;
118 image = [[NSImage alloc] initWithSize:textureRect.size];
121 [[NSColor clearColor] set];
122 NSRectFill(textureRect);
123 [texImage drawInRect:textureCropRect fromRect:cropRect operation:NSCompositeSourceOver fraction:1.0];
124 bitmapImageRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:textureRect];
128 // normalise textureCropRect size to 0.0 -> 1.0
129 textureCropRect.size.width /= textureRect.size.width;
130 textureCropRect.size.height /= textureRect.size.height;
132 //NSLog(@"Texture has :\n%d bitsPerPixel\n%d bytesPerPlane\n%d bytesPerRow",[bitmapImageRep bitsPerPixel],[bitmapImageRep bytesPerPlane],[bitmapImageRep bytesPerRow]);
133 //NSLog(@"Texture is :\n%f x %f pixels, using %f x %f",textureRect.size.width,textureRect.size.height,textureCropRect.size.width,textureCropRect.size.height);
136 [textureData autorelease];
137 textureData = [[NSData dataWithBytes:[bitmapImageRep bitmapData] length:textureRect.size.width*textureRect.size.height*4] retain];
138 [bitmapImageRep release];
140 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
141 glGenTextures(1, &texName); // get a new unique texture name
142 glBindTexture(GL_TEXTURE_2D, texName); // initialise it
144 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
145 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
146 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
147 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
149 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureRect.size.width, textureRect.size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, [textureData bytes]);
153 - (void)replaceTextureFromImage:(NSImage *)texImage cropRectangle:(NSRect)cropRect
155 NSBitmapImageRep* bitmapImageRep;
156 NSRect textureRect = NSMakeRect(0.0,0.0,OPEN_GL_SPRITE_MIN_WIDTH,OPEN_GL_SPRITE_MIN_HEIGHT);
162 textureCropRect = cropRect;
164 //NSLog(@"texImage size is %f %f - textureRect.size is %f %f", [texImage size].width, [texImage size].height, textureRect.size.width, textureRect.size.height);
166 // correct size for texture to a power of two
167 while (textureRect.size.width < cropRect.size.width)
168 textureRect.size.width *= 2;
169 while (textureRect.size.height < cropRect.size.height)
170 textureRect.size.height *= 2;
172 if ((textureRect.size.width != textureSize.width)||(textureRect.size.height != textureSize.height))
174 NSLog(@"ERROR! replacement texture isn't the same size as original texture");
175 NSLog(@"cropRect %f x %f textureSize %f x %f",textureRect.size.width, textureRect.size.height, textureSize.width, textureSize.height);
179 textureRect.origin= NSMakePoint(0,0);
180 //textureRect.size = textureSize;
181 textureCropRect.origin= NSMakePoint(0,0);
183 image = [[NSImage alloc] initWithSize:textureRect.size];
186 [[NSColor clearColor] set];
187 NSRectFill(textureRect);
188 [texImage drawInRect:textureCropRect fromRect:cropRect operation:NSCompositeSourceOver fraction:1.0];
189 bitmapImageRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:textureRect];
193 // normalise textureCropRect size to 0.0 -> 1.0
194 textureCropRect.size.width /= textureRect.size.width;
195 textureCropRect.size.height /= textureRect.size.height;
197 //NSLog(@"Texture has :\n%d bitsPerPixel\n%d bytesPerPlane\n%d bytesPerRow",[bitmapImageRep bitsPerPixel],[bitmapImageRep bytesPerPlane],[bitmapImageRep bytesPerRow]);
198 //NSLog(@"Texture is :\n%f x %f pixels, using %f x %f",textureRect.size.width,textureRect.size.height,textureCropRect.size.width,textureCropRect.size.height);
201 [textureData autorelease];
202 textureData = [[NSData dataWithBytes:[bitmapImageRep bitmapData] length:textureSize.width*textureSize.height*4] retain];
203 [bitmapImageRep release];
205 glBindTexture(GL_TEXTURE_2D, texName);
207 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, textureSize.width, textureSize.height, GL_RGBA, GL_UNSIGNED_BYTE, [textureData bytes]);
211 - (void)substituteTextureFromImage:(NSImage *)texImage
213 NSBitmapImageRep* bitmapImageRep;
214 NSRect cropRect = NSMakeRect(0.0,0.0,[texImage size].width,[texImage size].height);
215 NSRect textureRect = NSMakeRect(0.0,0.0,textureSize.width,textureSize.height);
221 image = [[NSImage alloc] initWithSize:textureSize];
224 [[NSColor clearColor] set];
225 NSRectFill(textureRect);
226 [texImage drawInRect:textureRect fromRect:cropRect operation:NSCompositeSourceOver fraction:1.0];
227 bitmapImageRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:textureRect];
231 // normalise textureCropRect size to 0.0 -> 1.0
232 textureCropRect = NSMakeRect(0.0,0.0,1.0,1.0);
234 //NSLog(@"Texture has :\n%d bitsPerPixel\n%d bytesPerPlane\n%d bytesPerRow",[bitmapImageRep bitsPerPixel],[bitmapImageRep bytesPerPlane],[bitmapImageRep bytesPerRow]);
235 //NSLog(@"Texture is :\n%f x %f pixels, using %f x %f",textureRect.size.width,textureRect.size.height,textureCropRect.size.width,textureCropRect.size.height);
237 if ([bitmapImageRep bitsPerPixel]==32)
240 [textureData autorelease];
241 textureData = [[NSData dataWithBytes:[bitmapImageRep bitmapData] length:textureSize.width*textureSize.height*4] retain];
243 glBindTexture(GL_TEXTURE_2D, texName);
245 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, textureSize.width, textureSize.height, GL_RGBA, GL_UNSIGNED_BYTE, [textureData bytes]);
247 else if ([bitmapImageRep bitsPerPixel]==24)
250 [textureData autorelease];
251 textureData = [[NSData dataWithBytes:[bitmapImageRep bitmapData] length:textureSize.width*textureSize.height*3] retain];
253 glBindTexture(GL_TEXTURE_2D, texName);
255 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, textureSize.width, textureSize.height, GL_RGB, GL_UNSIGNED_BYTE, [textureData bytes]);
257 [bitmapImageRep release];