gl extension, blending, and pyOpenGL

Hello,

I posted about this subject before, I got some good tips, but I can’t get it running.

I have a font-rendering routine written with pyOpenGL. The font is a bitmap with luminance/alpha. I would like to show this bitmap (font) in the colour of my choice.

The actula rendering code looks like this:
(Python code!)

from OpenGL.GL.EXT.blend_color import *

glBlendFunc(GL_CONSTANT_COLOR_EXT, GL_ZERO)
glBlendColorEXT(1.0, 0.0, 0.0, 0.0) # Red
glEnable( GL_BLEND)
glDrawPixels( GL_LUMINANCE_ALPHA, array )

When I remove the blending part (glBlendFunc,glBlendColorEXT, glEnable) I get a fine font in white. The code above gives me red squares with the size of the bitmap. The really puzzeling thing is that this even happens with an alpha of 0.0.

I contacted the maintainer of pyOpenGL, and he can’t explain this behaviour either. Does anyone have a suggestion how to solve the problem?

Thanks,
Frits

Don’t use DrawPixels. Use a texture instead.

I think you suggested this before.

It would mean that I remove the display-list code that I use. At the moment I call glRasterPos2f( x,y ) and the display-list. This can not be done if I would use textures. A complete rewrite would be necessary. Apart from bandwidth considerations, are there other weighty arguments to prefer textures over bitmaps?

If the raster position gets clipped, then glDrawPixels won’t have any effect, even if part of the text is inside the viewport.

It won’t be a total rewrite. Just put your pixels in textures. Use rect textures instead of 2D.

>>>When I remove the blending part (glBlendFunc,glBlendColorEXT, glEnable) I get a fine font in white. The code above gives me red squares with the size of the bitmap. The really puzzeling thing is that this even happens with an alpha of 0.0<<<

I beleive that is the correct behavior.
What were you expecting?

>If the raster position gets clipped, then
> glDrawPixels won’t have any effect, even if
> part of the text is inside the viewport.

I’m sorry, but I don’t understand what you refer to.

>It won’t be a total rewrite. Just put your pixels
> in textures. Use rect textures instead of 2D.

I went through the OpenGL PG forward and backward. Unfortunately there was no mention of rect textures. glBindTexture has no such thing, and I don’t know another way to put them back.

>>>When I remove the blending part (glBlendFunc,glBlendColorEXT, glEnable) I get a fine font in white. The code above gives me red squares with the size of the bitmap. The really puzzeling thing is that this even happens with an alpha of 0.0<<<

> I beleive that is the correct behavior.

I see your point: the alpha has no effect.

> What were you expecting?

I expected that the luminance data in my bitmap would be replaced by the colour of my choice, and the alpha would remain as it was.

Here is a tutorial on how to do “bitmap” fonts.

If you are using Display Lists then you really just have to change the creation of the Display Lists.

The NeHe lesson is usable on MS-Windows only, which I dont’ use. Concerning the bitmaps/textures: NeHe shows the use of bitmaps, similar to my approach.

Apologies, that tutorial was not the tute I thought it was. I can’t find the tutorial I was thinking of. The code from it is basically as follows:

GLFont::GLFont()
{
  fWidth = 16;
  fHeight = 16;
  fSpacing = 10; 
  fxCount = 16;
  fyCount = 16;
  fdWidth = 640;
  fdHeight = 480;
  fStartPos = 0;
}

GLFont::~GLFont()
{
 KillFont();
}

GLvoid GLFont::KillFont(GLvoid)	// Delete The Font From Memory
{
	glDeleteLists(fBase,fxCount * fyCount);	// Delete Allocated Display Lists
}


