Re[3]: OK
От: Sasparella США  
Дата: 06.05.02 09:08
Оценка: 8 (1)
Здравствуйте LtS, Вы писали:

LtS> Спасибо за ответ,


S>>1. это плохая идея, не стоит так делать

LtS> А какая идея будет получше, если хочется повыводить достаточно простыми методами с достаточным уровнем предсказуемости результатов двумерную графику совместно с трёхмерной.

ПОнятно. У OpenGL точнее его куска под Windows есть чудесная функция wglBuildFontBitmaps.

Она по выбраному на данный момент в DC шрифту строит растровые изображения и кидает их в displayList-ы.

Потом ими можно очень просто выводить текст.

Вот привожу класс обертку для писания шрифтом в OpenGL


GLFont.h

// GLFont.h: interface for the CGLFont class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_GLFONT_H__563EFF12_A150_47EB_86C1_6F1E2B420978__INCLUDED_)
#define AFX_GLFONT_H__563EFF12_A150_47EB_86C1_6F1E2B420978__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <gl\gl.h>
#include <stdarg.h>        
#include "vector.hpp"

class CGLFont  
{
public:
    bool Print(const dvector dvPos, const char *fmt, ...);
    CSize GetTextSize(LPCTSTR pText);
    bool VerifyContext();
    bool Create(TCHAR* szFaceName = "Arial", int iHeight = -12, bool bBold=false, bool bItalic=false);
    bool KillFont();
    CGLFont();
    virtual ~CGLFont();
private:
    
    HGLRC m_hNativeGLRC;        // Holds HGLRC in which the font has been created
    HDC   m_hNativeDC;        // Holds HGLRC in which the font has been created
    bool m_bFontCreated;
    GLuint m_uiBase;
    HFONT m_hFont;

};

#endif // !defined(AFX_GLFONT_H__563EFF12_A150_47EB_86C1_6F1E2B420978__INCLUDED_)


// GLFont.cpp: implementation of the CGLFont class.
//
//    Purpose: OpenGL raster font wrapper
//    Author:    Alexander Bijamov aka Sasparella
//    Created: N/A
//    
//    Last Modified: 10 April 2002              by A. Bijamov.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "GLFont.h"
#include "OpenGL.h"
#include "routines.h"
#include <gl\gl.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#define NUM_CHARACTERS 96

CGLFont::CGLFont()
{
    m_hNativeGLRC = NULL;
    m_hNativeDC = NULL;
    m_bFontCreated = false;
    m_hFont = NULL;
}

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

bool CGLFont::Create(TCHAR *szFaceName, int iHeight, bool bBold, bool bItalic)
{    

    if (m_bFontCreated && (!KillFont())) return false; // could not kill font - probably different context

    HDC hDC = ::wglGetCurrentDC();
    if (!hDC) return false;
    
    m_hFont = CreateFont(iHeight,
                        0,                                // Width Of Font
                        0,                                // Angle Of Escapement
                        0,                                // Orientation Angle
                        bBold? FW_BOLD:FW_NORMAL,        // Font Weight
                        bItalic,                        // Italic
                        FALSE,                            // Underline
                        FALSE,                            // Strikeout
                        ANSI_CHARSET,                    // Character Set Identifier
                        OUT_TT_PRECIS,                    // Output Precision
                        CLIP_DEFAULT_PRECIS,            // Clipping Precision
                        ANTIALIASED_QUALITY,            // Output Quality
                        FF_DONTCARE|DEFAULT_PITCH,        // Family And Pitch
                        szFaceName);                    // Font Name

    if (!m_hFont)
    {
        DisplayErrorMessage("CreateFont");
        return false;
    }

    m_uiBase = glGenLists(NUM_CHARACTERS);

    HFONT hOldFnt = (HFONT)SelectObject(hDC, (HGDIOBJ)m_hFont);    // Selects The Font We Want
    

    VERIFY(wglUseFontBitmaps(hDC, 32, NUM_CHARACTERS, m_uiBase));                // Builds 96 Characters Starting At Character 32
    
    glFlush();

    SelectObject(hDC, (HGDIOBJ)hOldFnt);
    

    m_hNativeGLRC = :: wglGetCurrentContext();
    m_hNativeDC   = hDC;
    m_bFontCreated = true;
    return true;
}

bool CGLFont::KillFont()
{
    //if (!VerifyContext()) return false; // you try to kill font, but you did not create it...
    if (!m_bFontCreated) return false;
    CToggleContext tc(m_hNativeDC, m_hNativeGLRC);
    ASSERT(::wglGetCurrentContext());

    glDeleteLists(m_uiBase, NUM_CHARACTERS);    
    DeleteObject(m_hFont);
    m_bFontCreated = false;
    return true;
}

bool CGLFont::VerifyContext()
{
    return (m_bFontCreated && ::wglGetCurrentContext()==m_hNativeGLRC && ::wglGetCurrentDC()==m_hNativeDC );
}

CSize CGLFont::GetTextSize(LPCTSTR pText)
{
    if (!m_bFontCreated) return CSize(0,0);
    
    HFONT hOldFnt = (HFONT)SelectObject(m_hNativeDC, (HGDIOBJ)m_hFont);    
    
    CDC* pDC = CDC::FromHandle(m_hNativeDC);
    CSize size = pDC->GetTextExtent(CString(pText));
    SelectObject(m_hNativeDC, (HGDIOBJ)hOldFnt);    

    return size;
}

bool CGLFont::Print(const dvector dvPos, const char *fmt, ...)        
{
    if (!VerifyContext()) return false;

    char        text[256];                            
    va_list        ap;                                    

    if (fmt == NULL)                                    
        return true;

    va_start(ap, fmt);
        vsprintf(text, fmt, ap);
    va_end(ap);

    glRasterPos3d(dvPos.x,dvPos.y,dvPos.z);

    glPushAttrib(GL_LIST_BIT);
    glListBase(m_uiBase - 32);
    
    glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);
    
    glPopAttrib();
    return true;
}



и вспомогательный клсаа


class CToggleContext
{
public:
    ~CToggleContext();
    CToggleContext(HDC hDC, HGLRC hGLRC);
private:
    HGLRC m_hMemoGLRC;
    HDC m_hMemoDC;
};

CToggleContext::CToggleContext(HDC hDC, HGLRC hGLRC)
{
    m_hMemoDC = wglGetCurrentDC();
    m_hMemoGLRC = wglGetCurrentContext();

    if (!wglMakeCurrent(hDC,hGLRC)) 
        DisplayErrorMessage("MakeCurrent");
}


CToggleContext::~CToggleContext()
{
    if (!wglMakeCurrent(m_hMemoDC,m_hMemoGLRC)) DisplayErrorMessage("MakeCurrent");
}


Кажись все понятно должно быть.


В классе вашего OpenGL окна созда5ете CGLfont glFont;

в инициализации после инита контекста вызываете glFont.Create(....)

а в очистке — glFont.KillFont() (до убивания контекста)



Рисовать —
glFont.Print(const dvector dvPos, const char *fmt, ...);

dvPos — это обычные координаты, как у glVertex. В этом месте и будет выведен текси.


Enjoy.


Саша.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.