set Gem._state as property
[exterlulz-kokogems.git] / src / OpenGLSprite.m
blob42e2ecd4e3dbba19ae841c96428d07d52677b3b5
1 //
2 //  OpenGLSprite.m
3 //  GL_BotChallenge
4 //
5 //  Created by Giles Williams on Fri Jun 21 2002.
6 //  Copyright (c) 2001 __MyCompanyName__. All rights reserved.
7 //
9 #import "OpenGLSprite.h"
12 @implementation OpenGLSprite
14 - (id) init
16     self = [super init];
17     return self;
20 - (id) initWithImage:(NSImage *)textureImage cropRectangle:(NSRect)cropRect size:(NSSize) spriteSize
22     self = [super init];
23     [self makeTextureFromImage:textureImage cropRectangle:cropRect size:spriteSize];
24     return self;
28 - (void) dealloc
30     const GLuint        delTextures[1] = { texName };
31     glDeleteTextures(1, delTextures);   // clean up the texture from the 3d card's memory
32     if (textureData)
33         [textureData release];
34     [super dealloc];
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);
42     glBegin(GL_QUADS);
44     glTexCoord2f(0.0, 1.0-textureCropRect.size.height);
45     glVertex3f(x, y+size.height, z);
47     glTexCoord2f(0.0, 1.0);
48     glVertex3f(x, y, z);
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);
56     glEnd();
57     glDisable(GL_TEXTURE_2D);
60 - (void)blitToX:(float)x Y:(float)y Z:(float)z Alpha:(float)a
62     if (a < 0.0)
63         a = 0.0;        // clamp the alpha value
64     if (a > 1.0)
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);
70     glBegin(GL_QUADS);
72     glTexCoord2f(0.0, 1.0-textureCropRect.size.height);
73     glVertex3f(x, y+size.height, z);
75     glTexCoord2f(0.0, 1.0);
76     glVertex3f(x, y, z);
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);
84     glEnd();
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);
92     NSImage*            image;
94     if (!texImage)
95         return;
97     size = spriteSize;
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;
113     
114     textureRect.origin= NSMakePoint(0,0);
115     textureCropRect.origin= NSMakePoint(0,0);
117     textureSize = textureRect.size;
119     image = [[NSImage alloc] initWithSize:textureRect.size];
121     [image lockFocus];
122     [[NSColor clearColor] set];
123     NSRectFill(textureRect);
124     [texImage drawInRect:textureCropRect fromRect:cropRect operation:NSCompositeSourceOver fraction:1.0];
125     bitmapImageRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:textureRect];
126     [image unlockFocus];
128     [image release];
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);
136     if (textureData)
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);
158     NSImage*            image;
160     if (!texImage)
161         return;
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))
174     {
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);
177         return;
178     }
180     textureRect.origin= NSMakePoint(0,0);
181     //textureRect.size = textureSize;
182     textureCropRect.origin= NSMakePoint(0,0);
184     image = [[NSImage alloc] initWithSize:textureRect.size];
186     [image lockFocus];
187     [[NSColor clearColor] set];
188     NSRectFill(textureRect);
189     [texImage drawInRect:textureCropRect fromRect:cropRect operation:NSCompositeSourceOver fraction:1.0];
190     bitmapImageRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:textureRect];
191     [image unlockFocus];
193     [image release];
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);
201     if (textureData)
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);
217     NSImage*            image;
219     if (!texImage)
220         return;
222     image = [[NSImage alloc] initWithSize:textureSize];
224     [image lockFocus];
225     [[NSColor clearColor] set];
226     NSRectFill(textureRect);
227     [texImage drawInRect:textureRect fromRect:cropRect operation:NSCompositeSourceOver fraction:1.0];
228     bitmapImageRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:textureRect];
229     [image unlockFocus];
231     [image release];
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)
239     {
240         if (textureData)
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]);
247     }
248     else if ([bitmapImageRep bitsPerPixel]==24)
249     {
250         if (textureData)
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]);
257     }
258     [bitmapImageRep release];
261 @end