Hey I've a got 2D game going on. I used SDL and also OpenGL. For loading images I always use .TGA's and I load them myself with code I mostly took from NeHe's site. It's like this:
I declare this data type:
struct TextureImage
{
GLubyte *imageData;
GLuint bpp;
GLuint width;
GLuint height;
GLuint texID;
};
Then I declare some variable:
Then I declare this function:
bool LoadTGA(TextureImage *texture, string &filename)
{
GLubyte TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0};
GLubyte TGAcompare[12];
GLubyte header[6];
GLuint bytesPerPixel;
GLuint imageSize;
GLuint temp;
GLuint type=GL_RGBA;
FILE *file = fopen(filename.c_str(), "rb");
if(file==NULL||
fread(TGAcompare,1,sizeof(TGAcompare),file)!=sizeof(TGAcompare)||
memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0||
fread(header,1,sizeof(header),file)!=sizeof(header))
{
if(file!=NULL)
fclose(file);
return false;
}
texture->width = header[1] * 256 + header[0];
texture->height = header[3] * 256 + header[2];
if(texture->width<=0||texture->height<=0||(header[4]!=24 && header[4]!=32))
{
fclose(file);
return false;
}
texture->bpp=header[4];
bytesPerPixel=texture->bpp/8;
imageSize=texture->width*texture->height*bytesPerPixel;
texture->imageData = (GLubyte *)malloc(imageSize); //Ah, malloc, C's answer to "new". So when is this memory freed?
//you have to free it yourself NeHe has a Deinitialize function
if(texture->imageData==NULL||fread(texture->imageData, 1, imageSize, file)!=imageSize)
{
if(texture->imageData!=NULL)
{
free(texture->imageData); //well, I guess this is how you free it
texture->imageData = NULL;
}
fclose(file);
return false;
}
//for a fun time comment this out
for(GLuint i=0; i<(unsigned int)imageSize; i+=bytesPerPixel)
{
temp=texture->imageData;
texture->imageData = texture->imageData;
texture->imageData = temp;
}
fclose (file);
<span class="cpp-comment">// Build A Texture From The Data</span>
glGenTextures(<span class="cpp-number">1</span>, &texture[<span class="cpp-number">0</span>].texID); <span class="cpp-comment">//texture is a pointer to a TextureImage</span>
<span class="cpp-comment">//why not just texture.texID? why &texture[0]?? wtf</span>
<span class="cpp-comment">//the the address of a pointer? the first element of it? it has no elements, wtf?</span>
<span class="cpp-comment">//wtf could [0] possibly mean?</span>
<span class="cpp-comment">//oh I remember, you use -> for pointers instead of . like above</span>
<span class="cpp-comment">//so here he wants to use . so maybe ampersand on a pointer "converts" it back to a regular data type?</span>
<span class="cpp-comment">//I have no idea what's going on</span>
glBindTexture(GL_TEXTURE_2D, texture[<span class="cpp-number">0</span>].texID); <span class="cpp-comment">//And here it needs no ampersand. Why? I don't know.</span>
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
<span class="cpp-keyword">if</span>(texture[<span class="cpp-number">0</span>].bpp==<span class="cpp-number">24</span>)
{
type=GL_RGB;
}
<span class="cpp-comment">//Here using . instead of -> so maybe [0] takes care of it? Then why the ampersand above?</span>
glTexImage2D(GL_TEXTURE_2D, <span class="cpp-number">0</span>, type, texture[<span class="cpp-number">0</span>].width, texture[<span class="cpp-number">0</span>].height,<span class="cpp-number">0</span>, type, GL_UNSIGNED_BYTE, texture[<span class="cpp-number">0</span>].imageData);
<span class="cpp-keyword">return</span> <span class="cpp-keyword">true</span>;
}
</pre></div><!–ENDSCRIPT–>
So now I pass *whatever to that function along with the name of a .tga file and I can bind *whatever whenver I want and slap on some quads.
<!–STARTSCRIPT–><!–source lang="cpp"–><div class="source"><pre>
glBindTexture(GL_TEXTURE_2D, whatever.texID);
glBegin(GL_POLYGON);
glTexCoord2f(<span class="cpp-number">0</span>.<span class="cpp-number">0</span>,<span class="cpp-number">1</span>.<span class="cpp-number">0</span>); glVertex3f(<span class="cpp-number">0</span>,<span class="cpp-number">768</span>,<span class="cpp-number">0</span>.<span class="cpp-number">0</span>);
glTexCoord2f(<span class="cpp-number">1</span>.<span class="cpp-number">0</span>,<span class="cpp-number">1</span>.<span class="cpp-number">0</span>); glVertex3f(<span class="cpp-number">1024</span>,<span class="cpp-number">768</span>,<span class="cpp-number">0</span>.<span class="cpp-number">0</span>);
glTexCoord2f(<span class="cpp-number">1</span>.<span class="cpp-number">0</span>,<span class="cpp-number">0</span>.<span class="cpp-number">0</span>); glVertex3f(<span class="cpp-number">1024</span>,<span class="cpp-number">0</span>,<span class="cpp-number">0</span>.<span class="cpp-number">0</span>);
glTexCoord2f(<span class="cpp-number">0</span>.<span class="cpp-number">0</span>,<span class="cpp-number">0</span>.<span class="cpp-number">0</span>); glVertex3f(<span class="cpp-number">0</span>,<span class="cpp-number">0</span>,<span class="cpp-number">0</span>.<span class="cpp-number">0</span>);
glEnd();
</pre></div><!–ENDSCRIPT–>
But TGA's always take up a few trillion terrabytes and no one's used them since Fred Flintstone so I want to start loading .PNG's instead.
I want to use SDL_image loader and using SDL_image loader for an SDL game is easy enough except I want it to load the PNG into a data type that I can bind to an OpenGL texture like I'm doing above with .tga's.
I cannot find how to do this. I don't think it would take more than a page of code, I figured there would be something out there I could just block copy and figure out later but I can't find anything. I don't know why, lots of people have probably loaded .png's with SDL_image and textured OpenGL quads with them.