Sign in to follow this  

3D Font problem

This topic is 4135 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey folks, I am currently trying to implement 3D Fonts. I am working with a tutorial that uses display lists. Everything worked out fine with the fonts, they are displaying exaclty how they are supposed to, however, if I also wanna display some rects with textures on them, only the font gets displayed. The crucial point is when I call the glCallLists function. Initiation of the font
hFont = CreateFont(0, 0, 0, 0, FW_BOLD, false, false, false, 
ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, 
ANTIALIASED_QUALITY, FF_DONTCARE|DEFAULT_PITCH, fontname);

hOldFont = (HFONT)SelectObject(hdc, hFont);

wglUseFontOutlines(hdc,	0, 255, uiFontListID, 0, extrude, WGL_FONT_POLYGONS, GlyphInfo);

How the font is being rendered:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0, 0, 6,     0, 0, 0,     0, 1, 0);

glPushMatrix();
glBindTexture(GL_TEXTURE_2D, 0);

glPushAttrib(GL_LIST_BIT);

glListBase(uiFontListID);

glCallLists((int)strlen(pcText), GL_UNSIGNED_BYTE, pcText);

glPopAttrib();

glPopMatrix();
SwapBuffers(hdc);

Does anyone of you have an idea what might be going wrong? Thx in advance cherio Woltan [Edited by - Woltan on August 17, 2006 3:06:46 AM]

Share this post


Link to post
Share on other sites
I am confused on the last part where you say when you want to texture a rectangle and the font is the only thing that gets displayed? Are you trying to render the fonts onto a rectangle with another texture also? If so are you using multitexturing? If not you need to or do multiple passes then...

Share this post


Link to post
Share on other sites
The glBindTexture(GL_TEXTURE_2D, 0) is only in there because actually all the rendering is within a loop, and glBindTexture gets called everytime, but if there is no texture it gets called with a "0" as the second parameter. The RenderScene function looks like this:


glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0, 0, 6, 0, 0, 0, 0, 1, 0);

//Loop is starting here the source down here is just one element out of others

glPushMatrix();
glBindTexture(GL_TEXTURE_2D, 0);

glPushAttrib(GL_LIST_BIT);
glListBase(uiFontListID);
glCallLists((int)strlen(pcText), GL_UNSIGNED_BYTE, pcText);
glPopAttrib();

glPopMatrix();

//Loops ends here

SwapBuffers(hdc);


Just for an example an other element within the loops is this:

//Beginning of loop
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, uiTex);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(pfPointA[0], pfPointA[1], pfPointA[2]);

glTexCoord2f(0.0f, 0.0f);
glVertex3f(pfPointB[0], pfPointB[1], pfPointB[2]);

glTexCoord2f(1.0f, 0.0f);
glVertex3f(pfPointC[0], pfPointC[1], pfPointC[2]);

glTexCoord2f(1.0f, 1.0f);
glVertex3f(pfPointD[0], pfPointD[1], pfPointD[2]);
glEnd();
glPopMatrix();
//End of loop



I hope this helped. Maybe there is something wrong with my loop. But as far as I understood OpenGL it should work. With textured quads and circls however it works.

[Edited by - Woltan on August 17, 2006 3:48:12 AM]

Share this post


Link to post
Share on other sites
Ok, I am still lost but can recommend this one use source tags like so

use [] around source and /source

or Phantom will have a cow...

Also I am thinking you need to post complete code of what you are doing, but just a tip unless you are translating or doing something to move the object location you don't need glPushMatrix glPopMatrix. From what I can see that "0" in your glBindTexture() call still bugs me, as the second one has an ID in it. Second are you sure your texture coordinates are correct for all the render objects? I am tired so I am not thinking 100%...

Share this post


Link to post
Share on other sites


Hey MARS_999,
thx for your help so far, as you can see the sourcey things are done may the Phantom have mercy on my soul.

Quote:
Original post by MARS_999
I am thinking you need to post complete code of what you are doing


OK, i hope the next bit isnt too confusing + my english is good enough to explain everything.

What I set up is an OpenGLWindow, which initiates everything OpenGL needs. Then I added a class Drawable.

class Drawable
{
public:
void Paint();
GLuint SetTexture(char *path);
private:
virtual void PaintObject() = 0;
GLuint uiTex;
//plus a lot of floats for position rotation and scale
};


Every following class is going to inherite the Drawable class. The purpose of the virtual PaintObject method is, that every following renders itself, i.e. a rect, triangle, circle...
The Paint() method of Drawable soes this:

glPushMatrix();
glTranslatef(fX, fY, fZ);
glRotatef(fRotX, 1, 0, 0);
glRotatef(fRotY, 0, 1, 0);
glRotatef(fRotZ, 0, 0, 1);
glScalef(fScale, fScale, fScale);
glBindTexture(GL_TEXTURE_2D, uiTex);
PaintObject();
glPopMatrix();



As an example I have a simplified Rect class:

class OpenGLRect : public Drawable
{
void PaintObject()
{
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(pfPointA[0], pfPointA[1], pfPointA[2]);

glTexCoord2f(0.0f, 0.0f);
glVertex3f(pfPointB[0], pfPointB[1], pfPointB[2]);

glTexCoord2f(1.0f, 0.0f);
glVertex3f(pfPointC[0], pfPointC[1], pfPointC[2]);

glTexCoord2f(1.0f, 1.0f);
glVertex3f(pfPointD[0], pfPointD[1], pfPointD[2]);
glEnd();
}
};


Just like that I did it with the Font class:

class Font3D : public Drawable
{
public:
Font3D(HDC *hdc, char *fontname, float extrude)
{
uiFontListID = glGenLists(256);
hFont = CreateFont(0, 0, 0, 0, FW_BOLD, false, false, false,
ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
ANTIALIASED_QUALITY, FF_DONTCARE|DEFAULT_PITCH, fontname);

hOldFont = (HFONT)SelectObject(*hdc, hFont);

wglUseFontOutlines(*hdc, 0, 255, uiFontListID, 0, extrude, WGL_FONT_POLYGONS, GlyphInfo);

SelectObject(*hdc, hOldFont);
DeleteObject(hFont);
}

void PaintObject()
{
glPushAttrib(GL_LIST_BIT);
glListBase(uiFontListID);
glCallLists((int)strlen(pcText), GL_UNSIGNED_BYTE, pcText);
glPopAttrib();
}
UINT uiFontListID;
HFONT hFont, hFontOld;
};



The next source sample deals with the connection between the window and the RenderScene function:

OpenGLWindow *pW = new...;
OpenGLRect *pRect = new...;
Font3D *pFont = new...;
bool RenderScene()
{
pRect->Paint();
pFont->Paint();
pW->SwitchBuffers(); //Switches the buffers ;)
}

bool OpenGLWindow::Paint()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

gluLookAt(0, 0, 6, 0, 0, 0, 0, 1, 0);

return RenderScene();
}



The last source sample shows all the methods and function that get called when the scene gets painted:


glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //from OpenGLWindow::Paint()
glLoadIdentity(); //from OpenGLWindow::Paint()
gluLookAt(0, 0, 6, 0, 0, 0, 0, 1, 0); //from OpenGLWindow::Paint()

//First the Drawable::OpenGLRect
glPushMatrix(); //from Drawable::(OpenGLRect)::Paint()
glTranslatef(fX, fY, fZ); //from Drawable::(OpenGLRect)::Paint()
glRotatef(fRotX, 1, 0, 0); //from Drawable::(OpenGLRect)::Paint()
glRotatef(fRotY, 0, 1, 0); //from Drawable::(OpenGLRect)::Paint()
glRotatef(fRotZ, 0, 0, 1); //from Drawable::(OpenGLRect)::Paint()
glScalef(fScale, fScale, fScale); //from Drawable::(OpenGLRect)::Paint()
glBindTexture(GL_TEXTURE_2D, uiTex); //from Drawable::(OpenGLRect)::Paint()

//PaintObject();

glBegin(GL_QUADS); //from OpenGLRect::PaintObject()
glTexCoord2f(0.0f, 1.0f); //from OpenGLRect::PaintObject()
glVertex3f(pfPointA[0], pfPointA[1], pfPointA[2]); //from OpenGLRect::PaintObject()

glTexCoord2f(0.0f, 0.0f); //from OpenGLRect::PaintObject()
glVertex3f(pfPointB[0], pfPointB[1], pfPointB[2]); //from OpenGLRect::PaintObject()

glTexCoord2f(1.0f, 0.0f); //from OpenGLRect::PaintObject()
glVertex3f(pfPointC[0], pfPointC[1], pfPointC[2]); //from OpenGLRect::PaintObject()

glTexCoord2f(1.0f, 1.0f); //from OpenGLRect::PaintObject()
glVertex3f(pfPointD[0], pfPointD[1], pfPointD[2]); //from OpenGLRect::PaintObject()
glEnd(); //from OpenGLRect::PaintObject()

glPopMatrix(); //from Drawable::(OpenGLRect)::Paint()

//Next the Font:

