OpenGL Texture not displaying - my first class.
Well, I just started messing around with OOP classes, and so far I've found them to be pretty cool. As my first, I figured I'd start with something relatively simple: A form of SDL_Surface, but for OpenGL. It uses DevIL and OpenGL. Unfortunatly, my texture does not appear.
I've actually posted a thread about this over at gameDev, but then I realized. Oh wait... what am I doing? It's the mac users that are the smart ones, I'll ask them.
Here's the other thread, for reference.
What I've tried:
- Binding the texture directly from IL, instead of from my class variables. (When drawing.)
- Inserting little warning tags after every action. (Showed no problems.)
- Swapping up the vertex ordering of the texture grabbing.
No luck, anyhow. Here's my class:
(Feel free to tell me how useless it is!
)
Thanks for any help you can give!
I've actually posted a thread about this over at gameDev, but then I realized. Oh wait... what am I doing? It's the mac users that are the smart ones, I'll ask them.

Here's the other thread, for reference.
What I've tried:
- Binding the texture directly from IL, instead of from my class variables. (When drawing.)
- Inserting little warning tags after every action. (Showed no problems.)
- Swapping up the vertex ordering of the texture grabbing.
No luck, anyhow. Here's my class:
(Feel free to tell me how useless it is!
)Code:
#include <cstdlib>
#include <cstring>
#include "OpenGL/gl.h"
#include "OpenGL/glu.h"
#include "IL/il.h"
#include "IL/ilu.h"
#include "IL/ilut.h"
using namespace std;
class glSurface {
protected:
GLint components;
GLsizei width;
GLsizei height;
GLenum format;
GLvoid *pixels;
ILuint image_IL;
GLuint texture_GL;
int x;
int y;
int firstDraw;
public:
glSurface();
int Open(char *);
void Position(int, int);
void Draw();
};
glSurface::glSurface() {
ilGenImages(1, &image_IL);
glGenTextures(1, &texture_GL);
firstDraw = 1;
}
int glSurface::Open(char filename[]) {
ILint open_currentBound_IL = ilGetInteger(IL_CUR_IMAGE);
ILboolean open_success_IL;
ilBindImage(image_IL);
open_success_IL = ilLoadImage(filename);
if (open_success_IL == IL_FALSE) {
ilBindImage(open_currentBound_IL);
cout << "Problem!" << endl;
return(-1);
}
components = ilGetInteger(IL_IMAGE_BPP);
width = ilGetInteger(IL_IMAGE_WIDTH);
height = ilGetInteger(IL_IMAGE_HEIGHT);
format = ilGetInteger(IL_IMAGE_FORMAT);
pixels = ilGetData();
ilBindImage(open_currentBound_IL);
return(0);
}
void glSurface::Position(int tx, int ty) {
x = tx;
y = ty;
}
void glSurface::Draw() {
glBindTexture(GL_TEXTURE_2D, texture_GL);
if (firstDraw = 1) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, components, width, height, 0, format, GL_UNSIGNED_BYTE, pixels);
firstDraw = 0;
}
glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex2i(x, y);
glTexCoord2i(0, 1); glVertex2i(x + width, y);
glTexCoord2i(1, 1); glVertex2i(x + width, y + height);
glTexCoord2i(1, 0); glVertex2i(x, y + width);
glEnd();
}Thanks for any help you can give!
I don't know DevIL, so your code might already do this depending on DevIL's setup of surfaces. But remember that OpenGL (afaik) can't load non-power-of-two textures. That might be your problem.
On another note, I am using SDL for loading of OpenGL textures, and loving it. Took some doing to set up, but there's a tutorial (GLtest) in the SDL source code that shows exactly how to do it. If you use SDL at some point instead of DevIL, try it out.
Hope you solve your problem - I hate getting white squares or nothing instead of textures.
On another note, I am using SDL for loading of OpenGL textures, and loving it. Took some doing to set up, but there's a tutorial (GLtest) in the SDL source code that shows exactly how to do it. If you use SDL at some point instead of DevIL, try it out.
Hope you solve your problem - I hate getting white squares or nothing instead of textures.
My Game Dev Page:
http://whindgames.50webs.com/
StressFracture: http://www.sourceforge.net/projects/stressfracture
Everything looks OK, but when you say that the texture doesn't appear - what happens? White square, or nothing? Also, is GL_TEXTURE_2D enabled?
Greywhind Wrote:I don't know DevIL, so your code might already do this depending on DevIL's setup of surfaces. But remember that OpenGL (afaik) can't load non-power-of-two textures. That might be your problem.
That must be the third or forth time I've forgotten that rule. *sigh*
Thanks, my problem should be solved now.
*1 minute later*
Yeah, it's solved... sorta. One problem remains though.
My colors... check out the original tiff:
Now, after load:
![[Image: copter_wtf.png]](http://homepage.mac.com/gareth.cross/copter_wtf.png)
Ignore the rotation, that's actually just a texpos mis-type. But why is it Pink? I'm guessing it's because of some sort of byte ordering error. It's a tif, with transparency, and DevIL should be passing the right format. This *might* be another pixen error, but I viewed it in photoshop and it seemed fine.
The dark blue windows becoming light yellow suggests that you are inverting the RGB channels, although the green/pink area maintains its shadows so this may not be quite right. It could be a little endian/big endian error with the RGB values. Also check you are reading the correct pixel format (not mixing up RGBA with ARGB or something), although I think you are OK on that one.
backslash Wrote:The dark blue windows becoming light yellow suggests that you are inverting the RGB channels, although the green/pink area maintains its shadows so this may not be quite right. It could be a little endian/big endian error with the RGB values. Also check you are reading the correct pixel format (not mixing up RGBA with ARGB or something), although I think you are OK on that one.
That's what I was thinking... might it be my "type" in glTexImage2D? It's set at GL_UNSIGNED_BYTE, perhaps GL_BITMAP or another choice could help...
I also can't get it to be oriented correctly, If I assume that the top-left corner is 0,0 of my texture it looks like the above picture. If I assume that bottom-left corner is 0,0... it's upside down.
I'm gonna take a wild guess and try drawing the from the right corners.Using DevIL, I tried forcing the image to be RGBA with:
Code:
ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);But it remained tinted pink and yellow.
EDIT: Trying to make it any other type results in a type 4 crash.
EDIT 2: I tried making GL use ONLY GL_RGBA isntead of what DevIL gave it, like this:
Code:
glTexImage2D(GL_TEXTURE_2D, 0, components, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);It's still pink.
Grr. I'm gonna try another format besides tif.EDIT 3: Make another go, but with a gif... it just doesn't even draw the quad now! *smashes head against keyboard.* I mean come-on, the image only has like 4 little colors! No blending at all! Argh!
EDIT 4: Well, just noticed something... even if I rotated the image, or changed where it's drawn from, it'll still be backwards. This must be a byte ordering thing, with my tifs and DevIL. Pity, that's the only format I can export too that supports transparency. That and gif, which doesn't load.
Personally, I've always used PNGs. Libpng may not be the easiest library in the world, but the example code is quite good, and you only really have to write this stuff once. Don't feel constrained by only being able to export TIFFs - Preview can convert to many formats (including PNG), and there are plenty of free tools out there.
Anyway...
For your texture coordinates, you should have (0,0) in the top left and (1,0) in the top right. You appear to have the x and y coordinates mixed up between the texture coords and the the polygon coords in the code above. Also, remember that if (0,0) is the bottom left corner of the screen then you need to use y-height for the lower corners. I think this is why you are seeing it backwards - you are actually looking at the back of it.
Anyway...
For your texture coordinates, you should have (0,0) in the top left and (1,0) in the top right. You appear to have the x and y coordinates mixed up between the texture coords and the the polygon coords in the code above. Also, remember that if (0,0) is the bottom left corner of the screen then you need to use y-height for the lower corners. I think this is why you are seeing it backwards - you are actually looking at the back of it.
Wow... it took me a while to get back to this thread.
Anyways:
I'm on PPC, too cheap for an intel one yet.
Anyways, I've got a problem again similar to this one, so I put it in this thread.
I've tried out libpng (again, after leaving it for DevIL) and I wrote a C++ class for using it with OpenGL. It supports error codes, arbitrary sized textures and stuff too. Here's the source:
Here's my main file (simple testing one):
But my quad is still white...
Wait... *thought* shouldn't I convert the signature for Big-Endian support?
I'll try that.
Thanks for any other plausible problems/solutions you can offer!
EDIT: Nope, sigs are chars... not a good solution.
Anyways:
I'm on PPC, too cheap for an intel one yet.

