Перевёрнутые символы в wglUseFontOutlines

Тема в разделе "WASM.OpenGL", создана пользователем DEEP, 5 июл 2011.

  1. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    Доброго времени суток экспертам!

    Сегодня столкнулся с очень странным поведением функции wglUseFontOutlines.
    Сами символы выводятся в штатном режиме, однако все они повёрнуты на некоторый угол.
    Причём угол, насколько могу судить, является функцией от позиции вызова wglUseFontOutlines внутри кода…
    Эффект проявляется только на виртуальной машине (WinXP SP2 на VirtualBox 4.0.10), «нормальные» Винды, а также, как ни странно, WINE, отображают символы прямо.
    Как Вы считаете, что может служить причиной?

    Поскольку для меня устранение этого глюка критично, уже готовлю запасные решения, такие как перегон символов на текстуры или создание tesselated-объектов вручную по кривым Безье, полученным из GDI32.GetGlyphOutline. Однако хотелось бы обойтись малой кровью.

    Код:
    Код (Text):
    1. .386
    2. .model flat, stdcall
    3. option casemap:none
    4.  
    5. include c:\masm32\include\windows.inc
    6.  
    7. include c:\masm32\include\user32.inc
    8. include c:\masm32\include\kernel32.inc
    9. include c:\masm32\include\gdi32.inc
    10. include c:\masm32\include\opengl32.inc
    11. include c:\masm32\include\glu32.inc
    12.  
    13. includelib c:\masm32\lib\user32.lib
    14. includelib c:\masm32\lib\kernel32.lib
    15. includelib c:\masm32\lib\gdi32.lib
    16. includelib c:\masm32\lib\opengl32.lib
    17. includelib c:\masm32\lib\glu32.lib
    18.  
    19. include c:\masm32\macros\macros.asm
    20.  
    21. ;const
    22.   WW equ 600
    23.   WH equ 400
    24.   IC equ 1
    25.   GLF_START_LIST equ 1000
    26.  
    27. .code
    28.  
    29.   WN db "TEST1", 0
    30.   WC db "OGLclass", 0
    31.   WF db "Verdana", 0
    32.   TT db "ABC"
    33.   TL equ $ - TT
    34.  
    35. @main:
    36.   xor edi, edi
    37.  
    38.   invoke GetModuleHandle, edi
    39.   mov esi, eax
    40.  
    41.   push offset WC
    42.   push edi
    43.   push COLOR_BTNFACE + 1
    44.   invoke LoadCursor, edi, IDC_HAND
    45.   push eax
    46.   invoke LoadIcon, esi, IC
    47.   push eax
    48.   push esi
    49.   push edi
    50.   push edi
    51.   push offset WindowProc
    52.   push CS_HREDRAW or CS_VREDRAW
    53.   mov ebp, esp
    54.  
    55.   invoke RegisterClass, ebp
    56.  
    57.   push edi
    58.   push edi
    59.   push edi
    60.   push edi
    61.   push WH
    62.   push WW
    63.   invoke GetSystemMetrics, SM_CYSCREEN
    64.   sub eax, WH
    65.   shr eax, 1
    66.   push eax
    67.   invoke GetSystemMetrics, SM_CXSCREEN
    68.   sub eax, WW
    69.   shr eax, 1
    70.   push eax
    71.   push WS_VISIBLE or WS_SYSMENU
    72.   push offset WN
    73.   push offset WC
    74.   push WS_EX_CLIENTEDGE
    75.   CALL CreateWindowEx
    76.   invoke ShowWindow, eax, SW_SHOWNORMAL
    77.  
    78.   push edi
    79.   push edi
    80.   push edi
    81.   jmp @mget
    82.   @loop:
    83.     invoke DispatchMessage, ebp
    84.   @mget:
    85.     push ebp
    86.     call GetMessage
    87.     sub esp, 12
    88.     test eax, eax
    89.   jne @loop
    90.  
    91.   invoke ExitProcess, edi
    92.  
    93.  
    94.  
    95. WindowProc proc hWnd: dword, uMsg: dword, wPrm: dword, lPrm: dword
    96.  
    97.   xor eax, eax
    98.   cmp dword ptr [uMsg], WM_PAINT
    99.   je @WM_PAINT
    100.   cmp dword ptr [uMsg], WM_SIZE
    101.   je @WM_SIZE
    102.   cmp dword ptr [uMsg], WM_DESTROY
    103.   je @WM_DESTROY
    104.   cmp dword ptr [uMsg], WM_SYSCOLORCHANGE
    105.   je @GCOL
    106.   cmp dword ptr [uMsg], WM_CREATE
    107.   jne @DEFAULT
    108.  
    109.     mov edi, @main
    110.     mov ecx, SIZEOF(PIXELFORMATDESCRIPTOR)/4 + 1
    111.     rep lodsd
    112.  
    113.     mov (PIXELFORMATDESCRIPTOR ptr[@main]).dwFlags, PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER
    114.     mov (PIXELFORMATDESCRIPTOR ptr[@main]).iPixelType, PFD_TYPE_RGBA
    115.     mov (PIXELFORMATDESCRIPTOR ptr[@main]).cColorBits, 32
    116.     mov (PIXELFORMATDESCRIPTOR ptr[@main]).dwLayerMask, PFD_MAIN_PLANE
    117.  
    118.     invoke CreateFont, -10, eax, eax, eax, FW_BOLD, eax, eax, eax, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH or FF_DONTCARE, offset WF
    119.     push eax
    120.     push eax
    121.  
    122.     invoke GetDC, hWnd
    123.     mov dword ptr [@main + 4], eax
    124.     mov edi, eax
    125.     push edi
    126.     call SelectObject
    127.     push eax
    128.  
    129.     invoke ChoosePixelFormat, edi, @main
    130.     invoke SetPixelFormat, edi, eax, @main
    131.     invoke wglCreateContext, edi
    132.     mov dword ptr [@main], eax
    133.     invoke wglMakeCurrent, edi, eax
    134.     invoke glHint, GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST
    135.  
    136.     invoke glPointSize, FP4(20.0)
    137.  
    138.     invoke glEnable, GL_COLOR_MATERIAL
    139.     invoke glEnable, GL_DEPTH_TEST
    140.     invoke glEnable, GL_LIGHTING
    141.     invoke glEnable, GL_LIGHT0
    142.  
    143.     invoke wglUseFontOutlines, dword ptr [@main + 4], 0, 255, GLF_START_LIST, FP4(0.0), FP4(0.0), WGL_FONT_POLYGONS, 0
    144.  
    145.     push edi
    146.     call SelectObject
    147.     call DeleteObject
    148.  
    149.  
    150.   @GCOL:
    151.     invoke GetSysColor, COLOR_BTNFACE
    152.     push 255
    153.     fild dword ptr [esp]
    154.     fld1
    155.     fstp dword ptr [esp]
    156.     fld st(0)
    157.     fld st(0)
    158.  
    159.     mov edx, eax
    160.     shr edx, 16
    161.     movzx edx, dl
    162.     push edx
    163.     fidivr dword ptr [esp]
    164.     fstp dword ptr [esp]
    165.  
    166.     movzx edx, ah
    167.     push edx
    168.     fidivr dword ptr [esp]
    169.     fstp dword ptr [esp]
    170.  
    171.     movzx edx, al
    172.     push edx
    173.     fidivr dword ptr [esp]
    174.     fstp dword ptr [esp]
    175.  
    176.     call glClearColor
    177.     xor eax, eax
    178.     ret
    179.  
    180.  
    181.   @WM_PAINT:
    182.     invoke BeginPaint, hWnd, @main + 8
    183.     invoke glClear, GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT
    184.  
    185.     invoke glColor3ub, 255, 127, 0
    186.  
    187.  
    188.     invoke glPushMatrix
    189.       invoke glScalef, FP4(10.0), FP4(10.0), FP4(10.0)
    190.       invoke glListBase, GLF_START_LIST
    191.       invoke glCallLists, TL, GL_UNSIGNED_BYTE, offset TT
    192.     invoke glPopMatrix
    193.  
    194. ;    invoke glBegin, GL_LINE_LOOP
    195.  
    196. ;    invoke glVertex2f, FP4(0.0), FP4(0.0)
    197. ;    invoke glVertex2f, FP4(1.0), FP4(-1.0)
    198. ;    invoke glVertex2f, FP4(1.0), FP4(1.0)
    199.  
    200. ;    invoke glEnd
    201.  
    202.  
    203.     invoke SwapBuffers, dword ptr [@main + 8]
    204.     invoke EndPaint, hWnd, @main + 8
    205.     xor eax, eax
    206.     ret
    207.  
    208.  
    209.   @WM_SIZE:
    210.     mov eax, lPrm
    211.     mov edx, eax
    212.     movzx eax, ax
    213.     shr edx, 16
    214.  
    215.     xor ecx, ecx
    216.  
    217.     push 408f4000h;          <<< 1000.0
    218.     push ecx
    219.  
    220.     push 3fba0000h;          <<< 0.1
    221.     push ecx
    222.  
    223.     push eax
    224.     fild dword ptr [esp]
    225.     push edx
    226.     fidiv dword ptr [esp]
    227.     fstp qword ptr [esp];    <<< ratio
    228.  
    229.     push 40468000h;          <<< 45.0
    230.     push ecx
    231.  
    232.     invoke glViewport, 0, 0, eax, edx
    233.  
    234.     invoke glMatrixMode, GL_PROJECTION
    235.     invoke glLoadIdentity
    236.  
    237.     call gluPerspective
    238.     invoke glMatrixMode, GL_MODELVIEW
    239.     invoke glLoadIdentity
    240.  
    241.     invoke glTranslatef, FP4(0.0), FP4(0.0), FP4(-50.0)
    242.     ret
    243.  
    244.  
    245.   @WM_DESTROY:
    246.     push eax
    247.     push eax
    248.     mov edi, dword ptr [@main + 4]
    249.     invoke glDeleteLists, GLF_START_LIST, 256
    250.     call wglMakeCurrent
    251.     invoke wglDeleteContext, dword ptr [@main]
    252.     invoke ReleaseDC, hWnd, edi
    253.     invoke DeleteDC, edi
    254.  
    255.     invoke PostQuitMessage, eax
    256.     xor eax, eax
    257.     ret
    258.  
    259.  
    260.   @DEFAULT:
    261.     invoke DefWindowProc, hWnd, uMsg, wPrm, lPrm
    262.     ret
    263.  
    264. WindowProc endp
    265.  
    266. end @main
    Обратите внимание, что в программе присутствует прямая запись в кодовый сегмент (линкер делает его перезаписываемым, когда склеивает с сегментами данных и ресурсов), однако по всем расчётам, и подтверждающим их экспериментам, записываемое неспособно достать до места вызова.

    Заранее спасибо за совет.

    [U:]
    На всякий случай, вот код сборочного батника:
    Код (Text):
    1. @echo off
    2.  
    3. if exist oOGL.obj del oOGL.obj
    4. if exist oOGL.exe del oOGL.exe
    5.  
    6. C:\MASM32\BIN\ml.exe /c /coff oOGL.asm
    7. if errorlevel 1 goto errasm
    8.  
    9. C:\MASM32\BIN\PoLink.exe /SUBSYSTEM:WINDOWS /merge:.data=.text /merge:.rsrc=.text oOGL.obj > nul
    10. if errorlevel 1 goto errlink
    11. dir oOGL.exe
    12. goto TheEnd
    13.  
    14. :errlink
    15. echo There has been an error while linking this project.
    16. goto TheEnd
    17.  
    18. :errasm
    19. echo There has been an error while assembling this project.
    20. goto TheEnd
    21.  
    22. :TheEnd
    23. if exist oOGL.obj del oOGL.obj
    24.  
    25. pause
    А вот так вышесказанное выглядит на виртуальной машине:
    [​IMG]
    А вот так оно должно выглядеть:
    [​IMG]
     
  2. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    Ох. Вот она, сила форумов. После того как запостил, начинаешь вчитываться в собственный код.
    Проблема была вот в этой строке:
    Код (Text):
    1. rep lodsd
    На виртуальной машине она отчего-то портит EAX.
    Решается это элементарно, заменой в последующем вызове
    Код (Text):
    1. invoke CreateFont, -10, eax, eax, eax, FW_BOLD, eax, eax, eax, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH or FF_DONTCARE, offset WF
    всех EAX на ECX, который, поскольку из REP мы вышли, с гарантией равен 0.

    И вообще, на месте LODSD должен был быть STOSD.

    Прошу прощения за беспокойство, тему можно удалять.