OpenGL Image Textures
I am writing an OpenGL game in C, and I feel it would be much better if i could use textures. I have tried to muddle together some libpng stuff, but it's all too complicated.
I can see how to actually write tex coordinates on a quad, but I don't see how to load the image.
I'd be happy with any format bar JPEG or GIF, for obvious reasons.
Can someone help?
Thanks
I can see how to actually write tex coordinates on a quad, but I don't see how to load the image.
I'd be happy with any format bar JPEG or GIF, for obvious reasons.
Can someone help?
Thanks
~ Bring a Pen ~
Yes, I've seen that before, but that makes use of <glaux.h>, which is windows only.
It's not really the actual textures I'm stuck with, it's getting the image into an OpenGL texture.
It's not really the actual textures I'm stuck with, it's getting the image into an OpenGL texture.
~ Bring a Pen ~
Quote:Yes, I've seen that before, but that makes use of <glaux.h>, which is windows only.
There's Mac OS X code at the bottom of every NeHe tutorial.
Also, if you search these forums, Apple examples, and the net in general, you'll find lots of texture loading code. It comes up often.
Yes, I have looked at the OSX code for that tutorial, but I don't understand it, and when I try and copy it, I get loads of errors. As for Apple examples... Well, the amount of code that's not ObjC, and not Legacy is small. Still, I'll look again...
~ Bring a Pen ~
... Nope. Can't find anything that's not C++ or ObjC or Windows or Linux.
Can you help?
Can you help?
~ Bring a Pen ~
Give this a try: http://developer.apple.com/graphicsimagi...ageio.html
If ImageIO doesn't work out, try this: http://www.google.com/search?client=safa...8&oe=UTF-8
If ImageIO doesn't work out, try this: http://www.google.com/search?client=safa...8&oe=UTF-8
Sorry if I seem stupid, but I don't get any of these. The ObjC just confuses things. And I don't even know what CGImage is. I find the Apple code is all too... politically correct, so much so It becomes unreadable.
~ Bring a Pen ~
You can't expect to understand something this involved when you spend less than an hour reading about it. If there's a part of the API that doesn't make sense to you (for example, if you don't know what a CGImage is), look it up in Apple documentation and keep reading until you do understand it. If you don't have the patience or dedication to do that, programming may not be an appropriate hobby for you.
I might put something together.
Sir, e^iπ + 1 = 0, hence God exists; reply!
I've made a tool for putting images into C source code for OpenGL. To compile the tool use:
gcc OpenGLTextureMaker.m -framework Cocoa -o OpenGLTextureMaker
run it like this:
./OpenGLTextureMaker example_image.png > output.txt
fix the output up and then paste it into
and compile that using:
gcc -framework GLUT -framework OpenGL textureexample.c -o textureexample
to see it working.
Edit: Remember to use textures that have dimensions that are powers of two!
gcc OpenGLTextureMaker.m -framework Cocoa -o OpenGLTextureMaker
Code:
#import <Cocoa/Cocoa.h>
#define ensure(conditional, error) if(!(conditional)) { NSLog(error); return 0; }
#define nl puts("");
#define indent printf(" ");
void datadump(int n, unsigned char * data) {
printf("{");
while(1) {
printf("0x%X", *data);
if(--n) printf(", ");
else break;
data++;
}
printf("};");
nl;
}
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
ensure(argc == 2, @"Provide an image as the command line parameter");
NSBitmapImageRep * im =
[[NSBitmapImageRep alloc]
initWithData:
[NSData dataWithContentsOfFile:[NSString stringWithUTF8String:argv[1]]]];
ensure(im, @"Image not found or invalid");
ensure([im samplesPerPixel] == 3, @"Image has more (or less) than 3 channels");
ensure([im bitsPerPixel] == 3*8, @"Image has more than one byte per channel");
printf("void $name_texture() {"); nl;
indent; printf("unsigned char $name_texture_data[] ="); nl;
datadump([im pixelsWide] * [im pixelsHigh] * 3, [im bitmapData]);
indent; printf("glTexImage2D(GL_TEXTURE_2D,"); nl;
indent; printf(" 0,"); nl;
indent; printf(" 3,"); nl; // or maybe 4?
indent; printf(" %d,", [im pixelsWide]); nl;
indent; printf(" %d,", [im pixelsHigh]); nl;
indent; printf(" 0,"); nl;
indent; printf(" GL_RGB,"); nl; // or maybe RGBA?
indent; printf(" GL_UNSIGNED_BYTE,"); nl;
indent; printf(" $name_texture_data);"); nl;
indent; printf("glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);"); nl;
indent; printf("glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);"); nl;
printf("}"); nl;
[pool drain];
return 0;
}run it like this:
./OpenGLTextureMaker example_image.png > output.txt
fix the output up and then paste it into
Code:
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <GLUT/glut.h>
/// SNIP
// paste the program output here
/// SNIP
void display(void) {
glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1,1,1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
example_texture();
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2f(-1,-1);
glTexCoord2f(1, 0);
glVertex2f( 1,-1);
glTexCoord2f(1, 1);
glVertex2f( 1, 1);
glTexCoord2f(0, 1);
glVertex2f(-1, 1);
glEnd();
glutSwapBuffers();
}
int main(int argc, char ** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(512,512);
glutCreateWindow("texture example");
glutDisplayFunc(display);
glutMainLoop();
return 0;
}and compile that using:
gcc -framework GLUT -framework OpenGL textureexample.c -o textureexample
to see it working.
Edit: Remember to use textures that have dimensions that are powers of two!
Sir, e^iπ + 1 = 0, hence God exists; reply!
mikey Wrote:Yes, I have looked at the OSX code for that tutorial, but I don't understand it
Which is normally where you ask a question about the code, not ask for different code. What makes you think you'll understand different code anymore than the working code you've already seen?
Quote:and when I try and copy it, I get loads of errors.
Well, that's your fault, not the code's.

