Растянутый примитив

Тема в разделе "WASM.OpenGL", создана пользователем Rito, 24 июн 2008.

  1. Rito

    Rito New Member

    Публикаций:
    0
    Регистрация:
    30 май 2008
    Сообщения:
    59
    Подскажите кто может.
    Есть такой код, всё работает, только не так как надо.
    Код (Text):
    1. format PE GUI 4.0
    2. entry start
    3.  
    4. include 'g:\fasm\include\win32a.inc'
    5.  
    6. include 'g:\fasm\include\OPENGL.inc'
    7. ;include 'g:\fasm\include\opengl_macros.inc'
    8. ;include 'g:\fasm\include\opengl_const.inc'
    9.  
    10.  
    11. section '.data' data readable writeable
    12. wHMain         dd   ?
    13. wHInstance     dd   ?
    14.  
    15. wTitle         db   'Tutorial 3',0 ;name of our window
    16. wClsName       db   'TUT03',0      ;name of our window class
    17.  
    18. wMsg      MSG
    19. wCls      WNDCLASS
    20.  
    21. pfd         PIXELFORMATDESCRIPTOR   <>
    22. g_hDC           dd          0
    23. g_hRC           dd          0
    24. PixelFormat     dd          0
    25.  
    26. theta           dd          0
    27. delta           dd          0.1
    28.  
    29. section '.code' code readable executable
    30.      start:
    31.           ;***********************
    32.           invoke    GetModuleHandle,NULL
    33.           mov  [wHInstance],eax
    34.           mov  [wCls.hInstance],eax
    35.           mov  [wCls.style],CS_HREDRAW or CS_VREDRAW
    36.           mov  [wCls.lpfnWndProc],window_procedure
    37.           mov  [wCls.lpszClassName],wClsName
    38.           mov  [wCls.hbrBackground],COLOR_WINDOW+1
    39.           invoke    LoadIcon,NULL,IDI_APPLICATION
    40.           mov  [wCls.hIcon],eax
    41.           invoke    LoadCursor,NULL,IDC_ARROW
    42.           mov  [wCls.hCursor],eax
    43.           invoke    RegisterClass,wCls
    44.  
    45.           ;***********************
    46.           invoke    CreateWindowEx,\
    47.                          0,\
    48.                          wClsName,\
    49.                          wTitle,\
    50.                          WS_OVERLAPPEDWINDOW,\
    51.                          CW_USEDEFAULT,\
    52.                          CW_USEDEFAULT,\
    53.                          CW_USEDEFAULT,\
    54.                          CW_USEDEFAULT,\
    55.                          NULL,\
    56.                          NULL,\
    57.                          [wHInstance],\
    58.                          NULL
    59.                     mov  [wHMain],eax
    60.  
    61.            ;***********************
    62.     call    InitOpenGL
    63.    
    64.           ;***********************
    65.           invoke    ShowWindow,[wHMain],SW_SHOW
    66.  
    67.           ;***********************
    68.           window_message_loop_start:
    69.         invoke    PeekMessage, wMsg,NULL,0,0,PM_REMOVE
    70.         cmp eax,1
    71.         jnz __render
    72.             cmp [wMsg.message], WM_QUIT
    73.             jz  window_message_loop_end
    74.             ;je window_message_loop_end
    75.         invoke    TranslateMessage,wMsg
    76.         invoke    DispatchMessage,wMsg
    77.             jmp  window_message_loop_start
    78. __render:
    79.             call    Render
    80.             jmp  window_message_loop_start
    81.           window_message_loop_end:
    82.                invoke    ExitProcess,0
    83.  
    84.  
    85. ;***************************
    86. ;
    87. ;***************************
    88.           proc window_procedure,hWnd,uMsg,wParam,lParam
    89.                push ebx esi edi    ;eventhough the API would preserved, but play safe :p
    90.                cmp  [uMsg],WM_DESTROY
    91.                je   wmDESTROY
    92.  
    93.                wmDEFAULT:
    94.                     invoke    DefWindowProc,[hWnd],[uMsg],[wParam],[lParam]
    95.                               jmp  wmBYE
    96.                wmDESTROY:
    97.                     invoke    PostQuitMessage,0
    98.  
    99.                wmBYE:
    100.                     pop  edi esi ebx
    101.                     ret
    102.           endp
    103.  
    104. ;***********************
    105. ;Рендер сцены
    106. ;***********************
    107. Render:
    108.     invoke  glClear,GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT
    109.     invoke  glClearColor,1.0f, 0.0f, 0.0f, 0.0f
    110.     invoke  glLoadIdentity
    111.  
    112.     ;invoke gluLookAt,  0.0,0.0f,   0.0,-1.0f,  0.0,-1.0f,\
    113.     ;           0.0,0.0f,   0.0,-2.0f,  0.0,1.0f,\
    114.     ;           0.0,0.0f,   0.0,1.0f,   0.0,0.0f
    115.  
    116.     invoke  glTranslatef,0.0f,0.0f, -25.0f
    117.  
    118.     invoke glRotatef,[theta],0.0,0.0,1.0
    119.  
    120.     fld [theta]
    121.     fadd [delta]
    122.     fstp [theta]
    123.  
    124.     invoke  glBegin,GL_TRIANGLES
    125.         invoke  glColor3f,0.0,1.0,1.0      
    126.             invoke  glVertex3f, -0.5,   -0.5,   -1.0
    127.         invoke  glColor3f,1.0,1.0,0.0      
    128.             invoke  glVertex3f, 0.5,    -0.5,   -1.0
    129.         invoke  glColor3f,0.0,1.0,1.0      
    130.             invoke  glVertex3f, 0.5,    0.5,    -1.0
    131.     invoke  glEnd
    132.  
    133.     invoke  SwapBuffers,[g_hDC]
    134.     ret
    135.  
    136. InitOpenGL:
    137.     mov [pfd.nSize],sizeof.PIXELFORMATDESCRIPTOR
    138.     mov [pfd.nVersion],1
    139.     mov [pfd.dwFlags],PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER
    140.     mov [pfd.iPixelType],PFD_TYPE_RGBA
    141.     mov [pfd.cColorBits],32
    142.     mov [pfd.cRedBits],0
    143.     mov [pfd.cRedShift],0
    144.     mov [pfd.cGreenBits],0
    145.     mov [pfd.cGreenShift],0
    146.     mov [pfd.cBlueBits],0
    147.     mov [pfd.cBlueShift],0
    148.     mov [pfd.cAlphaBits],0
    149.     mov [pfd.cAlphaShift],0
    150.     mov [pfd.cAccumBits],0
    151.     mov [pfd.cAccumRedBits],0
    152.     mov [pfd.cAccumGreenBits],0
    153.     mov [pfd.cAccumBlueBits],0
    154.     mov [pfd.cAccumAlphaBits],0
    155.     mov [pfd.cDepthBits],16
    156.     mov [pfd.cStencilBits],0
    157.     mov [pfd.cAuxBuffers],0
    158.     mov [pfd.iLayerType],PFD_MAIN_PLANE
    159.     mov [pfd.bReserved],0
    160.     mov [pfd.dwLayerMask],0
    161.     mov [pfd.dwVisibleMask],0
    162.     mov [pfd.dwDamageMask],0
    163.    
    164.     invoke  GetDC,[wHMain]
    165.     mov [g_hDC],eax
    166.  
    167.     invoke  ChoosePixelFormat,[g_hDC],pfd
    168.     mov [PixelFormat],eax
    169.  
    170.     invoke  SetPixelFormat,[g_hDC],[PixelFormat],pfd
    171.  
    172.     invoke  wglCreateContext,[g_hDC]
    173.     mov [g_hRC],eax
    174.  
    175.     invoke  wglMakeCurrent,[g_hDC],[g_hRC]
    176.  
    177.     invoke  glShadeModel,GL_SMOOTH
    178.  
    179.     ;invoke glClearDepth,1.0f
    180.     invoke  glEnable,GL_DEPTH_TEST
    181.     ;invoke glDepthFunc,GL_LESS
    182.  
    183.     invoke  glClearColor,0,0,0,0
    184.  
    185.     invoke  glHint,GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST
    186.  
    187.     invoke  glViewport,0,0,800,600
    188.  
    189.     invoke  glMatrixMode,GL_PROJECTION
    190.     ;invoke glLoadIdentity
    191.  
    192.     invoke  gluPerspective,0,45.0f,0,1.0f,0,0.1f,0,100.0f
    193.     ;glcall gluPerspective,90.0,ratio,0.1,100.0
    194.     ;invoke gluPerspective,45.0f,1.0f,1.0f,100.0f
    195.  
    196.     invoke  glMatrixMode,GL_MODELVIEW
    197.     ;invoke glLoadIdentity 
    198.     ret
    В результате получается наверное треугольник, но слишком растянутый какой то. Хотя должен быть нормальным с координатами:
    Код (Text):
    1. invoke  glVertex3f, -0.5,   -0.5,   -1.0
    2. invoke  glVertex3f, 0.5,    -0.5,   -1.0
    3. invoke  glVertex3f, 0.5,    0.5,    -1.0
     
  2. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    В результате создается окно неправильного размера (не квадратное)... Затем, это окно нормируется в соответствии с кодом инициализации OpenGL, и естественно, получаем искажения. Более того,
    задает вытянутый по Х вьюпорт (что в общем случае немного не то, что хотелось бы. В идеале, надо читать текущие размеры окна, и делать вьюпорт соответствующих размеров. А потом вычислять соотношение сторон, и изменять масштаб, чтобы избежать искажения)

    Попробуй четко задать размер окна, чтоб получить одинаковую размерность по X и Y ;) (естественно, учитывая, что некоторая часть по Y у окна отводится под системный заголовок). Вот тогда треугольник будет правильным.

    Вопрос на воображение: что будет, если мышкой изменять границы окна с изображенным примитивом? ;)))

    То есть, чтоб совсем было понятно, надо делать как-то так:
    Код (Text):
    1. LOCAL rc:RECT
    2.     ...
    3.     invoke wglMakeCurrent,[hdc],eax
    4.     invoke GetClientRect,[hWnd],addr rc
    затем
    Код (Text):
    1.     mov eax, [rc.right]
    2.     mov edx, [rc.bottom]
    3.     invoke  glViewport,0,0,eax,edx
    А при смене размеров окна, ловить WM_SIZE и опять менять вьюпорт в соответствии с новыми размерами, и перерисовывать сцену (иначе уменьшение размеров оставит нам для просмотра только верхний левый угол, а увеличение оставит кусок незадействованного пространства - неэстетично!).
    Чтобы избежать искажений на прямоугольном окне, можно после glLoadIdentity поделить размер окна по X на размер по Y (FPU! что естественно...), и выставить glScale с правильными параметрами.

    Или заранее (в обучающих целях, чтоб не возится с FPU) создавать окно почти квадратного размера, а вьюпорт задавать как 0,0, MIN([rc.bottom],[rc.right]), MIN([rc.bottom],[rc.right])