Texture Mapping: Loading a texture from a .bmp file?
I'm on OSX 10.4.11
I have a 900 MHz PowerPC G3 (laptop)
I'm trying to create a texture from a .bmp file to slap on a openGL quad in the hopes of moving twords creating a simple game using GLUT, openGL, and my knowledge of c++
I am trying to avoid using Cocoa just because of all the effort I've put into trying to learn c++. I have spent a solid month trying to get image data from a url, load it to memory and slap it onto a quad. I haven't found any documentation on how to get this to work without using Objective-c, so I have been reading "Quartz 2D Graphics for mac developers" and the "Red Book" and going through XCode's documentation files, and developer.apple.com files in hopes of finding the answer, all to no avail.
Here is my most recent attempt. I've been using the code I found on onesadcookie's blog about GLUT, and some of NeHe's bits of code smashed with random quartz code trying to get an image reference from a file. I've made no attempt at making clean organized well commented code because I just wanted to slap together a quick project so I could just understand the syntax of loading textures.
XCode gives me a warning "Initialization from incompatible pointer type when I try to call CFStringRef url = "MGspriteszed.bmp";
I was wondering if there is no way to do this with out resorting to Objective-C if I there is a universal imageIO framework I could use with out needing learn obj-c.
I have a 900 MHz PowerPC G3 (laptop)
I'm trying to create a texture from a .bmp file to slap on a openGL quad in the hopes of moving twords creating a simple game using GLUT, openGL, and my knowledge of c++
I am trying to avoid using Cocoa just because of all the effort I've put into trying to learn c++. I have spent a solid month trying to get image data from a url, load it to memory and slap it onto a quad. I haven't found any documentation on how to get this to work without using Objective-c, so I have been reading "Quartz 2D Graphics for mac developers" and the "Red Book" and going through XCode's documentation files, and developer.apple.com files in hopes of finding the answer, all to no avail.
Here is my most recent attempt. I've been using the code I found on onesadcookie's blog about GLUT, and some of NeHe's bits of code smashed with random quartz code trying to get an image reference from a file. I've made no attempt at making clean organized well commented code because I just wanted to slap together a quick project so I could just understand the syntax of loading textures.
Code:
#include <Carbon/Carbon.h>
#include <stdlib.h>
#include <GLUT/glut.h>
#include <ApplicationServices/ApplicationServices.h>
GLuint myTextureName;
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
CFStringRef url = "MGspriteszed.bmp";
CFURLRef imageurl = CFURLCreateWithString (NULL, url, NULL);
CGImageSourceRef myImageSourceRef = CGImageSourceCreateWithURL(imageurl, NULL);
CGImageRef myImageRef = CGImageSourceCreateImageAtIndex (myImageSourceRef, 0, NULL);
size_t width = CGImageGetWidth(myImageRef);
size_t height = CGImageGetHeight(myImageRef);
CGRect rect = {{0, 0}, {width, height}};
void * myData = calloc(width * 4, height);
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
CGContextRef myBitmapContext = CGBitmapContextCreate (myData,
width, height, 8,
width*4, space,
kCGBitmapByteOrder32Host |
kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(myBitmapContext, rect, myImageRef);
CGContextRelease(myBitmapContext);
glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &myTextureName);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, myTextureName);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, width, height,
0, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, myData);
free(myData);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBindTexture(GL_TEXTURE_2D, myTextureName);
glTranslatef(0.0, 0.0, 0.0);
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVector3f(0.0, 0.0, 0.0);
glTexCoord2f(1.0, 0.0); glVector3f(0.25, 0.0, 0.0);
glTexCoord2f(1.0, 1.0); glVector3f(0.25, 0.25, 0.0);
glTexCoord2f(0.0, 1.0); glVector3f(0.0, 0.25, 0.0);
glEnd();
glFlush();
glDisable(GL_TEXTURE_2D);
}
void spinDisplay(void)
{
}
void reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-50.0, 50.0, -50.0, 50.0, -1, -1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowPosition(200, 180);
glutInitWindowSize(640, 480);
glutCreateWindow("New Window");
init();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMainLoop();
return EXIT_SUCCESS;
}
XCode gives me a warning "Initialization from incompatible pointer type when I try to call CFStringRef url = "MGspriteszed.bmp";
I was wondering if there is no way to do this with out resorting to Objective-C if I there is a universal imageIO framework I could use with out needing learn obj-c.
ishrock Wrote:XCode gives me a warning "Initialization from incompatible pointer type when I try to call CFStringRef url = "MGspriteszed.bmp";
"MGspriteszed.bmp" is of type char *. You can use CFSTR("MGspriteszed.bmp") to get a compile-time CFStringRef constant.
ishrock Wrote:I was wondering if there is no way to do this with out resorting to Objective-C if I there is a universal imageIO framework I could use with out needing learn obj-c.
Indeed there is: http://developer.apple.com/graphicsimagi...ageio.html
As an aside, learning Objective-C is highly beneficial for developing software on the Mac or iPhone. I'd recommend giving it a try sooner rather than later; it only takes a day or two to get up and running with it.
ObjC is absolutely worth it, even if you're focused on C++ ( as I am, for 3d stuff at least ). By learning ObjC + Cocoa, you can work with the good stuff OSX provides so much easier. So much easier.
Thank you for the help and the references. I can now sleep soundly at night. I got it to pass the texture and load the program with out error (the code I posted had glVector3f instead of glVertex3f) but I still haven't got quad to show up on the screen with the texture. i think the quad is off the screen or flipped around, or some gl rendering thing is active when it shouldn't be. I'll post my code when I hunt down the issue.
My concern when it comes with Objective-C is that all my friends run on Microsoft windows. I would love to be able to port my simple games over to windows eventually (or write a game that would work on both systems in the first place). I fear that by using Obj-c that it might make that more painful in the long run. Is there any validity to this concern?
I like GLUT because it seems straight forward and to the point, but I have heard people on the forum talking about it's limited abilities (Though not saying what those limits are). As a hobbiest I think GLUT will probably be a fine starting point (is it?).
I looked into SDL and it seemed daunting. To me at this point in my programing life, daunting means it's probably awesome and I should learn SDL instead of GLUT.... Should I?
My concern when it comes with Objective-C is that all my friends run on Microsoft windows. I would love to be able to port my simple games over to windows eventually (or write a game that would work on both systems in the first place). I fear that by using Obj-c that it might make that more painful in the long run. Is there any validity to this concern?
I like GLUT because it seems straight forward and to the point, but I have heard people on the forum talking about it's limited abilities (Though not saying what those limits are). As a hobbiest I think GLUT will probably be a fine starting point (is it?).
I looked into SDL and it seemed daunting. To me at this point in my programing life, daunting means it's probably awesome and I should learn SDL instead of GLUT.... Should I?
So i have cleaned up my code a little and added the suggestions ThemsAllTook gave, minus the obj-c. It all compiles fine... except that my quad still has not texture. I just see a white box on a black background. I added a line of code to check it the texture was ever loaded in the first place and it looks like it hasn't.
I have imported the image file, and copied it to my project folder. In XCode I put it in a group named "Resources". I thought I would only need to put the name of the file ("MGspriteszed.bmp") for my program to be able to find it, but it didn't. I also tried ("/Resources/MGspriteszed.bmp"), ("/GL_Test/MGspriteszed.bmp"), ("Desktop/GL_Test/MGspriteszed.bmp")... so on and so forth.
Would any one be able to look at my code and help me out? Maybe i've done something horrible stupid... well... I'm sure I have, but thats why i need the help
I have imported the image file, and copied it to my project folder. In XCode I put it in a group named "Resources". I thought I would only need to put the name of the file ("MGspriteszed.bmp") for my program to be able to find it, but it didn't. I also tried ("/Resources/MGspriteszed.bmp"), ("/GL_Test/MGspriteszed.bmp"), ("Desktop/GL_Test/MGspriteszed.bmp")... so on and so forth.
Would any one be able to look at my code and help me out? Maybe i've done something horrible stupid... well... I'm sure I have, but thats why i need the help

