Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Мультимедия, OpenGL/DirectX > Русский текст в приложении OpenGL


Автор: kurlyak 19.2.2008, 22:59
Кто мне поможет исправить программу что бы печатались русские буквы:

Код

.......
char *lpctstr;
char * lpstr;
strcpy(lpctstr,"Привет");
CharToOem(lpctstr,lpstr);
glCallLists (6, GL_UNSIGNED_BYTE, lpstr); 
.......

Автор: Solomon 19.2.2008, 23:26
kurlyak, почитай http://pmg.org.ru/nehe/nehe13.htm и насколько я знаю для сохранения строки русского текста char не катит нужен wchar_t. 

Автор: kurlyak 20.2.2008, 00:20
Я вот так вот попробывал, но все равно ничего:

Код

USES_CONVERSION;
WCHAR wstr[MAX_PATH];
wcsncpy(wstr, T2W("Привет"), 10);
glCallLists (6, GL_UNSIGNED_BYTE,(const GLvoid*) wstr); 

Автор: kurlyak 20.2.2008, 14:14
вот я порылся по интернету исправил программу. но у людей пишут работает, у меня нет. выводит только английские буквы, русских на экране вобще не видно:
Код

void CText3DDlg::OnPaint() 
{

    // Light values and coordinates
    GLfloat  whiteLight[] = { 0.4f, 0.4f, 0.4f, 1.0f };
    GLfloat  diffuseLight[] = { 0.8f, 0.8f, 0.8f, 1.0f };
    GLfloat  specular[] = { 0.9f, 0.9f, 0.9f, 1.0f};
    //GLfloat     lightPos[] = { -240.0f, 200.0f, 200.0f, 1.0f };
    GLfloat lightPos[] = { -100.0f, 200.0f, 50.0f, 1.0f };

    // Setup the Font characteristics
    HFONT hFont;
    GLYPHMETRICSFLOAT agmf[128]; // Throw away
    LOGFONT logfont;

    logfont.lfHeight = -10;
    logfont.lfWidth = 0;
    logfont.lfEscapement = 0;
    logfont.lfOrientation = 0;
    logfont.lfWeight = FW_BOLD;
    logfont.lfItalic = FALSE;
    logfont.lfUnderline = FALSE;
    logfont.lfStrikeOut = FALSE;
    logfont.lfCharSet = RUSSIAN_CHARSET;//ANSI_CHARSET;
    logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
    logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
    logfont.lfQuality = DEFAULT_QUALITY;
    logfont.lfPitchAndFamily = DEFAULT_PITCH;
    strcpy(logfont.lfFaceName,"Arial");
    
    // Create the font and display list
    hFont = CreateFontIndirect(&logfont);
    pDC->SelectObject (hFont); 

    
    //create display lists for glyphs 0 through 255 with 0.1 extrusion 
    // and default deviation. The display list numbering starts at 1000 
    // (it could be any number). 
    HDC hDC=pDC->GetSafeHdc();
    
    GLuint fontbase = glGenLists(257); 
    wglUseFontOutlines(hDC, 0, 128, fontbase, 0.0f, 0.1f, 
                WGL_FONT_POLYGONS, agmf);    
    //wglUseFontOutlines(hDC, 0, 128, GL_3D_FONT_LIST, 0.0f, 0.1f, 
    //            WGL_FONT_POLYGONS, agmf); 
    
    DeleteObject(hFont);

    glEnable(GL_DEPTH_TEST);    // Hidden surface removal
    glEnable(GL_COLOR_MATERIAL);

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f );

    glEnable(GL_LIGHTING);
    glLightfv(GL_LIGHT0,GL_AMBIENT,whiteLight);
    glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);
    glLightfv(GL_LIGHT0,GL_SPECULAR,specular);
    glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
    glEnable(GL_LIGHT0);


    glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
    glMaterialfv(GL_FRONT, GL_SPECULAR,specular);
    glMateriali(GL_FRONT,GL_SHININESS,128);

    // Blue 3D Text
    glRGB(255, 0, 0);

    // Black background
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f );

    
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glLoadIdentity();
        glTranslatef(-1.0f,0.0 , -8.0f);

        glMatrixMode(GL_MODELVIEW);


        glListBase(fontbase);
        //glListBase(GL_3D_FONT_LIST);
        glPushMatrix();

        glRotatef(6.0f, 1.0f, 0.0f, 0.0f);
        glRotatef(-50.0f, 0.0f, 1.0f, 0.0f);

        char  text[30];
        sprintf(text,"%s","ÏðâèâåòHel");
        
        //русские буквы в пределах 1040-1103

        int n;
        n=strlen(text);
        BYTE *textbytes = new byte[n]; 
            for (int i = 0; i < strlen(text); i++) 
            { 
                textbytes[i] = (byte)text[i]; 

                if (text[i] > 1039 && text[i] < 1104) 
                { 
                    textbytes[i] = (byte)(text[i] + 176); 
                } 
                else 
                { 
                    textbytes[i] = (byte)text[i]; 
                } 
            }

        glCallLists (10, GL_UNSIGNED_BYTE, textbytes); 
    
        glPopMatrix();


        SwapBuffers(wglGetCurrentDC());


    if (IsIconic())
    {
        CPaintDC dc(this); // device context for painting

        SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

        // Center icon in client rectangle
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;

        // Draw the icon
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialog::OnPaint();
    }
}