//First the Drawable::OpenGLRect
glPushMatrix(); //from Drawable::(Font3D)::Paint()
glTranslatef(fX, fY, fZ); //from Drawable::(Font3D)::Paint()
glRotatef(fRotX, 1, 0, 0); //from Drawable::(Font3D)::Paint()
glRotatef(fRotY, 0, 1, 0); //from Drawable::(Font3D)::Paint()
glRotatef(fRotZ, 0, 0, 1); //from Drawable::(Font3D)::Paint()
glScalef(fScale, fScale, fScale); //from Drawable::(Font3D)::Paint()
glBindTexture(GL_TEXTURE_2D, uiTex); //from Drawable::(Font3D)::Paint()

//PaintObject();

glPushAttrib(GL_LIST_BIT); //from Font3D::PaintObject()
glListBase(uiFontListID); //from Font3D::PaintObject()
glCallLists((int)strlen(pcText), GL_UNSIGNED_BYTE, pcText); //from Font3D::PaintObject()
glPopAttrib(); //from Font3D::PaintObject()

glPopMatrix(); //from Drawable::(Font3D)::Paint()

SwapBuffers(); //done in RenderScene()




OK this is more or less it. I hope I could make myself clear how things work (if they would work) together. Since I came up with that myself and I am a bloody noob, maybe you or someone else could also comment that approach.
I hope you could find the flaw why the font is only being displayed. The crucial function is the glCallLists function. If I comment that out all the rects with its textures are being drawn just how they are suppost to. However, if I kick in the glCallLists function only the font is being displayed.

Mars, since you were already tired, you should be asleep by now ;)

I hope someone can help me
cherio Woltan

Share this post


Link to post
Share on other sites
I just did the Bitmap font tutorial, which uses the wglUseFontBitmaps function instead of the wglUseFontOutlines and it worked. However I need those Fonts rotating around its y-axis, and I need to scale them. And as far as I know this is not possible with the bitmap font.
I hope someone finds the flaw
cherio Woltan

Share this post


Link to post
Share on other sites
Quote:
Original post by Woltan
I just did the Bitmap font tutorial, which uses the wglUseFontBitmaps function instead of the wglUseFontOutlines and it worked. However I need those Fonts rotating around its y-axis, and I need to scale them. And as far as I know this is not possible with the bitmap font.
I hope someone finds the flaw
cherio Woltan
Okay, I think I know what your problem is.
Quote:
From the wglUseFontOutlines man page
...
With WGL_FONT_POLYGONS, the created display lists call glFrontFace(GL_CW) or glFrontFace(GL_CCW); thus the current front-face value might be altered.
...
So when you're rendering the font, either set the front face to what you expect it to be afterwards (probably GL_CCW) or wrap a glPushAttrib/glPopAttrib pair (with mask set to GL_POLYGON_BIT) around the calling of the display lists.

Share this post


Link to post
Share on other sites
Kalidor you are my hero of the day!!!
That did the trick. I have no idea why it worked, but the GL_POLYGON_BIT did the trick.
I did a lot of troublshooting but I would have never guessed that! Its a pitty, that I dont know anything about opengl. But maybe the enlightment will come later ;)
Thanks again for your help
cherio Woltan

Share this post


Link to post
Share on other sites
Quote:
Original post by Woltan
Kalidor you are my hero of the day!!!
That did the trick. I have no idea why it worked, but the GL_POLYGON_BIT did the trick.
I did a lot of troublshooting but I would have never guessed that! Its a pitty, that I dont know anything about opengl. But maybe the enlightment will come later ;)
Thanks again for your help
cherio Woltan
To understand why that works, you have to understand face culling. To change which faces get culled you use glCullFace and to define the winding of front faces you use glFrontFace.

The display list that wglUseFontOutlines creates for each character internally calls glFrontFace, possibly changing the current front face definition. Since OpenGL is a state machine, once some state is set, it stays set like that until it is changed. So depending on which character you rendered last, the front face definition may be either GL_CW or GL_CCW.

What glPushAttrib/glPopAttrib do is push/pop the attributes passed in mask onto the attribute stack, effectively saving/restoring those attributes (similar to how glPushMatrix/glPopMatrix work). The GL_POLYGON_BIT attribute encompasses several attributes related to the rendering of polygons, including the front face winding definition. So when you call glPushAttrib(GL_POLYGON_BIT) before rendering any text, it effectively saves all those polygon attributes. Then rendering the text may or may not alter the current front face definition, depending on which character you last rendered. Then calling glPopAttrib() restores those saved polygon attributes to what they were when you saved them.

Share this post


Link to post
Share on other sites
Hey Kalidor,
you were perfectly right with your guess. When I restore the source to its state where it didn't work and I look at my scene from 'behind', everything is visible, only mirrored, or somewhat strange.
Thx again for your help and your thorough explanation. You taught me something today, I wound forget that fast.
Thx again
cherio Woltan

Share this post


Link to post
Share on other sites

This topic is 4135 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this