Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 3 of 3

Thread: Texture Mapped Fonts from Beginning OpenGL Book

  1. #1
    Intern Newbie
    Join Date
    Nov 2011
    Location
    Fairborn, OH
    Posts
    31

    Texture Mapped Fonts from Beginning OpenGL Book

    I'm using the code from Chapter 11 of the Beginning OpenGL Game Programming book in line with a previous example from the same book that's using vertex buffer objects...I'm having a hard time getting the fonts to display on the same screen as my regular geometry...and I'm pretty sure it has something to do with the setting up of the VBO's and GLIdentities and Matrices in the TextureMappedFont.cpp module conflicting with my regular VBO rendering process.

    Is anyone here familiar with that book that would like to take a look at my code for me? I've got two problems...

    I can either make the call to m_font->printString before or after my existing glDrawElements in render and see the text but not my elements. Or I can comment out the call to m_font->printString and see the elements...

    Either way...if the block in init that gets the GL_VIEWPORT and initializes the TextureMappedFont object is called, I can not debug the application...debugger says "Could not initialize the application" but the exe runs just fine outside of debugging.

    Any ideas?

  2. #2
    Intern Newbie
    Join Date
    Nov 2011
    Location
    Fairborn, OH
    Posts
    31

    Re: Texture Mapped Fonts from Beginning OpenGL Book

    Here's some code if anyone is interested in helping...

    I have two apparently competing bits...here's the texturemappedfont object, and it's unmodified from the sample except to change the directory of the font files to the current directory.

    Code :
    #ifdef WIN32
    #include <windows.h>
    #endif
     
    #include "texturemappedfont.h"
    #include <GL/glu.h>
     
    TextureMappedFont::TextureMappedFont(const string&amp; textureName, int screenWidth, int screenHeight, float fontSize)
    { 
        m_textureName = textureName;
        m_shaderProgram = new GLSLProgram("font.vert", "font.frag");
        m_screenWidth = screenWidth;
        m_screenHeight = screenHeight;
        m_fontSize = fontSize;
    }
     
    bool TextureMappedFont::initialize()
    {
        if (!m_texture.load(m_textureName)) {
            std::cerr << "Couldn't load the font texture" << std::endl;
            return false;
     
        }
     
        glBindTexture(GL_TEXTURE_2D, m_textureID);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    	gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB8, m_texture.getWidth(), 
                          m_texture.getHeight(), GL_RGB, GL_UNSIGNED_BYTE, m_texture.getImageData());
     
     
        float vertices [] = {
            0.0f, 0.0f,
            m_fontSize, 0.0f, 
            m_fontSize, m_fontSize,
            0.0f, m_fontSize
        };
     
        glGenBuffers(1, &amp;m_vertexBuffer);
        glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 8, &amp;vertices[0], GL_STATIC_DRAW);
     
        //Just initialize with something for now, the tex coords are updated
        //for each character printed
        float texCoords [] = {
            0.0f, 0.0f,
            0.0f, 0.0f, 
            0.0f, 0.0f,
            0.0f, 0.0f
        };
     
        glGenBuffers(1, &amp;m_texCoordBuffer);
        glBindBuffer(GL_ARRAY_BUFFER, m_texCoordBuffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 8, &amp;texCoords[0], GL_DYNAMIC_DRAW);
     
        if (!m_shaderProgram->initialize()) {
            std::cerr << "The shader program could not be initialized" << std::endl;
            return false;
        }
     
        m_shaderProgram->bindAttrib(0, "a_Vertex");
        m_shaderProgram->bindAttrib(1, "a_TexCoord0");
        m_shaderProgram->linkProgram();
     
        m_shaderProgram->sendUniform("texture0", 0);
     
        return true;
    }
     
    void TextureMappedFont::printString(const string&amp; str, float x, float y) 
    {
        static float modelviewMatrix[16];
        static float projectionMatrix[16];
     
        m_shaderProgram->bindShader();
     
        setOrthoMode();
     
        float texCoords[8];
     
        glDisable(GL_CULL_FACE);
        glDisable(GL_DEPTH_TEST);
     
        glBindTexture(GL_TEXTURE_2D, m_textureID);
     
        glEnableVertexAttribArray(0);
        glEnableVertexAttribArray(1);
     
        glTranslatef(x, y, 0.0); //Position our text
        for(string::size_type i = 0; i < str.size(); ++i) 
        {
            const float oneOverSixteen = 1.0f / 16.0f;
     
            int ch = int(str[i]);
            float xPos = float(ch % 16) * oneOverSixteen;
            float yPos = float(ch / 16) * oneOverSixteen;
     
            texCoords[0] = xPos;
            texCoords[1] = 1.0f - yPos - oneOverSixteen;
     
            texCoords[2] = xPos + oneOverSixteen;
            texCoords[3] = 1.0f - yPos - oneOverSixteen;
     
            texCoords[4] = xPos + oneOverSixteen;
            texCoords[5] = 1.0f - yPos - 0.001f;
     
            texCoords[6] = xPos;
            texCoords[7] = 1.0f - yPos - 0.001f;
     
            glBindBuffer(GL_ARRAY_BUFFER, m_texCoordBuffer);
            glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float) * 8, &amp;texCoords[0]);
     
            glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
            glVertexAttribPointer((GLint)0, 2, GL_FLOAT, GL_FALSE, 0, 0);
     
            glBindBuffer(GL_ARRAY_BUFFER, m_texCoordBuffer);
            glVertexAttribPointer((GLint)1, 2, GL_FLOAT, GL_FALSE, 0, 0);
     
            glGetFloatv(GL_MODELVIEW_MATRIX, modelviewMatrix);
            glGetFloatv(GL_PROJECTION_MATRIX, projectionMatrix);
     
            m_shaderProgram->sendUniform4x4("modelview_matrix", modelviewMatrix);
            m_shaderProgram->sendUniform4x4("projection_matrix", projectionMatrix);
     
            glDrawArrays(GL_QUADS, 0, 4);
     
            glTranslatef(m_fontSize * 0.80f, 0, 0); //Move along a bit for the next character
        }
     
        glDisableVertexAttribArray(0);
        glDisableVertexAttribArray(1);
     
        unsetOrthoMode();
    }
     
    void TextureMappedFont::setOrthoMode()
    {
        glMatrixMode(GL_PROJECTION);
        glPushMatrix();
        glLoadIdentity();
        glOrtho(0, m_screenWidth, 0, m_screenHeight, -1, 1);
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
        glLoadIdentity();
    }
     
    void TextureMappedFont::unsetOrthoMode()
    {
        glPopMatrix();
        glMatrixMode(GL_PROJECTION);
        glPopMatrix();
        glMatrixMode(GL_MODELVIEW);
    }

    And here's the pertinent calls in my code.

    Code :
    bool ReactionTime::init(int width, int height)
    {
    	// Init OpenGL
    	if (!glGenBuffers || !glBindBuffer || !glBufferData || !glDrawRangeElements)
    		{
    			std::cerr << "VBOs are not supported by your graphics card" << std::endl;
    			return false;
    		}
     
    	screenWidth = width;
    	screenHeight = height;
     
    	glEnable(GL_DEPTH_TEST);
    	glClearColor(0.0f, 0.0f, 0.3f, 1.0f);
     
    	glEnable(GL_CULL_FACE);
    	glEnable(GL_DEPTH_TEST);
    	glDepthFunc(GL_LEQUAL);
     
    	currentStage = RESET;
     
    	plotArrows(CROSS);
    	genBuffers();
    	updateProjection();
     
      // If this code is present, I cannot debug, but my drawn elements do appear if the printstring call is commented out of render
      GLint viewport[4];
      glGetIntegerv(GL_VIEWPORT, viewport);
      m_font = new TextureMappedFont("font.tga", viewport[2], viewport[3], 25.0f);
      if (!m_font->initialize()) {
          std::cerr << "Could not initialize the font" << std::endl;
          return false;
      }
     
    	//Return success
    	return true;
    }
    void ReactionTime::render()
    {
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    	//Load the identity matrix (reset to the default position and orientation)
    	glLoadIdentity();
     
    	updateProjection();
    	//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
     
    	glDrawElements(GL_TRIANGLE_FAN, m_indices.size(), GL_UNSIGNED_INT, 0);
     
            //the following line causes ONLY the text to be displayed, not my drawn elements, even if it's disabled via if statement...if this line is present, the drawelements above does nothing
    	m_font->printString("Simple Reaction Time Task", 0, 0);
    }
    void ReactionTime::genBuffers()
    {
    	glEnableClientState(GL_COLOR_ARRAY);
    	glEnableClientState(GL_VERTEX_ARRAY);
     
    	glGenBuffers(MAX_BUFFERS, &amp;m_vbos[0]);
    	glBindBuffer(GL_ARRAY_BUFFER, m_vbos[VERTEX_BUFFER]); //Bind the vertex buffer
    	glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * m_vertices.size(), &amp;m_vertices[0], GL_DYNAMIC_DRAW); //Send the data to OpenGL
     
    	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vbos[INDEX_BUFFER]); //Bind the index buffer
    	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * m_indices.size(), &amp;m_indices[0], GL_DYNAMIC_DRAW); //Send the data to OpenGL
     
    	glBindBuffer(GL_ARRAY_BUFFER, m_vbos[COLOR_BUFFER]);
    	glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * m_colors.size(), &amp;m_colors[0], GL_DYNAMIC_DRAW); //Send the data to OpenGL
     
    	//Bind the color array, and set the color pointer to point at it
    	glBindBuffer(GL_ARRAY_BUFFER, m_vbos[COLOR_BUFFER]);
    	glColorPointer(3, GL_FLOAT, 0, 0);
     
    	glBindBuffer(GL_ARRAY_BUFFER, m_vbos[VERTEX_BUFFER]);
    	glVertexPointer(3, GL_FLOAT, 0, 0);
     
    }
    void ReactionTime::rebufferData()
    {
    	glBindBuffer(GL_ARRAY_BUFFER, m_vbos[VERTEX_BUFFER]); //Bind the vertex buffer
    	glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * m_vertices.size(), &amp;m_vertices[0], GL_DYNAMIC_DRAW); //Send the new data to OpenGL
     
    	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vbos[INDEX_BUFFER]); //Bind the index buffer
    	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * m_indices.size(), &amp;m_indices[0], GL_DYNAMIC_DRAW); //Send the new data to OpenGL
     
    	glBindBuffer(GL_ARRAY_BUFFER, m_vbos[COLOR_BUFFER]); //Bind the color buffer
    	glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * m_colors.size(), &amp;m_colors[0], GL_DYNAMIC_DRAW); //Send the data to OpenGL
     
     
    }
    void ReactionTime::updateProjection()
    {
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
     
    	float screenAspect, left, right, bottom, top;
     
    	screenAspect = (float) screenWidth / screenHeight;
     
    	left = 0;
    	right = 0;
    	bottom = -8;
    	top = 8;
     
    	left -= (screenAspect * 8);
    	right = (screenAspect * 8);
     
    	glOrtho(left, right, top, bottom, 1.0, 100.0);
     
    	glMatrixMode(GL_MODELVIEW);
    	glLoadIdentity();
    }

    I left out the prepare routine and the plotarrows routine. prepare just decides which symbol gets drawn based on the task logic and calls plotarrows which sets up the vertices and the indices and the colors...

    I can only display either text from the texturemappedfont object or my symbology from the GL_TRIANGLE_FAN...

    Any help would be greatly appreciated it...I'm sure it's just some mode that's getting toggled or switches and clearing everything else when the text is shown, but I don't know what.

  3. #3
    Intern Newbie
    Join Date
    Nov 2011
    Location
    Fairborn, OH
    Posts
    31

    Re: Texture Mapped Fonts from Beginning OpenGL Book

    Anybody have any ideas on this?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •