256 lines
6.5 KiB
Plaintext
256 lines
6.5 KiB
Plaintext
#include "stdafx.h"
|
|
#include "GameEngine.h"
|
|
|
|
#import "glstringosx.h"
|
|
|
|
// GLString follows
|
|
|
|
@implementation GLString
|
|
|
|
- (void) deleteTexture
|
|
{
|
|
if (texName && cgl_ctx) {
|
|
(*cgl_ctx->disp.delete_textures)(cgl_ctx->rend, 1, &texName);
|
|
texName = 0; // ensure it is zeroed for failure cases
|
|
cgl_ctx = 0;
|
|
}
|
|
}
|
|
|
|
- (void) dealloc
|
|
{
|
|
[self deleteTexture];
|
|
[textColor release];
|
|
[string release];
|
|
[super dealloc];
|
|
}
|
|
|
|
// designated initializer
|
|
- (id) initWithString:(NSString *)aString withFont:(NSFont *) inFont withTextColor:(NSColor *)color inBox:(NSRect *)box withFlags:(uint32_t) inFlags
|
|
{
|
|
[super init];
|
|
cgl_ctx = NULL;
|
|
texName = 0;
|
|
texSize.width = 0.0f;
|
|
texSize.height = 0.0f;
|
|
|
|
[color retain];
|
|
textColor = color;
|
|
|
|
[inFont retain];
|
|
font = inFont;
|
|
|
|
flags = inFlags;
|
|
|
|
NSMutableDictionary *attribs = [NSMutableDictionary dictionary];
|
|
[attribs setObject: font forKey: NSFontAttributeName];
|
|
[attribs setObject: textColor forKey: NSForegroundColorAttributeName];
|
|
|
|
string = [[NSAttributedString alloc] initWithString:aString attributes:attribs];
|
|
|
|
border = *box;
|
|
|
|
requiresUpdate = YES;
|
|
return self;
|
|
}
|
|
|
|
- (void) setFont:(NSFont *)inFont
|
|
{
|
|
if ( [font isEqual: inFont] )
|
|
return;
|
|
|
|
[string release];
|
|
[font release];
|
|
|
|
[inFont retain];
|
|
font = inFont;
|
|
|
|
NSMutableDictionary *attribs = [NSMutableDictionary dictionary];
|
|
[attribs setObject: font forKey: NSFontAttributeName];
|
|
[attribs setObject: textColor forKey: NSForegroundColorAttributeName];
|
|
|
|
string = [[NSAttributedString alloc] initWithString:[string string] attributes:attribs];
|
|
|
|
requiresUpdate = YES;
|
|
}
|
|
|
|
- (void) setColor:(NSColor *)color
|
|
{
|
|
if ( [textColor isEqual:color] )
|
|
return;
|
|
|
|
[string release];
|
|
[textColor release];
|
|
|
|
[color retain];
|
|
textColor = color;
|
|
|
|
NSMutableDictionary *attribs = [NSMutableDictionary dictionary];
|
|
[attribs setObject: font forKey: NSFontAttributeName];
|
|
[attribs setObject: textColor forKey: NSForegroundColorAttributeName];
|
|
|
|
string = [[NSAttributedString alloc] initWithString:[string string] attributes:attribs];
|
|
|
|
requiresUpdate = YES;
|
|
}
|
|
|
|
- (void) setBox:(NSRect *)box
|
|
{
|
|
if ( NSEqualRects(border, *box ) )
|
|
return;
|
|
|
|
border = *box;
|
|
requiresUpdate = YES;
|
|
}
|
|
|
|
- (void) setFlags:(uint32_t) inFlags
|
|
{
|
|
if ( inFlags == flags )
|
|
return;
|
|
|
|
flags = inFlags;
|
|
requiresUpdate = YES;
|
|
}
|
|
|
|
|
|
// generates the texture without drawing texture to current context
|
|
- (void) genTexture
|
|
{
|
|
NSSize previousSize = texSize;
|
|
|
|
NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
|
|
pixelsWide:border.size.width
|
|
pixelsHigh:border.size.height
|
|
bitsPerSample:8
|
|
samplesPerPixel:4
|
|
hasAlpha:YES
|
|
isPlanar:NO
|
|
colorSpaceName:NSCalibratedRGBColorSpace
|
|
bytesPerRow:border.size.width * 4
|
|
bitsPerPixel:0];
|
|
|
|
[textColor set];
|
|
|
|
float x = 0.0f;
|
|
float y = (border.size.height - [string size].height)/2;
|
|
|
|
if ( flags & TEXTPOS_CENTER )
|
|
x = (border.size.width - [string size].width)/2;
|
|
else if ( flags & TEXTPOS_RIGHT )
|
|
x = border.size.width - [string size].width;
|
|
|
|
[NSGraphicsContext saveGraphicsState];
|
|
NSGraphicsContext *context = [NSGraphicsContext graphicsContextWithBitmapImageRep:bitmap];
|
|
[context setShouldAntialias:YES];
|
|
[NSGraphicsContext setCurrentContext:context];
|
|
|
|
[string drawAtPoint:NSMakePoint(x, y)]; // draw at offset position
|
|
|
|
[NSGraphicsContext restoreGraphicsState];
|
|
|
|
texSize.width = [bitmap pixelsWide];
|
|
texSize.height = [bitmap pixelsHigh];
|
|
|
|
if ( (cgl_ctx = CGLGetCurrentContext () ) )
|
|
{ // if we successfully retrieve a current context (required)
|
|
glPushAttrib(GL_TEXTURE_BIT);
|
|
if (0 == texName) glGenTextures (1, &texName);
|
|
glBindTexture (GL_TEXTURE_RECTANGLE_EXT, texName);
|
|
if (NSEqualSizes(previousSize, texSize)) {
|
|
glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, texSize.width, texSize.height, [bitmap hasAlpha] ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, [bitmap bitmapData]);
|
|
} else {
|
|
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, texSize.width, texSize.height, 0, [bitmap hasAlpha] ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, [bitmap bitmapData]);
|
|
}
|
|
glPopAttrib();
|
|
}
|
|
else
|
|
{
|
|
NSLog (@"-genTexture: Failure to get current OpenGL context\n");
|
|
|
|
}
|
|
[bitmap release];
|
|
|
|
requiresUpdate = NO;
|
|
}
|
|
|
|
- (GLuint) texName
|
|
{
|
|
return texName;
|
|
}
|
|
|
|
- (NSSize) texSize
|
|
{
|
|
return texSize;
|
|
}
|
|
|
|
- (void) setTextColor:(NSColor *)color // set default text color
|
|
{
|
|
[color retain];
|
|
[textColor release];
|
|
textColor = color;
|
|
requiresUpdate = YES;
|
|
}
|
|
|
|
- (NSColor *) textColor
|
|
{
|
|
return textColor;
|
|
}
|
|
|
|
- (NSRect) border
|
|
{
|
|
return border;
|
|
}
|
|
|
|
- (NSFont *)font
|
|
{
|
|
return font;
|
|
}
|
|
|
|
- (uint32_t) flags
|
|
{
|
|
return flags;
|
|
}
|
|
|
|
- (void) drawWithBounds:(NSRect)bounds
|
|
{
|
|
if (requiresUpdate)
|
|
[self genTexture];
|
|
if (texName)
|
|
{
|
|
glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT); // GL_COLOR_BUFFER_BIT for glBlendFunc, GL_ENABLE_BIT for glEnable / glDisable
|
|
|
|
glDisable (GL_DEPTH_TEST); // ensure text is not remove by depth buffer test.
|
|
glEnable (GL_BLEND); // for text fading
|
|
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // ditto
|
|
glEnable (GL_TEXTURE_RECTANGLE_EXT);
|
|
|
|
glBindTexture (GL_TEXTURE_RECTANGLE_EXT, texName);
|
|
glBegin (GL_QUADS);
|
|
glTexCoord2f (0.0f, 0.0f); // draw upper left in world coordinates
|
|
glVertex2f (bounds.origin.x, bounds.origin.y);
|
|
|
|
glTexCoord2f (0.0f, texSize.height); // draw lower left in world coordinates
|
|
glVertex2f (bounds.origin.x, bounds.origin.y + bounds.size.height);
|
|
|
|
glTexCoord2f (texSize.width, texSize.height); // draw upper right in world coordinates
|
|
glVertex2f (bounds.origin.x + bounds.size.width, bounds.origin.y + bounds.size.height);
|
|
|
|
glTexCoord2f (texSize.width, 0.0f); // draw lower right in world coordinates
|
|
glVertex2f (bounds.origin.x + bounds.size.width, bounds.origin.y);
|
|
glEnd ();
|
|
|
|
glPopAttrib();
|
|
}
|
|
}
|
|
|
|
- (void) drawAtPoint:(NSPoint)point
|
|
{
|
|
if (requiresUpdate)
|
|
[self genTexture]; // ensure size is calculated for bounds
|
|
if (texName) // if successful
|
|
[self drawWithBounds:NSMakeRect (point.x, point.y, texSize.width, texSize.height)];
|
|
}
|
|
|
|
@end
|