Автор: kurlyak 21.2.2008, 01:55
я пробным путем нашел следующее. если написать код так то выводиться русская "а":
Код


wglUseFontOutlines(hDC,480 , 128, 1000, 0.0f, 0.1f, 
                WGL_FONT_POLYGONS, agmf); 
glListBase(1000);

если написать код так то выводиться русская "б":
Код

wglUseFontOutlines(hDC,481 , 128, 1000, 0.0f, 0.1f, 
                WGL_FONT_POLYGONS, agmf); 
glListBase(1000);


причем независимо от количества букв в текстовой переменной которую я вывожу- выводиться одна буква - либо "а" - 480 либо "б" - 481. Может это как то надо использовать? Кто подскажет?

Автор: kurlyak 21.2.2008, 04:15
Как мало человеку нужно для счастья... Вот наколупал правильный код для русского 3D текста:
Код

void CText3DDlg::OnPaint() 
{

    // Light values and coordinates
    GLfloat  whiteLight[] = { 0.4f, 0.4f, 0.4f, 1.0f };
    GLfloat  diffuseLight[] = { 0.8f, 0.8f, 0.8f, 1.0f };
    GLfloat  specular[] = { 0.9f, 0.9f, 0.9f, 1.0f};
    //GLfloat     lightPos[] = { -240.0f, 200.0f, 200.0f, 1.0f };
    GLfloat lightPos[] = { -100.0f, 200.0f, 50.0f, 1.0f };

    // Setup the Font characteristics
    //AddFontResource("D:\\MFC Doc\\OpenGL Doc\\Fonts\\edik.ttf");
    //SendMessage( WM_FONTCHANGE, 0, 0); 

    HFONT hFont;
    GLYPHMETRICSFLOAT agmf[128]; // Throw away
    LOGFONT logfont;

    logfont.lfHeight = -10;
    logfont.lfWidth = 0;
    logfont.lfEscapement = 0;
    logfont.lfOrientation = 0;
    logfont.lfWeight = FW_BOLD;
    logfont.lfItalic = FALSE;
    logfont.lfUnderline = FALSE;
    logfont.lfStrikeOut = FALSE;
    logfont.lfCharSet = RUSSIAN_CHARSET; // обязательно
    logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
    logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
    logfont.lfQuality = DEFAULT_QUALITY;
    logfont.lfPitchAndFamily = DEFAULT_PITCH;
    strcpy(logfont.lfFaceName,"Arial");
    
    // Create the font and display list
    hFont = CreateFontIndirect(&logfont);
    pDC->SelectObject (hFont); 

    
    //create display lists for glyphs 0 through 255 with 0.1 extrusion 
    // and default deviation. The display list numbering starts at 1000 
    // (it could be any number). 
    HDC hDC=pDC->GetSafeHdc();

    #define GL_3D_FONT_LIST 1000    
    
    wglUseFontOutlines(hDC,'А' , 128, GL_3D_FONT_LIST, 0.0f, 0.1f, // русская буква А
                WGL_FONT_POLYGONS, agmf); 

    DeleteObject(hFont);

    glEnable(GL_DEPTH_TEST);    // Hidden surface removal
    glEnable(GL_COLOR_MATERIAL);

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f );

    glEnable(GL_LIGHTING);
    glLightfv(GL_LIGHT0,GL_AMBIENT,whiteLight);
    glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);
    glLightfv(GL_LIGHT0,GL_SPECULAR,specular);
    glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
    glEnable(GL_LIGHT0);


    glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
    glMaterialfv(GL_FRONT, GL_SPECULAR,specular);
    glMateriali(GL_FRONT,GL_SHININESS,128);

    // Blue 3D Text
    glRGB(255, 0, 0);

    // Black background
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f );

    
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glLoadIdentity();
        glTranslatef(-2.5f,0.0 , -10.0f);

        glMatrixMode(GL_MODELVIEW);



        glListBase(GL_3D_FONT_LIST);
        
        glPushMatrix();

        glRotatef(6.0f, 1.0f, 0.0f, 0.0f);
        glRotatef(-20.0f, 0.0f, 1.0f, 0.0f);
        
        //char  text[30];
        //sprintf(text,"%s","Привет всем");

        CString text;
        text="Привет всем!";
        
        
        byte *textbytes = new byte[strlen(text)]; 
            for (int i = 0; i < strlen(text); i++) 
            { 
                
                textbytes[i] = (byte)text[i]+64; //смещение 64
                   
               
            }
        
        
        
        glCallLists (text.GetLength() , GL_UNSIGNED_BYTE, textbytes ); 
        
        glPopMatrix();


        SwapBuffers(wglGetCurrentDC());


    if (IsIconic())
    {
        CPaintDC dc(this); // device context for painting

        SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

        // Center icon in client rectangle
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;

        // Draw the icon
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialog::OnPaint();
    }
}

Автор: Rickert 19.5.2008, 11:54
Кто-нибудь вывел нормально русский текст?

Автор: Graf_h 19.5.2008, 12:16
Цитата(Rickert @  19.5.2008,  11:54 Найти цитируемый пост)
Кто-нибудь вывел нормально русский текст?

Можно самому сделать картинку со шрифтом, и выводить его smile! кстати Rickert вы тем самым решите проблему вычисления размера текста, по которой вы создали тему smile! мне кажется это самый правильный выбор!

Автор: Rickert 21.5.2008, 01:05
А ещё идеи? smile

Автор: Malezan 5.6.2008, 13:19
у меня вместо русских букв выводились символы из кодировки Windows Latin 1, пока я в свойствах проекта не изменила Character Set c Use Unicode Character Set на Use Multi-Byte Character Set (project->Properties->General->Character Set)

Добавлено через 7 минут и 42 секунды
Код


// Построение нашего растрового шрифта
GLvoid BuildFont(GLvoid)  
{
    //Мы создаем группу из 256 списков отображения, используя glGenLists(256). 
    //После того, как списки отображения созданы, 
    //переменная base будет содержать номер первого списка.

    
  base = glGenLists(256);  // Выделим место для 256 символов 
  font1 = CreateFont(  -16,                // Высота фонта 
                        0,                // Ширина фонта
                        0,                // Угол отношения
                        0,                // Угол наклона
                        FW_NORMAL,        // Ширина шрифта
                        FALSE,            // Курсив
                        FALSE,            // Подчеркивание
                        FALSE,            // Перечеркивание
                        RUSSIAN_CHARSET,            // Идентификатор набора символов
                        OUT_DEFAULT_PRECIS,                // Точность вывода
                        CLIP_DEFAULT_PRECIS,        // Точность отсечения
                        PROOF_QUALITY,        // Качество вывода
                        FF_DONTCARE|VARIABLE_PITCH,  // Семейство и шаг
                        _T("Arial"));            // Имя шрифта

  // Теперь мы выберем шрифт, привязав его к нашему DC, и построим 96 списков отображения, 
    // начиная с символа 32 (который является пробелом). 
    // Вы можете построить все 256 символов, если Вы хотите. 
    // Проверьте, что Вы удаляете все 256 списков отображения, 
    // когда Вы выходите из программы, и проверьте, что 
    // Вы задаете вместо 32 значение 0 и вместо 96 значение 255 в строке кода ниже.

    SelectObject(hDC, font1);        // Выбрать шрифт, созданный нами 
    wglUseFontBitmaps(hDC, 0, 256, base); // Построить 256 символов 
  
}

GLvoid glPrint(const char *fmt, ...)        // Заказная функция «Печати» GL
{
    char    text[256];   // Место для нашей строки
    va_list    ap;          // Указатель на список аргументов
    if (fmt == NULL)     // Если нет текста
        return;            // Ничего не делать
    
    va_start(ap, fmt);           // Разбор строки переменных
    vsprintf(text, fmt, ap);    // И конвертирование символов в реальные коды
    va_end(ap);                  // Результат помещается в строку
    
    glPushAttrib(GL_LIST_BIT);      // Протолкнуть биты списка отображения 
    glListBase(base - 0);          // Задать базу символа 
    glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);// Текст списками отображения
    glPopAttrib(); // Возврат битов списка отображения 
}

int DrawGLScene( GLvoid )                // Здесь будет происходить вся прорисовка
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );      // Очистить экран и буфер глубины
    glLoadIdentity();              // Сбросить текущую матрицу
    glTranslatef(0.0f,0.0f,-1.0f); // Передвижение на одну единицу вглубь

    glColor3f(1.0f, 1.0f, 1.0f);    // цвет текста

    glRasterPos2f(-0.45f, 0.35f);    // положение текста
    glPrint("АБВГДЕЁЖЗИКЛМНОП");    // вывод текста

    glRasterPos2f(-0.45f, 0.25f);
    glPrint("РСТУФХЦЧШЩЪЫЬЭЮЯ"); 

    glRasterPos2f(-0.45f, 0.15f);
    glPrint("абвгдеёжзиклмноп"); 

    glRasterPos2f(-0.45f, 0.05f);
    glPrint("рстуфхцчшщъыьэюя"); 


    return true;                // Прорисовка прошла успешно
}


Добавлено через 8 минут и 43 секунды
код на основе 13-го урока NeHe
там очень подробно описаны все функции, связанные с выводом текста

Автор: adruha 18.6.2008, 08:47
Вот сто процентов рабочий проект с русским текстом на основе вашего кода.
http://www.zaomiramax.ru/file/opgl.zip

Автор: Brain 7.7.2008, 11:47
Цитата

Вот сто процентов рабочий проект с русским текстом на основе вашего кода.
    

adruha, сделал по вашему проекту свой, но с wglUseFontBitmaps(это необходимо для увеличения производительности в будущем)
Но русские буквы все равно не выводит подскажите что нибудь...
Вот код проекта:
Код

#include <windows.h>
#include <stdarg.h>
#include <Math.h>
#include <stdlib.h>
#include <time.h>
#include "glut.h"
#include <GL\\glu.h>
#include <GL\\gl.h>
#include <GL\\glu.h>
#include <stdio.h>


    #define GL_3D_FONT_LIST 1000    

GLint TimerDelay = 10;

GLfloat windowWidth;
GLfloat windowHeight;
GLuint base;
GLint VNum = 48;

HWND hWnd;
HDC hDC;

bool MyExit=false, text = true, Run = true;


