NPOT

Hello!

I’m new in this list, but I’ve been using OpenGL for a while. I tought this forum was the right place to put the question.

I’ve searched the forum for a solution (or explanation) on how to use the NPOT textures, but without success.

My question is: What’s the best solution to get NPOT textures working? Upgrade the OpenGL Driver? Get new headers?

I’m kinda stuck here.

Thanks for any help.
Below is some info on how I’m registering the texture and information on my video card.


glGenTextures(1, &texid);
glBindTexture(GL_TEXTURE_2D, texid);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexImage2D(
	GL_TEXTURE_2D,
	0,
	img.getBpp() / 8,
	m_width,
	m_height,
	0,
	drawtype,
	GL_UNSIGNED_BYTE,
	img.getBuffer()
);

The texture size is 280 x 120 and the returned error is GL_INVALID_VALUE.

The OpenGL info I got from the code using glGetString():

OpenGL Vendor: Intel
Version: 1.4.0 - Build 7.14.10.4926

The extensions:
GL_ARB_depth_texture
GL_ARB_fragment_program
GL_ARB_multitexture
GL_ARB_point_parameters
GL_ARB_shadow
GL_ARB_texture_border_clamp
GL_ARB_texture_compression
GL_ARB_texture_cube_map
GL_ARB_texture_env_add
GL_ARB_texture_env_combine
GL_ARB_texture_env_dot3
GL_ARB_texture_env_crossbar
GL_ARB_transpose_matrix
GL_ARB_vertex_buffer_object
GL_ARB_vertex_program
GL_ARB_window_pos
GL_EXT_abgr
GL_EXT_bgra
GL_EXT_blend_color
GL_EXT_blend_func_separate
GL_EXT_blend_minmax
GL_EXT_blend_subtract
GL_EXT_clip_volume_hint
GL_EXT_compiled_vertex_array
GL_EXT_cull_vertex
GL_EXT_draw_range_elements
GL_EXT_fog_coord
GL_EXT_multi_draw_arrays
GL_EXT_packed_pixels
GL_EXT_rescale_normal
GL_EXT_secondary_color
GL_EXT_separate_specular_color
GL_EXT_shadow_funcs
GL_EXT_stencil_two_side
GL_EXT_stencil_wrap
GL_EXT_texture_compression_s3tc
GL_EXT_texture_env_add
GL_EXT_texture_env_combine
GL_EXT_texture_lod_bias
GL_EXT_texture_filter_anisotropic
GL_EXT_texture3D
GL_3DFX_texture_compression_FXT1
GL_IBM_texture_mirrored_repeat
GL_NV_blend_square
GL_NV_texgen_reflection
GL_SGIS_generate_mipmap
GL_SGIS_texture_edge_clamp
GL_SGIS_texture_lod
GL_WIN_swap_hint

I’m using Windows XP 32 bits on a Intel 82945G. Latest drivers (15/02/2008).

Sorry about the long post.

Thanks!

Your card does not support NPOT textures : GL 1.4 only, and no NPOT extension (nor any of the older rectangle variants)
See the wiki page about it : http://www.opengl.org/wiki/NPOT_Textures
Too bad, however there are tricks to work around this hardware limitation.
Are you interested ?
Can you provide some background on why you need NPOT texture and how you plan to use it ?

That was a quick reply!
I really need to use NPOT texture. I’m making a game clone using the original data, and the original data uses NPOT textures (it uses DirectX, not OpenGL).

There are two uses (so far), for my NPOT textures. One are the GUI objects. I have several “windows”, “buttons” (all bmp files) and “characters” (players), “monsters”, “items”, etc (these have its own format, but I can manage to convert them to an OpenGL undersandable format) inside a huge (1.2Gb) file that I need to draw.

To draw the windows/buttons, I use a code like this:


void Engine::Mode2DStart() {
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	gluOrtho2D(0, m_width, m_height, 0);
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();

	glDisable(GL_DEPTH_TEST);

	m_mode2d = true;
}

void Engine::Mode2DEnd() {
	m_mode2d = false;

	glEnable(GL_DEPTH_TEST);
	
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();
}

And to draw the other objects I use billboard (I do not have the billboard code on me, right now, but it works).

Any help you can provide me is welcome.

If you want to know more about my project, you can see it in my webpage.

One way to handle NPOT textures without hardware support is to move image dimensions to the closest POT dimensions.

If you have many litle NPOT textures I recommend you to pack them in one big POT one. Try to reduce its dimension as much as you can rearranging all textures in it.

If you have a big NPOT texture, you can try to split it into many POT one but this is quite more complicated to handle when you have to map all this stuff. It depends on your needs.

Then of course it is only a matter of choosing correctly the textures coordinates.

Hardware pads NPOT textures out to POT internally anyway afaik, so all it really buys you (currently) is the convenience.

I am surprised : what is the source of your knowledge on the subject ?
I am pretty sure there is some padding, probably in cache friendly blocks, but more in the order of 32x32 or less.
If you were right, any card could expose NPOT extension : as it is not the case, I really doubt POT are used internally.

I think there’s something in the NV programming guide about loading a POT texture with NPOT source… there’s mention of padding.

Of course with hw NPOT support it’s a different story.

My phrasing was a bit nebulous…

And to illustrate all this, I stumbled upon this interesting nvidia article about mipmaps generation with NPOT textures, It is not a piece of cake! :slight_smile:

http://download.nvidia.com/developer/Papers/2005/NP2_Mipmapping/NP2_Mipmap_Creation.pdf

Thanks everyone for the information. Now I need just a little bit more… How do I check if a hardware supports NPOT?
So, I would check every time I load a texture if the hardware supports it, if not, I’ll resize it and set the “max_u” and “max_v” in my class.

Thanks again!

on application startup you need to check the extension list of your card for either “GL_ARB_texture_non_power_of_two” or “GL_ARB_texture_rectangle”. the latter won’t support the use of mipmaps but might be still enough for GUI. no need to check for it every frame from the graphics card instead retrieve once and store it on CPU memory f.e in a bitfield (deviceCaps |= NPOT_TEXTURE_SUPPRORTED;).

In addition to what _NK47, you can get the extensions list with the glGetString(GL_EXTENSIONS).

However, you can also use tools that automatically load all supported extensions and retrieve their call entry point (See Glee and glew) here. They also provide you a way to check if a particular extension is supported by hardware at runtime.

Thanks everyone who replied. I’ve managed to check if the video card has support to NPOT textures. If it doesn’t, it grows the texture to the next POT size and sets the u and v values accordingly (old_size / POT_size). When drawing, I get the “maxu” and “maxv” values when setting the texture coordinates.

It’s easier then putting all (or some) together in the same picture and finding out the coordinates for each one (at least, programatically, which is my case, as I “can’t” change the source textures – not for this project).

Thanks for all the help!