2015-06-08 4 views
1

я подумал я мог бы сделать карту OPENGL координаты (-1, -1) и (1, 1) пикселей (0,0) и (ширина, высота) с этих вызовов:glViewport неправильно отображает нормальные координаты в координаты окна?

(gl-viewport 0 0 width height) 

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

Однако прямоугольник, оттянутый от (-1, -1) до (1,1), пересекает только две трети левого и нижнего краев окна. Я могу это исправить, используя

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

, но это не похоже на меня. Что я делаю не так?

Это фрагмент кода для DrRacket

#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)) 

Screenshot of the above

ответ

1

кажется, что у вас есть дисплей настройки масштабирования равен 150% на вашей системе Windows. 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) 
+0

Что дало вам эту идею? Я еще не тестировал это, но я действительно играл с этим компьютером из-за его высоких точек на дюйм, и теперь это имеет смысл. – user3125280

+0

Я застрял в той же проблеме, пытаясь заменить рендеринг моего прототипа моей операционной системы с помощью OpenGL, кроме У меня был коэффициент шкалы 1,25. Затем я вспомнил свой 125% экранный масштаб и нашел эту статью (особенно в разделе «Использование дисплея в рендерере»): https://nlguillemot.wordpress.com/2016/12/11/high-dpi-rendering/ – eternastudento

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)) 
+0

Соотношение сторон части просто хлюпает мнение, чтобы включить некоторые из сцены за -1 и 1 (который, да, являются кромками), так что форма оказываются в виде квадрата (с дополнительным черным фоном в зависимости от аспект окна). Ваш код ничего не менял для меня - похоже, он специфичен для драйверов моего компьютера. Почти так, как если бы окна 8.1 играли трюки в библиотеках opengl ... – user3125280

+0

(изображение в моем вопросе - это самый большой размер, который достигает форма) – user3125280

Смежные вопросы