【问题标题】:How to configure gl:ortho for the size of window in cl-opengl如何在 cl-opengl 中为窗口大小配置 gl:ortho
【发布时间】:2019-12-16 15:24:54
【问题描述】:

我正在尝试为 cl-opengl 中的窗口大小配置 gl:ortho,但不起作用:

(gl:viewport 0 0 (width window) (height window))
(gl:matrix-mode :projection)
(gl:ortho (- (/ (width window) 2)) (/ (width window) 2) (- (/ (height window) 2)) (/ (height window) 2) -1.0 1.0)
(gl:matrix-mode :modelview)
(gl:load-identity)

与:

(width window) => 800
(height window) => 600 

如果我用下面的顶点绘制一个三角形:

(verts #(0.0 280.0
         -280.0 -280.0
         280.0 -280.0))

我得到了整个蓝屏。但如果我尝试使用以下坐标:

(verts #(0.0 0.8
         -0.8 -0.8
         0.8 -0.8))

我在屏幕上看到蓝色三角形,好像它没有在gl:ortho 中配置任何东西。

我哪里做错了?

【问题讨论】:

    标签: opengl common-lisp


    【解决方案1】:

    我设法让它工作,秘诀是你需要将投影矩阵乘以顶点着色器中的位置,如下所示:

    下一个例子的通用函数:

    (require :sdl2)
    (require :cl-opengl)
    (require :cl-glut)
    
    (defun runtime-load-shader (shader-type shader-src)
      (let ((shader (gl:create-shader shader-type)))
        (gl:shader-source shader shader-src)
        (gl:compile-shader shader) 
        shader))
    
    (defun alloc-array-buffer (verts)
      (let ((array-buffer (gl:gen-buffer))
        (arr (gl:alloc-gl-array :float (length verts))))
        (gl:bind-buffer :array-buffer array-buffer)
        (dotimes (i (length verts))
          (setf (gl:glaref arr i) (aref verts i)))
        (gl:buffer-data :array-buffer :static-draw arr)
        (gl:free-gl-array arr)
        array-buffer))
    
    (defun create-new-program (program)
      (let ((verts #(0.0 280.0
             -280.0 -280.0
             280.0 -280.0))
        (vs (runtime-load-shader :vertex-shader "#version 120
    
    uniform mat4 projectionMatrix;
    attribute vec2 coord2d;
    
    void main(void) {
      gl_Position = projectionMatrix * vec4(coord2d, 0.0, 1.0);
    }
    "))
        (fs (runtime-load-shader :fragment-shader "#version 120
    
    void main(void) {
      gl_FragColor[0] = 0.0;
      gl_FragColor[1] = 0.0;
      gl_FragColor[2] = 1.0;
    }
    "))
        (coord2d nil))
        (gl:attach-shader program vs)
        (gl:attach-shader program fs)
        (gl:link-program program)
        (alloc-array-buffer verts)
        (setf coord2d (gl:get-attrib-location program "coord2d"))
        (gl:use-program program)
        (gl:enable-vertex-attrib-array coord2d)
        (gl:vertex-attrib-pointer coord2d
                          2
                          :float
                          :false
                          0
                          (cffi:null-pointer))))
    
    (defun draw-triangle ()
      (gl:draw-arrays :triangles 0 3))
    
    (defun program-shutdown (program)
      (gl:delete-program program))
    

    使用 cl-glut 绘制三角形的示例:

    (defclass glut-test-window (glut:window)
      ((program :accessor program)) 
      (:default-initargs :width 800 :height 600
                 :mode '(:double :rgb :depth) :title "shader-vao-test"))
    
    (defmethod glut:display-window :before ((w glut-test-window))
      (setf (program w) (gl:create-program))
      (create-new-program (program w)))
    
    (defmethod glut:display ((w glut-test-window))
      (gl:clear-color 0.0 0.0 0.2 1.0)
      (gl:clear :color-buffer-bit)
      (draw-triangle)
      (glut:swap-buffers))
    
    (defmethod glut:reshape ((w glut-test-window) width height)
      (gl:viewport 0 0 800 600)
      (gl:matrix-mode :projection)
      (gl:load-identity)
      (gl:ortho -400 400 -300 300 -1.0 1.0)
      (when (program w)
          (let ((proj-mat (gl:get-float :projection-matrix)))
        (gl:uniform-matrix 
         (gl:get-uniform-location (program w) "projectionMatrix") 
         4 
         (vector proj-mat))))
      (gl:matrix-mode :modelview)
      (gl:load-identity))
    
    (defmethod glut:keyboard ((w glut-test-window) key x y)
      (declare (ignore x y))
      (case key
        (#\Esc (glut:destroy-current-window))))
    
    (defun glut-test ()
      (let ((w (make-instance 'glut-test-window)))
        (glut:display-window w)
        (program-shutdown (program w))))
    
    (glut-test)
    

    使用 cl-sdl2 绘制三角形的示例:

    (defun sdl2-test ()
      (sdl2:with-init (:everything)
        (sdl2:with-window (win :flags '(:shown :opengl))
          (sdl2:with-gl-context (gl-context win)
            (let ((program (gl:create-program)))
          (create-new-program program)
    
              (gl:viewport 0 0 800 600)
          (gl:matrix-mode :projection)
          (gl:load-identity)
          (gl:ortho -400 400 -300 300 -1.0 1.0)
          (when program
            (let ((proj-mat (gl:get-float :projection-matrix)))
              (gl:uniform-matrix 
               (gl:get-uniform-location program "projectionMatrix") 
               4 
               (vector proj-mat))))
          (gl:matrix-mode :modelview)
          (gl:load-identity)
    
          (sdl2:with-event-loop (:method :poll)
                (:idle ()
                       (gl:clear :color-buffer)
                       (gl:color 1.0 0.0 0.0)
               (draw-triangle)
                       (sdl2:gl-swap-window win))
    
                (:quit () t)))))))
    (sdl2-test)
    

    可悲的是必须在所有着色器上乘以投影矩阵。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-06-18
      • 2015-05-23
      • 2010-10-31
      • 2013-02-09
      • 2019-02-25
      • 2021-11-09
      • 2010-10-11
      相关资源
      最近更新 更多