glViewport错误地将法线坐标映射到窗口坐标?

时间:2015-06-08 12:40:40

标签: opengl racket

我以为我可以通过这些调用让opengl将坐标(-1,-1)和(1,1)映射到像素(0,0)和(宽度,高度):

(gl-ortho -1 1 -1 1 -1 1)

(gl-viewport 0 0 (* 3/2 width) (* 3/2 height))

然而,从(-1,-1)到(1,1)绘制的矩形仅到达窗口左边和底边的三分之二。我可以通过使用

来解决这个问题
#lang racket/base

(require racket/class)
(require racket/gui/base)
(require sgl)
(require sgl/gl-vectors)

(define game-canvas%
  (class canvas%
    (inherit refresh with-gl-context swap-gl-buffers)

    (super-new)

    (define (next x)
      (modulo (+ 1 x) 100))

    (define x-factor 0)

    (define/override (on-paint)
      (with-gl-context
       (lambda ()
         (gl-clear-color 0.0 0.0 0.0 0.0)
         (gl-clear 'color-buffer-bit 'depth-buffer-bit)
         (gl-color 1 1 0) (gl-rect -1 -1 (+ -1 (* 2 x-factor 1/100)) 1)
         (swap-gl-buffers)
         (gl-flush))))

    (define/public (STEP)
      (set! x-factor (next x-factor))
      (refresh)
      (sleep/yield 1/60)
      (queue-callback (lambda _ (send this STEP) #f)))

    (define/override (on-event e)
      (when (is-a? e mouse-event%)
        (when (eq? (send e get-event-type) 'left-down)
          (exit 0))))

    (define/override (on-size width height)
      (with-gl-context
       (lambda ()
         (let ((aspect (/ width height)))
           ;(gl-viewport 0 0 width height)
           (gl-viewport 0 0 (* 3/2 width) (* 3/2 height))
           (gl-matrix-mode 'projection)
           (gl-load-identity)
           (gl-ortho (* aspect -1) (* aspect 1) -1 1 -1 1)
           (gl-enable 'depth-test))))
      (refresh))))

(module+ main
  (define-values (W H) (get-display-size #t))
  (define f (new frame%
                 [style '(no-resize-border
                          no-caption
                          no-system-menu
                          hide-menu-bar)]
                 [label "glui"]
                 [width (/ W 2)]
                 [height (/ H 2)]))
  (define c (new game-canvas%
                 [parent f]
                 [style '(gl)]))
  (send f show #t)
  (send f center 'both)

  (send c STEP))

但这对我来说似乎不正确。我做错了什么?

这是DrRacket的片段

<p id=displayText> <p>
<script type="text/javascript">
    function doSomeThing()
    {
      var para = document.getElementById('displayText');
      para.innerHTML = para.innerHTML + text1;
      para.innerHTML = para.innerHTML + text2;
      para.innerHTML = para.innerHTML + text3;
    }
</script>

Screenshot of the above

2 个答案:

答案 0 :(得分:2)

您的Windows系统上的显示缩放设置似乎等于150%。 OpenGL不了解它,你需要手动扩展。

(define/override (on-size width height)
  ...
  (let ([scale (get-display-backing-scale)]
        [scaled-width (exact-truncate (* width scale))]
        [scaled-height (exact-truncate (* height scale))])
    ...
    (gl-viewport 0 0 scaled-width scaled-height)

答案 1 :(得分:1)

您似乎没有直接使用(gl-ortho -1 1 -1 1 -1 1),而是在aspect中另外将(gl-ortho (* aspect -1) (* aspect 1) -1 1 -1 1)的左右值相乘。这是错误的,因为-1和1将始终指向左右边框(如果其他值是指定的),与宽高比无关。所以我会完全删除aspect并使用-1和1.这是适用于我的16/9显示的代码:

#lang racket/base

(require racket/class)
(require racket/gui/base)
(require sgl)
(require sgl/gl-vectors)

(define game-canvas%
  (class canvas%
    (inherit refresh with-gl-context swap-gl-buffers)

    (super-new)

    (define (next x)
      (modulo (+ 1 x) 100))

    (define x-factor 0)

    (define/override (on-paint)
      (with-gl-context
       (lambda ()
         (gl-clear-color 0.0 0.0 0.0 0.0)
         (gl-clear 'color-buffer-bit 'depth-buffer-bit)
         (gl-color 1 1 0) (gl-rect -1 -1 (+ -1 (* 2 x-factor 1/100)) 1)
         (swap-gl-buffers)
         (gl-flush))))

    (define/public (STEP)
      (set! x-factor (next x-factor))
      (refresh)
      (sleep/yield 1/60)
      (queue-callback (lambda _ (send this STEP) #f)))

    (define/override (on-event e)
      (when (is-a? e mouse-event%)
        (when (eq? (send e get-event-type) 'left-down)
          (exit 0))))

    (define/override (on-size width height)
      (with-gl-context
       (lambda ()
         ;; Changes here
         (gl-viewport 0 0 width height)
         (gl-matrix-mode 'projection)
         (gl-load-identity)
         (gl-ortho  -1  1 -1 1 -1 1)
         (gl-enable 'depth-test)))
         ;; End of changes
      (refresh))))

(module+ main
  (define-values (W H) (get-display-size #t))
  (define f (new frame%
                 [style '(no-resize-border
                          no-caption
                          no-system-menu
                          hide-menu-bar)]
                 [label "glui"]
                 [width (/ W 2)]
                 [height (/ H 2)]))
  (define c (new game-canvas%
                 [parent f]
                 [style '(gl)]))
  (send f show #t)
  (send f center 'both)

  (send c STEP))