Code:
#include <Carbon/Carbon.h>
#include <stdlib.h>
#include <GLUT/glut.h>
#include <ApplicationServices/ApplicationServices.h>
GLuint myTextureName[1];
CFStringRef GetTextureURL(void) //My function to create a CFStringRef of a URL to a BMP file
{
CFStringRef url = CFSTR("MGspriteszed.bmp");
return url;
}
void LoadTextures( CFStringRef url) // my function to load a BMP for a url into
{ // global GLuint myTextureName[1]
CFURLRef imageurl = CFURLCreateWithString (NULL, url, NULL); //creates URL from a string that was passed into the function
CGImageSourceRef myImageSourceRef = CGImageSourceCreateWithURL(imageurl, NULL); // makes a refrence to the bmp file the url point to
if (myImageSourceRef == NULL) {
exit(TRUE);
};
CGImageRef myImageRef = CGImageSourceCreateImageAtIndex (myImageSourceRef, 0, NULL); // load the bmp data from file and create a refrence to where it is in memory
size_t width = CGImageGetWidth(myImageRef);
size_t height = CGImageGetHeight(myImageRef);
CGRect rect = {{0, 0}, {width, height}};
void * myData = calloc(width * 4, height); // makes sure there is exact space in momory to store bmp data
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
CGContextRef myBitmapContext = CGBitmapContextCreate (myData, // makes off screen bmp context
width, height, 8,
width*4, space,
kCGBitmapByteOrder32Host |
kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(myBitmapContext, rect, myImageRef); // draws my image to somewhere
CGContextRelease(myBitmapContext); //frees memory
glPixelStorei(GL_UNPACK_ROW_LENGTH, width); // does this read the bmp data and prepair to store it
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // as something openGL can read?
glGenTextures(1, &myTextureName[0]); // Tells open gl myTextureName[0] is a place in memory where textures are stored
glBindTexture(GL_TEXTURE_2D, myTextureName[0]); // puts the data from GL_UNPACK into myTextureName[0]
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, //voodoo
0, GL_RGB, GL_UNSIGNED_BYTE, myData);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
free(myData); //frees memory from pointer myData
}
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
CFStringRef url = GetTextureURL(); // get a CFStringRef to file name to pass to LoadTextures
LoadTextures(url); // call to my function to load bmp data with quartz
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, myTextureName[0]); // get ready to use my texture
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.0, 0.0); //bottom left
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, 0.0, 0.0);//top left
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 0.0);//top right
glTexCoord2f(0.0, 1.0); glVertex3f(0.0, 1.0, 0.0); //bottom right
glEnd();
glFlush();
glDisable(GL_TEXTURE_2D);
}
void reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-50.0, 50.0, -50.0, 50.0, -1, -1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowPosition(200, 180);
glutInitWindowSize(640, 480);
glutCreateWindow("New Window");
init();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMainLoop();
return EXIT_SUCCESS;
}
ishrock Wrote:My concern when it comes with Objective-C is that all my friends run on Microsoft windows. I would love to be able to port my simple games over to windows eventually (or write a game that would work on both systems in the first place). I fear that by using Obj-c that it might make that more painful in the long run. Is there any validity to this concern?
There is validity, but using Objective-C isn't mutually exclusive with compiling for Windows. There are ways to compile Objective-C code on other platforms, and although I've never personally been able to get them to work, other iDevGames members have. Another approach, which I'm currently using, is to write the vast majority of your game in C or C++ using only platform-independent APIs, and link it to a small platform-specific shell which is implemented separately for each platform you compile for. This way, all of your Objective-C code would be isolated in a "Mac-only" section, and you'd be able to implement an equivalent "Windows-only" (and "Linux-only", etc.) section in another language.
ishrock Wrote:I like GLUT because it seems straight forward and to the point, but I have heard people on the forum talking about it's limited abilities (Though not saying what those limits are). As a hobbiest I think GLUT will probably be a fine starting point (is it?).
I looked into SDL and it seemed daunting. To me at this point in my programing life, daunting means it's probably awesome and I should learn SDL instead of GLUT.... Should I?
GLUT is a fine place to start, though you may find that you outgrow it. Its event handling API isn't exactly full-featured, and I remember one of our members being unable to get full screen mode working reliably. On the plus side, it's completely cross-platform and very easy to use. If nothing else, it's an excellent starting point to get something up and running quickly, that you can potentially swap out later for something more full-featured.
I haven't used SDL myself, but many other members here swear by it. One caveat to be aware of is that you'll need to bundle the appropriate SDL frameworks with your application when you distribute it, which has historically been the source of many headaches. It also increases the size of your distribution by a few megabytes.
As for the file loading problem, you were barking up the right tree. Here's an explanation from another one of our members: http://blog.onesadcookie.com/2007/12/fin...files.html
Possibly Related Threads...
Thread: | Author | Replies: | Views: | Last Post | |
Mapping 2D texture to multiple GL_TRIANGLES | ardowz | 4 | 8,316 |
Feb 27, 2017 11:09 PM Last Post: Nicolredmay |
|
Rendering Heightmap using texture data | ardowz | 4 | 6,010 |
Nov 17, 2015 03:32 AM Last Post: mark89 |
|
OpenGL ES Texture Masking | airfire | 6 | 22,768 |
Mar 17, 2014 07:07 PM Last Post: baioses |
|
Render to Texture behaves weirdly | ardowz | 2 | 4,864 |
Feb 17, 2014 04:50 PM Last Post: ardowz |
|
Preventing texture from creating transparent gaps on edges | ardowz | 3 | 4,898 |
Jan 21, 2014 11:28 AM Last Post: SethWillits |