C Board  

Go Back   C Board > General Programming Boards > Game Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 09-22-2006, 05:27 PM   #1
Mad
 
OnionKnight's Avatar
 
Join Date: Jan 2005
Location: Umeå, Sweden
Posts: 555
Texture won't load (libpng with OpenGL)

I was following this tutorial: http://nehe.gamedev.net/data/lessons....asp?lesson=06
But as I don't have the GLaux library and didn't feel like I wanted it I went ahead studied how to use libpng with OpenGL following this tutorial: http://www.macdevcenter.com/pub/a/ma...ps.html?page=1
The resulting code was copied and slightly modified code from the site,
Code:
unsigned char* glxReadPNG (TCHAR* file, png_uint_32* w, png_uint_32* h)
{
	FILE* f;
	unsigned char sig[8];
	png_structp png_ptr;
	png_infop   info_ptr;
	unsigned char* image_data;
	int bit_depth;
	int color_type;
	unsigned int rowbytes;
	png_uint_32 i;
	png_bytepp row_pointers;

	if ((f = fopen(file, "rb")) == NULL)
		return NULL;
	fread(sig, sizeof(*sig), sizeof(sig), f);
	if (!png_check_sig(sig, sizeof(*sig))) {
		fclose(f);
		return NULL;
	}
	if ((png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)) == NULL) {
		fclose(f);
		return NULL;
	}
	if ((info_ptr = png_create_info_struct(png_ptr)) == NULL) {
		png_destroy_read_struct(&png_ptr, NULL, NULL);
		fclose(f);
		return NULL;
	}

	if (setjmp(png_jmpbuf(png_ptr))) {
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
		fclose(f);
		return NULL;
	}
	png_ptr->io_ptr = (png_voidp) f;
	png_set_sig_bytes(png_ptr, 8);

	png_read_info(png_ptr, info_ptr);
	png_get_IHDR(png_ptr, info_ptr, w, h, &bit_depth, &color_type, NULL, NULL, NULL);
	if (color_type & PNG_COLOR_MASK_ALPHA)
		png_set_strip_alpha(png_ptr);
	if (bit_depth > 8)
		png_set_strip_16(png_ptr);
	if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
		png_set_gray_to_rgb(png_ptr);
	if (color_type == PNG_COLOR_TYPE_PALETTE)
		png_set_palette_to_rgb(png_ptr);
	png_read_update_info(png_ptr, info_ptr);

	rowbytes = png_get_rowbytes(png_ptr, info_ptr);
	if ((image_data = malloc(*h * rowbytes)) == NULL) {
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
		fclose(f);
		return NULL;
	}
	if ((row_pointers = malloc(*h * sizeof(png_bytep))) == NULL) {
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
		fclose(f);
		free(image_data);
		return NULL;
	}

	for (i = 0; i < *h; i++)
		row_pointers[*h - 1 - i] = image_data + i*rowbytes;
	png_read_image(png_ptr, row_pointers);
	free(row_pointers);
	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
	fclose(f);

	return image_data;
}
Also following the same site, I loaded this texture using the lines found on page 3 and probably a mix from the NeHe tutorial.
Global variables and static variables for wndproc (window procedure for the OpenGL window):
Code:
//global
int w;
int h;
GLfloat xrot = 0.0f;
GLfloat yrot = 0.0f;
GLuint imgname;

//static variables for wndproc
static HDC   hdc;
static HGLRC hrc;
static HFONT font;
static RECT  re = {0, 0, 0, 0};
static unsigned char* image;
static int imgw, imgh;
WM_CREATE for wndproc:
Code:
		case WM_CREATE:
		{
			PIXELFORMATDESCRIPTOR pfd = {
				sizeof(pfd),
				1,
				PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
				PFD_TYPE_RGBA,
				32,
				0, 0, 0, 0, 0, 0,
				0,
				0,
				0,
				0, 0, 0, 0,
				32,
				0,
				0,
				PFD_MAIN_PLANE,
				0,
				0, 0, 0
			};
			if ((hdc = GetDC(hwnd)) == NULL ||
			    !SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd) ||
			    (hrc = wglCreateContext(hdc)) == NULL ||
			    !wglMakeCurrent(hdc, hrc))
			{
				Error();
				PostQuitMessage(1);
				break;
			}
			font = CreateFont(-MulDiv(12, GetDeviceCaps(hdc, LOGPIXELSY), 72), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "MS Shell Dlg");
			if (font == NULL) {
				Error();
				PostQuitMessage(1);
				break;
			}
			SetTextColor(hdc, RGB(0, 0xFF, 0));
			SetBkMode(hdc, TRANSPARENT);
			if ((image = glxReadPNG(TEXT("ogl.png"), &imgw, &imgh)) == NULL) {
				Error();
				PostQuitMessage(1);
				break;
			}
			glGenTextures(1, &imgname);
			glBindTexture(GL_TEXTURE_2D, imgname);
			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
			free(image);
			glEnable(GL_TEXTURE_2D);
			glShadeModel(GL_SMOOTH);
			glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
			glClearDepth(1.0f);
			glEnable(GL_DEPTH_TEST);
			glDepthFunc(GL_LEQUAL);
			glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
			break;
		}
