Introduction
Working with textures in OpenGL meant until very recently working with images with sizes of power of two, limited to 1024, 2048 or 4096. On April 26, 2005, Mark J. Kilgard published the
NVIDIA OpenGL 2.0 Support notes, making direct reference to the fact that "NVIDIA�s GeForce 6 Series and NV4xGL-based Quadro FX GPUs fully support non-power-of-two textures at the fragment level" (of course, with some limitations). From a programmer's point of view, it may be sometimes attractive to work with images of whatever size (and I mean pretty large images) and think of them implicitly as non-power-of-two large textures, let's say of a 8000 x 3000 pixel size, and not to care a bit about the well known texture "kitchen".
anyTex
is a class allowing you to load a bitmap of a given color depth from a file and think of it as texture with no restrictions (of course, limited by the computer resources, that is something we have to live with).
Working with the class
anyTex comes with two files, anytex.cpp and anytex.h, which you have to add to your project. Make sure you have OpenGL32.lib, GLu32.lib, GLaux.lib in the Link tab of your project settings. Then #include "anytex.h"
in the header file of your main dialog class. Add a public member of type AnyTex
to the main dialog class:
AnyTex m_atImage;
Add a CStatic
control to your application, which will be responsible for rendering your OpenGL scenes (I made that choice just for the sake of the presentation). Then, add a CStatic
derived class with the wizard and map a variable of that type to the control. Let us assume that m_oglDisplay
is the name of that variable. In the OnInitDialog()
function, create the OpenGL rendering context by passing the address of the control to the InitializeOpenGL()
function provided by the anyTex
class:
if ( !m_atImage.InitializeOpenGL(&m_oglDisplay) )
{
AfxMessageBox("Cannot initialize OpenGL");
PostMessage(WM_QUIT);
}
Before going further, keep in mind that, behind the scene, anyTex
still works with power-of-two classical textures as basic square cells. By default, the cell size is 1024. Should you want to set another cell size, you are free to do it by calling the SetTexCellSize(int nSize)
function provided by anyTex
. You may choose whatever value you want for nSize
. anyTex
adjusts it automatically to 128, 256, 512 or 1024. Load a bitmap image of your choice and create the anyTex
texture, which will be called further on just anyTex
for simplicity.
if ( m_atImage.LoadBmpImage("test.bmp") ) m_atImage.CreateTex();
The CreateTex()
function needs a boolean parameter, which by default is false
, this leading to creation of 2D image textures. By calling the function with the parameter set to true
, mipmaps are generated. From now on, you have only to call the PreRender()
function (which can be overwritten according to your needs) and the Render()
function of the anyTex
class from within the OnPaint()
function of your CStatic
derived class.
The things behind
anyTex
is supported by a CList <UINT, UINT> m_listTex
, storing the ID of the texture cells. The bitmap is brought into the memory as a DIB. anytex
"goes" throughout the DIB, sequentially extracting squares with the same size as the basic texture cell. Each square is blitted to a memory device context, resulting a DDB. The DDB is converted to a DIB having a 32 color depth, which is used then to generate a basic texture cell or its corresponding mipmaps, according to the boolean parameter passed to the AnyText::CreateTex()
function. The texture ID is added to m_listTex
.
anyTex considers a square texture canvas of size 1 mapped over the anyTex
object in the following way:
anyTex
is top-left aligned to the canvas. The AnyTex::Render()
function renders anyText
as it is, as a whole. Should you now be interested in 3D rendering and need to use the component texture cells individually, all you have to do is to call the:
UINT AnyTex::RetrieveTexCell(double atX, double atY,
double &renLeft, double &renTop, double &renSize)
function and pass the atX, atY
position on the logical canvas as parameters. The function returns the texture ID for the corresponding cell or 0 in case no one is found. A non-zero ID means a valid ID, and the basic cell pointed by that ID is rendered at renLeft, renTop
and has the size stored in renSize
, values which can be used further in your computations.
History