void TimerFunc(int value)
{
    glutPostRedisplay();
    glutTimerFunc(TimerDelay, TimerFunc, 1);
}
void ChangeSize(GLsizei w, GLsizei h)
{
    GLfloat aspectRatio;
    if(h==0)
        h =1;
    //glViewport(10, 10, 250, 200);
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    aspectRatio = (GLfloat)w/(GLfloat)h;
    if(w <= h)
    {
        windowWidth=100;
        windowHeight=100 / aspectRatio;
        gluOrtho2D(0, w , 0, h);
    }
    else
    {
        windowWidth=100 * aspectRatio;
        windowHeight=100;
        gluOrtho2D(0, w , 0, h);
    }
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}
void BuildFont(void)
{
    HFONT hFont;
    GLYPHMETRICSFLOAT agmf[256]; // Throw away
    base = glGenLists (255);
    LOGFONT logfont;
    logfont.lfHeight = -10;
    logfont.lfWidth = 0;
    logfont.lfEscapement = 0;
    logfont.lfOrientation = 0;
    logfont.lfWeight = FW_BOLD;
    logfont.lfItalic = FALSE;
    logfont.lfUnderline = FALSE;
    logfont.lfStrikeOut = FALSE;
    logfont.lfCharSet = RUSSIAN_CHARSET;
    logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
    logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
    logfont.lfQuality = DEFAULT_QUALITY;
    logfont.lfPitchAndFamily = DEFAULT_PITCH;
    wcscpy(logfont.lfFaceName,L"Arial");
    
    // Create the font and display list
    hFont = CreateFontIndirect(&logfont);

    SelectObject(hDC, hFont); 

    wglUseFontBitmaps(hDC,32,224,base);

    DeleteObject(hFont);
  

}
void KillFont(void)                                    // Delete The Font List
{
    glDeleteLists(base, 255);                            // Delete All 96 Characters
}
void glPrint(const char *fmt, ...)                    // Custom GL "Print" Routine
{
    char        text[256];                                // Holds Our String
    va_list        ap;                                        // Pointer To List Of Arguments

    if (fmt == NULL)                                    // If There's No Text
        return;                                            // Do Nothing

    va_start(ap, fmt);                                    // Parses The String For Variables
        vsprintf(text, fmt, ap);                        // And Converts Symbols To Actual Numbers
    va_end(ap);                                            // Results Are Stored In Text

    glPushAttrib(GL_LIST_BIT);                            // Pushes The Display List Bits
    glListBase(base - 32);                                // Sets The Base Character to 32
    glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);    // Draws The Display List Text
    glPopAttrib();                                        // Pops The Display List Bits
}
void RenderScene(void)
{
    glClear(GL_COLOR_BUFFER_BIT);//clear screen
    //glLoadIdentity();                                    // Reset The Current Modelview Matrix
    //glTranslatef(0.0f,0.0f,-1.0f);                        // Move One Unit Into The Screen

    glColor3f(1.0f, 1.0f, 1.0f);

//    glPushMatrix();

    glRasterPos2f(1.0,1.0);
    glPrint("Привет123");

    glBegin(GL_QUADS);
        glVertex2d(100,100);
        glVertex2d(150,150);
    glEnd();

    glutSwapBuffers();
}
void SetupRC(HDC hDC) 
{
    glShadeModel(GL_SMOOTH);                            // Enable Smooth Shading
    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);                // Black Background
    //glClearDepth(1.0f);                                    // Depth Buffer Setup
    //glEnable(GL_DEPTH_TEST);                            // Enables Depth Testing
    //glDepthFunc(GL_LEQUAL);                                // The Type Of Depth Testing To Do
    //glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);    // Really Nice Perspective Calculations

    BuildFont();                                        // Build The Font
}
void KeyFunc(unsigned char KeyChar, int x, int y)
{
    if(KeyChar == '0' || KeyChar == ' ')
    {
        MyExit = true;
        glutDestroyWindow(glutGetWindow());
        exit(0);
    }
}
void SpecialFunc(int Key, int x, int y)
{
}
void main(void)
{
    char* argv="Window";
    int argc=1;

    srand(time(NULL));
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB );
    glutInitWindowSize(640,480);
    glutInit(&argc,&argv);
    glutCreateWindow("OGL");
    //glutFullScreen();
    //glutGameModeString("640x460:8");
    //glutFullScreen();


    //glutInit(&argc,&argv); // 
    //glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);


    hWnd = FindWindowA(NULL, "OGL");
    if(hWnd == NULL || hWnd == INVALID_HANDLE_VALUE)
        MessageBoxA(NULL, "", "", NULL);
    hDC = GetDC(hWnd);

    SetupRC(hDC);
    glShadeModel(GL_SMOOTH);
    glutKeyboardFunc(KeyFunc);
    glutSpecialFunc(SpecialFunc);
    glutDisplayFunc(RenderScene);
    glutReshapeFunc(ChangeSize);
    glutTimerFunc(TimerDelay, TimerFunc, 1);

    glutMainLoop();
}


Автор: Brain 7.7.2008, 19:05
Все, разобрался! Изменил настройки как сказала Malezan - все заработало!

Автор: dandy77 16.9.2008, 09:00
А у меня получилось так как автор с самого начала написал свой пример. Цепляю файлик с проектом для Visual C++ 6.0. И русский текст и трехмерный!

Автор: Фыва 16.12.2008, 23:47
Доброго времени вам.
Не хочешь эту картошку ты.

Конечно в случае, если юникод не нужен в программе, то можно и в свойствах проекта поставить, что Use Multi-Byte Character Set. smile 
Но если такие костыли в силу некоторых причин не применимы, то юзаем другие костыли! smile  smile 

делаем для начала 
Код

wglUseFontBitmaps (hdc,0,1600, base); 

а при выводе текста:
Код

int ggg[222];
  for(int i=0;i<i_len;i++)
  {
       ggg[i]=(((unsigned char*)wc)[i*2])+((unsigned char*)wc)[i*2+1]*256;
     
  }
glCallLists(i_len, GL_INT ,ggg);

И вуаля!
Респект и уважуха kurlyak! 
Да прибудет с тобой научный тык!  smile 


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)