And again, this would be something you'd ask a question about. You're clearly missing something important and relevant that you'd likely miss with any other code.
Quote:As for Apple examples... Well, the amount of code that's not ObjC, and not Legacy is small.
Likability/usefulness of specific APIs aside, there's no reason to avoid Obj-C just because it's "not C". You can easily use the two together, and having platform-specific code in a cross platform app is common. The language shouldn't be an issue.
And there's always third party code like SDL_image that you could use.
Thankyou very much unknown! 




FreakSoftware:
Yes, you're probably right. Thanks anyway though.
You're right. I'm rushing. Thanks.





FreakSoftware:
Yes, you're probably right. Thanks anyway though.

Quote:You can't expect to understand something this involved when you spend less than an hour reading about it. If there's a part of the API that doesn't make sense to you (for example, if you don't know what a CGImage is), look it up in Apple documentation and keep reading until you do understand it. If you don't have the patience or dedication to do that, programming may not be an appropriate hobby for you.
You're right. I'm rushing. Thanks.
~ Bring a Pen ~
[INDENT]I've been researching this topic for a tutorial that I am working on. I am surprised at how little there is currently available on this topic. Here are my findings:[/INDENT]
[INDENT] In the Apple sample code there is the Texture2D class that will load an image as a texture, resize it as needed, invert it, and display it on a quad. The problem is that it freely mixes OpenGL with Objective-C, which makes it very fragile and problematic for beginners. Then there is the image loading code from the GLSprite sample code, which is easier to understand, but also rather fragile since it requires that the source image be in the right format and a power of two size, otherwise nothing will show up onscreen.[/INDENT]
In the end, I came up with this hybrid code:
which loads an image that can then be draw using something like this:
[INDENT]While this also mixes OpenGL and Objective-C and is not very robust in dealing with image formats, it nevertheless is easier for a beginner to understand. You can see that Core Graphics calls are being used to load the image data into memory, which is then passed as a pointer (spriteData) to OpenGL, which then takes over the responsibility for getting it to appear onscreen.[/INDENT]
[INDENT] In the Apple sample code there is the Texture2D class that will load an image as a texture, resize it as needed, invert it, and display it on a quad. The problem is that it freely mixes OpenGL with Objective-C, which makes it very fragile and problematic for beginners. Then there is the image loading code from the GLSprite sample code, which is easier to understand, but also rather fragile since it requires that the source image be in the right format and a power of two size, otherwise nothing will show up onscreen.[/INDENT]
In the end, I came up with this hybrid code:
Code:
glGenTextures(1, &textureID);
CGImageRef image;
CGContextRef spriteContext;
GLubyte *spriteData;
size_t width, height;
image = [UIImage imageNamed:@"puck.png"].CGImage;
width = CGImageGetWidth(image);
height = CGImageGetHeight(image);
if(image) {
spriteData = (GLubyte *) malloc(width * height * 4);
spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width * 4, CGImageGetColorSpace(image), kCGImageAlphaPremultipliedLast);
//these next two lines are necessary because the iPhone has its y-axis upside down, so everything looks flipped
CGContextTranslateCTM(spriteContext, 0.0, height); //i.e., move the y-origin from the top to the bottom
CGContextScaleCTM(spriteContext, 1.0, -1.0); //i.e., invert the y-axis
CGContextDrawImage(spriteContext, CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height), image);
CGContextRelease(spriteContext);
glBindTexture(GL_TEXTURE_2D, textureID); // first Bind creates the texture and assigns a numeric name to it
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
free(spriteData);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
}which loads an image that can then be draw using something like this:
Code:
glBindTexture(GL_TEXTURE_2D, textureID);
glVertexPointer(2, GL_FLOAT, 0, puckVertices);
glTexCoordPointer(2, GL_SHORT, 0, texCoords);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);//actually draw something on the screen
Why are you enabling blending?
Also, please hoist the line that sets GL_TEXTURE_MIN_FILTER to occur before the call to glTexImage2D. It is correct either way, but setting the min filter before creating texture level 0 may allow GL to operate more efficiently.
Also, please hoist the line that sets GL_TEXTURE_MIN_FILTER to occur before the call to glTexImage2D. It is correct either way, but setting the min filter before creating texture level 0 may allow GL to operate more efficiently.
Possibly Related Threads...
| Thread: | Author | Replies: | Views: | Last Post | |
| [SOLVED]OpenGL edges of textures | mk12 | 2 | 3,628 |
Sep 2, 2010 08:07 PM Last Post: mk12 |
|
| Dealing with inverted textures in OpenGL | johncmurphy | 7 | 5,861 |
Jun 15, 2009 08:11 AM Last Post: Skorche |
|
| Using textures OpenGL switches to software renderer | bruno | 2 | 3,111 |
Oct 12, 2008 03:06 AM Last Post: bruno |
|
| Loading and using textures with alpha in OpenGL with Cocoa | corporatenewt | 4 | 5,080 |
Dec 8, 2007 02:06 PM Last Post: Malarkey |
|
| loading textures - cocoa openGL | mDmarco | 20 | 8,333 |
Aug 28, 2007 08:48 PM Last Post: OneSadCookie |
|