The rendering function is pretty much identical with the one from the OpenGL tutorial, the exception being that I still have the triangle from earlier lessons still drawn but I think that shouldn't matter, also, this message is probably already too long to drop more code.

I don't know where it fails, when the screen was first drawn I saw nothing. Then I thought it was probably because the color was set to black so I changed it to white and that gave me a white cube, with no textures on it.

I don't think the PNG-loading function is failing as I wrote a test program in SDL to test it out. It returns the right width, height and pixel data as my test program had no problem drawing the picture it loaded (except upside down and horizontally flipped, which it should do according to the libpng guide).

Compiled using MinGW and libpng 1.2.8. Attaching ogl.c (main program), ogl.png (texture) and test.c (SDL program to test libpng).
I'm suffering from a cold at the moment and can't think clearly so I'm sorry if this thread isn't as helpful as it could. I'm gonna go grab some painkillers after posting this.
Attached Images
 
Attached Files
File Type: c ogl.c (10.5 KB, 72 views)
File Type: c test.c (3.2 KB, 69 views)
OnionKnight is offline   Reply With Quote
Old 10-04-2006, 03:52 AM   #2
Mad
 
OnionKnight's Avatar
 
Join Date: Jan 2005
Location: Umeå, Sweden
Posts: 555
I guess I'm on my own in this matter.
What functionalities of errorchecking does OpenGL provide? All the functions return void so that's not very helpful. I googled around and found out about the functions glGetError() as well as gluErrorString() and then I made this function:
Code:
GLvoid glxError (GLvoid)
{
	GLenum error;
	while ((error = glGetError()) != GL_NO_ERROR)
		MessageBox(NULL, gluErrorString(error), NULL, MB_OK | MB_ICONSTOP);
}
And called it after the glTexImage2D() call and some other random places like in the rendering function and there was no sign of a message box so obviously there were no errors, yet I get no textures.
Since there really should be errors I got suspicious and called the function inbetween a glBegin() and glEnd() which is supposed to give an error, but it didn't. So the function that handles errors is getting errors. That's just great. Could the fault lie in the libraries perhaps?

And why am I writing as if I was doing a novel?
OnionKnight is offline   Reply With Quote
Old 10-04-2006, 05:47 PM   #3
vae victus!
 
skorman00's Avatar
 
Join Date: Nov 2003
Posts: 594
I doubt the texture is failing to load, you're either not handing it to OGL correctly, or drawing correctly. I'm going to say you're not handing it to OGL correctly, because you're passing GL_RGB to what I remember to be the number of color channels. GL_RGB is definitely not 3.

I applaud your inner monolague.
skorman00 is offline   Reply With Quote
Old 10-04-2006, 10:28 PM   #4
Mad
 
OnionKnight's Avatar
 
Join Date: Jan 2005
Location: Umeå, Sweden
Posts: 555
Changing GL_RGB to 3 didn't change the results.
I tried the glaux approach, converting the texture to a bitmap and not to my surprise that worked just fine. The triangle seems to have been affected as well but I couldn't care less about that. Maybe there's something wrong with my PNG-reading function beside the sizeof(*sig) which should be sizeof(sig) in png_check_sig after all.
Since the data sent into the glTextureImage2D is in a specific format I should be able to compare the data of the PNG and BMP images to see how they differ, right? Stay tuned for results!

EDIT: Okay this is just downright creepy. I can dump the data of the BMP picture to a file but when I do the same to the PNG picture I get a file with 0 size, and no errors found in errno or GetLastError().

EDIT2: So I finally got a hold of the data for the PNG image by putting the output routine inside the function that loads it. The data for the BMP image and the PNG image are exactly the same. The data was dumped using
Quote:
fwrite(image, 1, 3*width*height, file)
(pseudocode) and since the image is 80x80 a 19 200 byte file was generated for both.
Could my source be haunted? Maybe there's an invisible force causing the data to act strange like in the first edit. Yes, that must be it.

EDIT3: Haha oh wow, I finally found the error. I'm passing w and h to glTextureImage2D() whereas imgw and imgh were the variables that contained the size. w and h contain the dimensions of the window.
All this work debugging something so simple.

Still, shouldn't I be getting a segfault or an error from OpenGL? The starting width and height of the application is 629 and 449 respectively, which is way larger than the array's dimensions.
Attached Images
 
Attached Files
File Type: txt oglbmpraw.txt (18.8 KB, 64 views)
File Type: txt oglpngraw.txt (18.8 KB, 63 views)

Last edited by OnionKnight; 10-05-2006 at 01:13 AM.
OnionKnight is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Texture Binding with OpenGL scwizzo Game Programming 5 07-01-2008 11:02 AM
Linking OpenGL in Dev-C++ linkofazeroth Game Programming 4 09-13-2005 10:17 AM
Pong is completed!!! Shamino Game Programming 11 05-26-2005 10:50 AM
OpenGL Window Morgul Game Programming 1 05-15-2005 12:34 PM
OpenGL and Windows sean345 Game Programming 5 06-24-2002 10:14 PM


All times are GMT -6. The time now is 09:36 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22