PDA

View Full Version : gl extension, blending, and pyOpenGL



fwest
11-11-2004, 09:15 PM
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

rgpc
11-11-2004, 11:52 PM
Don't use DrawPixels. Use a texture instead.

fwest
11-12-2004, 03:53 AM
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?

V-man
11-12-2004, 11:24 AM
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?

fwest
11-12-2004, 09:46 PM
>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.

rgpc
11-12-2004, 11:12 PM
Here (http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=13) 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.

fwest
11-13-2004, 12:15 AM
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.

rgpc
11-13-2004, 02:10 AM
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
}

fwest
11-13-2004, 02:36 AM
This looks very promising. I need to rewrite this in Python, but I don't see any problems.

Thanks

V-man
11-13-2004, 10:52 AM
Originally posted by fwest:
>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.
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