Anyways, I've got a problem again similar to this one, so I put it in this thread.
I've tried out libpng (again, after leaving it for DevIL) and I wrote a C++ class for using it with OpenGL. It supports error codes, arbitrary sized textures and stuff too. Here's the source:
Code:
#include <cstdlib>
#include <fstream>
#include "OpenGL/gl.h"
#include "OpenGL/glu.h"
#include <png.h>
#define PNG_NO_FILE 89224
#define PNG_BAD_FILE 71120
#define PNG_STRUCT_ERR 22398
#define PNG_LIB_ERR 10893
#define PNG_NO_MEMORY 62009
#define PNG_NO_ERR 55872
#define PNG_BUF_FULL 01512
#define PNG_BUF_EMPTY 11943
#define PNG_BAD_TEX 99124
using namespace std;
class PNG {
protected:
FILE *p_stream;
png_structp p_pngPTR;
png_infop p_infoPTR;
png_bytepp p_rowPointers;
unsigned char p_sig[8];
unsigned int p_cur_error;
bool p_imageLoaded;
public:
GLenum p_targArgs;
GLenum p_colArgs;
unsigned char *p_image;
unsigned int p_depth;
unsigned int p_colorType;
unsigned long p_width;
unsigned long p_height;
unsigned int p_rowbytes;
PNG();
bool Open(char*);
bool Flush();
bool Texture(GLuint);
};
/* Constructor, sets some pointers to null. */
PNG::PNG() {
p_image = NULL;
p_rowPointers = NULL;
p_imageLoaded = FALSE;
p_cur_error = PNG_NO_ERR;
}
/* Open a png image. */
bool PNG::Open(char *p_file) {
if (p_imageLoaded == TRUE) {
p_cur_error = PNG_BUF_FULL;
return(FALSE);
}
/* Open the file. */
p_stream = fopen(p_file, "rb");
if (!p_stream) {
p_cur_error = PNG_NO_FILE;
return(FALSE);
}
/* Read the file signature, and validate it. */
fread(p_sig, 1, 8, p_stream);
if (!png_check_sig((unsigned char *)p_sig, 8)) {
p_cur_error = PNG_BAD_FILE;
fclose(p_stream);
return(FALSE);
}
/* Create the png struct. */
p_pngPTR = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!p_pngPTR) {
fclose(p_stream);
p_cur_error = PNG_STRUCT_ERR;
return(FALSE);
}
/* Create the info struct. */
p_infoPTR = png_create_info_struct(p_pngPTR);
if (!p_infoPTR) {
png_destroy_read_struct(&p_pngPTR, (png_infopp) NULL, (png_infopp) NULL);
fclose(p_stream);
p_cur_error = PNG_STRUCT_ERR;
return(FALSE);
}
/* Handles libpng errors. */
if (setjmp(png_jmpbuf(p_pngPTR))) {
png_destroy_read_struct(&p_pngPTR, &p_infoPTR, NULL);
fclose(p_stream);
p_cur_error = PNG_LIB_ERR;
return(FALSE);
}
/* Store our file stream pointer. */
png_init_io(p_pngPTR, p_stream);
/* Tell libpng not to look for the file signature. */
png_set_sig_bytes(p_pngPTR, 8);
/* Get everything up to actual image data. */
png_read_info(p_pngPTR, p_infoPTR);
/* Take in the info, stick it in variables. */
png_get_IHDR(p_pngPTR, p_infoPTR, &p_width, &p_height,
(int*)&p_depth, (int*)&p_colorType, NULL, NULL, NULL);
/* Convert some stuff, if we have to. */
if (p_colorType & PNG_COLOR_MASK_ALPHA) {
png_set_strip_alpha(p_pngPTR);
}
if (p_depth > 8) {
png_set_strip_16(p_pngPTR);
}
if (p_colorType == PNG_COLOR_TYPE_GRAY ||
p_colorType == PNG_COLOR_TYPE_GRAY_ALPHA) {
png_set_gray_to_rgb(p_pngPTR);
}
if (p_colorType == PNG_COLOR_TYPE_PALETTE) {
png_set_palette_to_rgb(p_pngPTR);
}
/* Update the info. */
png_read_update_info(p_pngPTR, p_infoPTR);
/* Number of rowsize, in bytes. */
p_rowbytes = png_get_rowbytes(p_pngPTR, p_infoPTR);
/* Allocate memory for pixel data. */
if ((p_image = (unsigned char*)malloc(p_rowbytes * p_height)) == NULL) {
png_destroy_read_struct(&p_pngPTR, &p_infoPTR, NULL);
p_cur_error = PNG_NO_MEMORY;
return(FALSE);
}
if ((p_rowPointers = (png_bytepp)malloc(p_height * sizeof(png_bytepp))) == NULL) {
png_destroy_read_struct(&p_pngPTR, &p_infoPTR, NULL);
free(p_image);
p_image = NULL;
p_cur_error = PNG_NO_MEMORY;
return(FALSE);
}
/* Correct the row pointer offsets. */
for (int p_counter = 0; p_counter < p_height; p_counter++) {
p_rowPointers[p_height - 1 - p_counter] = p_image + p_counter * p_rowbytes;
}
/* Read in the image. */
png_read_image(p_pngPTR, p_rowPointers);
free(p_rowPointers);
fclose(p_stream);
/* Is it arbitrary, and non power of two? */
if (p_width & (p_width * -1) != 0) {
p_targArgs = GL_TEXTURE_RECTANGLE_ARB;
}
else if (p_height & (p_height * -1) != 0) {
p_targArgs = GL_TEXTURE_RECTANGLE_ARB;
}
else {
p_targArgs = GL_TEXTURE_2D;
}
/* Check COLOR settings... */
if (p_colorType == PNG_COLOR_TYPE_RGB_ALPHA) {
p_colArgs = GL_RGBA;
}
else if (p_colorType == PNG_COLOR_TYPE_RGB) {
p_colArgs = GL_RGB;
}
p_cur_error = PNG_NO_ERR;
p_imageLoaded = TRUE;
return(TRUE);
}
/* Clean out PNG data. */
bool PNG::Flush() {
if (p_imageLoaded == FALSE) {
p_cur_error = PNG_BUF_EMPTY;
return(FALSE);
}
png_destroy_read_struct(&p_pngPTR, &p_infoPTR, NULL);
free(p_image);
p_image = NULL;
p_imageLoaded = FALSE;
p_cur_error = PNG_NO_ERR;
return(TRUE);
}
/* Bind a gl texture. */
bool PNG::Texture(GLuint p_tex) {
/* Is the image loaded? */
if (p_imageLoaded == FALSE) {
p_cur_error = PNG_BUF_EMPTY;
return(FALSE);
}
/* Are it's sizes valid? */
if ((p_width <= 0) || (p_height <= 0)) {
p_cur_error = PNG_BAD_TEX;
return(FALSE);
}
/* Make a texture, use the ARB/2D values and color types. */
glBindTexture(p_targArgs, p_tex);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(p_targArgs, 0, p_colArgs, p_width, p_height,
0, p_colArgs, GL_UNSIGNED_BYTE, p_image);
p_cur_error = PNG_NO_ERR;
return(TRUE);
}Here's my main file (simple testing one):
Code:
#include <cstdlib>
#include <cstring>
#include <cmath>
#include "GLUT/glut.h"
#include "OpenGL/gl.h"
#include "OpenGL/glu.h"
#include "PNG_class.h"
using namespace std;
PNG myPicture;
GLuint hello;
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearDepth(0.0);
glShadeModel(GL_SMOOTH);
glEnable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_RECTANGLE_ARB);
myPicture.Open("/hello.png");
glGenTextures(1, &hello);
myPicture.Texture(hello);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glLoadIdentity();
glBindTexture(myPicture.p_targArgs, hello);
glTranslated(0, 0, -3);
glBegin(GL_QUADS);
glTexCoord2i(0,0);
glVertex3i(-1, 1, 0);
glTexCoord2i(1,0);
glVertex3i(1, 1, 0);
glTexCoord2i(1,1);
glVertex3i(1, -1, 0);
glTexCoord2i(0,1);
glVertex3i(-1, -1, 0);
glEnd();
glFlush();
}
void reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(320, 240);
glutInitWindowPosition(100, 100);
glutCreateWindow("OpenGL");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return(0);
}But my quad is still white...
Wait... *thought* shouldn't I convert the signature for Big-Endian support?
I'll try that.
Thanks for any other plausible problems/solutions you can offer!
EDIT: Nope, sigs are chars... not a good solution.
I know I'm a little late (didn't see this thread before), but when using DevIL, instead of using GL_RGBA in glTexImage2D(GL_TEXTURE_2D, 0, components, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); you probably should have used GL_BGRA. (for inverted blue and red channels)
For your libpng demo, is the texture a 2D texture or rectangular texture? You enable both GL_TEXTURE_2D and GL_TEXTURE_RECTANGLE_ARB, and I believe GL_TEXTURE_RECTANGLE_ARB takes precedence. If it's really a 2D texture, it won't display correctly.
BTW, you multiply by -1 to negate some numbers there: the unary - sign works. For example, this would be valid:
p_height & -p_height != 0
It won't make much of a difference, but it would take up a few less cycles.
(well, assuming you have optimizations turned on, it actually likely be optimized out.
)
For your libpng demo, is the texture a 2D texture or rectangular texture? You enable both GL_TEXTURE_2D and GL_TEXTURE_RECTANGLE_ARB, and I believe GL_TEXTURE_RECTANGLE_ARB takes precedence. If it's really a 2D texture, it won't display correctly.
BTW, you multiply by -1 to negate some numbers there: the unary - sign works. For example, this would be valid:
p_height & -p_height != 0
It won't make much of a difference, but it would take up a few less cycles.
(well, assuming you have optimizations turned on, it actually likely be optimized out.
)
akb825 Wrote:I know I'm a little late (didn't see this thread before), but when using DevIL, instead of using GL_RGBA in glTexImage2D(GL_TEXTURE_2D, 0, components, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); you probably should have used GL_BGRA. (for inverted blue and red channels)
For your libpng demo, is the texture a 2D texture or rectangular texture? You enable both GL_TEXTURE_2D and GL_TEXTURE_RECTANGLE_ARB, and I believe GL_TEXTURE_RECTANGLE_ARB takes precedence. If it's really a 2D texture, it won't display correctly.
BTW, you multiply by -1 to negate some numbers there: the unary - sign works. For example, this would be valid:
p_height & -p_height != 0
It won't make much of a difference, but it would take up a few less cycles.(well, assuming you have optimizations turned on, it actually likely be optimized out.
)
Would it really? I've always done it * -1 because it seemed to be more... correct. Dunno why.
I enable both ARB and 2D because the class can handle both, and needs to have both enabled. I'll try removing one...
If GL_TEXTURE_RECTANGLE_ARB is enabled, GL ignores whether GL_TEXTURE_2D is enabled (GL_TEXTURE_RECTANGLE_ARB takes precedence). Basically, it never makes sense to have more than one enabled at once.
...on the same texture unit.
Enabled just 2D (the one I'd need for my test picture), but nothing appears yet. This is strange, and I'm willing to bet it's something really stupid and simple I've completely missed.
BTW, did you check your error values? Perhaps you just didn't successfully open the texture.
Possibly Related Threads...
| Thread: | Author | Replies: | Views: | Last Post | |
| OpenGL ES Texture Compression | ajrs84 | 9 | 436 |
May 7, 2013 03:36 PM Last Post: ajrs84 |
|
| OpenGL ES Texture Masking | airfire | 5 | 11,437 |
Nov 14, 2012 09:36 AM Last Post: toanNguyen |
|
| OpenGL ES Texture Masking | dalasjoe sin | 0 | 3,132 |
Apr 13, 2012 12:17 AM Last Post: dalasjoe sin |
|
| Texture in OpenGL ES 2 looks pixelated | vunterslaush | 18 | 17,752 |
Aug 30, 2011 09:44 PM Last Post: Frogblast |
|
| Another beginner's question about displaying an animated object | superlemonster | 2 | 4,045 |
Jan 28, 2011 08:03 AM Last Post: OptimisticMonkey |
|