GLvoid GLFont::Print(GLint x, GLint y, char *string) // Where The Printing Happens
	{
	utilGlobal.renderer.BindTexture(0, GL_TEXTURE_2D, fTexture[0]);
	//glBindTexture(GL_TEXTURE_2D, fTexture[0]); // Select Our Font Texture
	utilGlobal.renderer.DisableState(REND_DEPTH_TEST);

	glEnable(GL_ALPHA_TEST);
	glAlphaFunc(GL_GREATER, 0.0f);
	glMatrixMode(GL_PROJECTION);	// Select The Projection Matrix
	glPushMatrix();			// Store The Projection Matrix
	glLoadIdentity();		// Reset The Projection Matrix
	glOrtho(0,fdWidth,0,fdHeight,-1,1); // Set Up An Ortho Screen
	glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
	glPushMatrix();		// Store The Modelview Matrix
	glLoadIdentity();	// Reset The Modelview Matrix
	glColor4fv(colour.components);
	glTranslated(x,fdHeight - y,0);	// Position The Text (0,0 - Bottom Left)
	glListBase(fBase - fStartPos);	// Choose The Font Set (0 or 1)
	glCallLists(strlen(string),GL_BYTE,string); // Write The Text To The Screen
	glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
	glPopMatrix();		// Restore The Old Projection Matrix
	glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
	glPopMatrix();		// Restore The Old Projection Matrix
	utilGlobal.renderer.EnableState(REND_DEPTH_TEST);
	glDisable(GL_ALPHA_TEST);

	}

void GLFont::SetBase(int Base)
	{
 fStartPos = Base;
	}

void GLFont::SetTexture(GLuint Tex, int xCount, int yCount)
	{
	fTexture[0] = Tex;
	fxCount     = xCount;
	fyCount     = yCount;
	}

void GLFont::SetFontProperties(int Width, int Height, int Spacing)
	{
	fWidth      = Width;
	fHeight     = Height;
	fSpacing    = Spacing;
	}

void GLFont::SetDisplayMode(int dWidth, int dHeight)
	{
	fdWidth  = dWidth;
	fdHeight = dHeight;
	}


GLvoid GLFont::BuildFont() // Build Our Font Display List
	{
	int     loop;
	float	cx; // Holds Our X Character Coord
	float	cy; // Holds Our Y Character Coord
    float   cwx; // CharWidth in texture units
	float   cwy; // CharHeight in texture units

	cwx         = (1.0f / 256.0f) * fWidth;
	cwy         = (1.0f / 256.0f) * fHeight;
	fBase=glGenLists(fxCount * fyCount); // Creating Display Lists
	utilGlobal.renderer.BindTexture(0, GL_TEXTURE_2D, fTexture[0]);
	//glBindTexture(GL_TEXTURE_2D, fTexture[0]); // Select Our Font Texture
	for (loop=0; loop<(fxCount * fyCount); loop++) // Loop Through All Lists
		{
		cx=float(loop%fxCount) * cwx; // X Position Of Current Character
		cy=float(loop/fyCount) * cwy; // Y Position Of Current Character

		glNewList(fBase + loop,GL_COMPILE); // Start Building A List
			glBegin(GL_QUADS); // Use A Quad For Each Character
				glTexCoord2f(cx,1-cy-cwy); // Texture Coord (Bottom Left)
				glVertex2i(0,0); // Vertex Coord (Bottom Left)
				glTexCoord2f(cx+cwx,1-cy-cwy); // Texture Coord (Bottom Right)
				glVertex2i(fWidth - 1,0); // Vertex Coord (Bottom Right)
				glTexCoord2f(cx+cwx,1-cy); // Texture Coord (Top Right)
				glVertex2i(fWidth - 1,fHeight -1); // Vertex Coord (Top Right)
				glTexCoord2f(cx,1-cy); // Texture Coord (Top Left)
				glVertex2i(0,fHeight -1); // Vertex Coord (Top Left)
			glEnd(); // Done Building Our Quad (Character)
			glTranslated(fSpacing,0,0); // Move To The Right Of The Character
		glEndList(); // Done Building The Display List
		} // Loop Until All Are Built
	}

This looks very promising. I need to rewrite this in Python, but I don’t see any problems.

Thanks

Originally posted by fwest:
[b]>If the raster position gets clipped, then
> glDrawPixels won’t have any effect, even if
> part of the text is inside the viewport.

I’m sorry, but I don’t understand what you refer to.

>It won’t be a total rewrite. Just put your pixels
> in textures. Use rect textures instead of 2D.

I went through the OpenGL PG forward and backward. Unfortunately there was no mention of rect textures. glBindTexture has no such thing, and I don’t know another way to put them back.
[/b]
In a previous post, you said :

Apart from bandwidth considerations, are there other weighty arguments to prefer textures over bitmaps?
so I gave a “weighty arguments to prefer textures over bitmaps.”


By rect texture, I mean GL_NV_texture_rectangle / GL_EXT_texture_rectangle / GL_ARB_texture_rectangle