

Common LispでOpenGLの[チュートリアル](https://learnopengl.com/#!Getting-started/Hello-
Triangle)を試していたのですが,  
`(gl:gen-vertex-array)`でエラーが出てしまいます.

[code]

    OpenGL signalled (1282 . INVALID-OPERATION) from GEN-VERTEX-ARRAYS.
    [Condition of type CL-OPENGL-BINDINGS:OPENGL-ERROR]
    
[/code]

デバッガでcontinueすると

[code]

    The value                                                                       
      (1)     
    is not of type 
      (UNSIGNED-BYTE 32)
       [Condition of type TYPE-ERROR]
    
[/code]

と出ます.  
上のサイトの翻訳をしているとエラーが出てしまいますが,replで単体で`(gen-vertex-array)`を評価するとエラーが出ません.  
どうすれば解決できるか教えていただけないでしょうか.  
ソースコードは

[code]

    (require :asdf)
    (asdf:oos 'asdf:load-op :cl-glfw3)
    (asdf:oos 'asdf:load-op :cl-opengl)
    (asdf:oos 'asdf:load-op :cl-glu)
    (asdf:oos 'asdf:load-op :trivial-main-thread)
    (require 'cffi)
    (defpackage glfw-test
      (:use :cl :trivial-main-thread)
      (:export #:run
           #:bound))
    (in-package :glfw-test)
    
    (defclass shader ()
       ((vbuff :accessor vertex-buffer)
       (ibuff :accessor index-buffer)
       (vshader :accessor vertex-shader)
       (fshader :accessor fragment-shader)
       (varray :accessor vertex-array)
       (program :accessor program)))
    
    (defvar *vertex-shader-source*
      "#version 330 core
       layout (location = 0) in vec3 apos;
       void main ()
       {
       gl_position = vec4(apos.x, apos.y, apos.z, 1.0);
       }
       ")
    (defvar *fragment-shader-source*
      "#version 330 core
       out vec4 fragcolor;
       void main()
       {
       fragcolor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
       }
       ")
    
    (defgeneric shader-init (shader)
      (:documentation "シェーダを初期化"))
    (defmethod shader-init ((shader shader))
      ;;バーテックスシェーダ
      (setf (vertex-shader shader) (gl:create-shader :vertex-shader))
      (gl:shader-source (vertex-shader shader) *vertex-shader-source*)
      (gl:compile-shader (vertex-shader shader))
      ;;フラグメントシェーダ
      (setf (fragment-shader shader) (gl:create-shader :fragment-shader))
      (gl:shader-source (fragment-shader shader) *fragment-shader-source*)
      (gl:compile-shader (fragment-shader shader))
      ;;シェーダプログラム
      (setf (program shader) (gl:create-program))
      (gl:attach-shader (program shader) (vertex-shader shader))
      (gl:attach-shader (program shader) (fragment-shader shader))
      (gl:link-program (program shader))
      ;;使い終わったシェーダを削除
      (gl:delete-shader (vertex-shader shader))
      (gl:delete-shader (fragment-shader shader))
      ;;アレイ
      (let ((vertices (gl:alloc-gl-array :float 9))
        (verts #(-0.5 -0.5 0.0
             0.5 -0.5 0.0
             0.0 0.5 0.0)))
        (dotimes (i (length verts))
          (setf (gl:glaref vertices i) (aref verts i)))
    
        (setf (vertex-array shader) (gl:gen-vertex-array))
        (setf (vertex-buffer shader) (gl:gen-buffers 1))
    
        (gl:bind-vertex-array (vertex-buffer shader))
    
        (gl:bind-buffer :array-buffer (vertex-buffer shader))
        (gl:buffer-data :array-buffer :static-draw vertices)
        (gl:free-gl-array vertices));freeにする
    
      (gl:vertex-attrib-pointer 0 3 :float nil 3 (cffi:null-pointer))
      (gl:enable-vertex-attrib-array 0)
      ;;アレイを解除
      (gl:bind-buffer :array-buffer 0)
      (gl:bind-vertex-array 0)
    
      (gl:use-program (program shader)))
    
    (defun main-loop ()
      (gl:clear-color 0.2 0.3 0.3 1.0)
      (gl:clear :color-buffer-bit)
      )
    
    (defun main ()
      (with-body-in-main-thread ()
        (glfw:with-init-window (:width 480 :height 400 :title "test glfw")
          (let ((shdr (make-instance 'shader)))
        (shader-init shdr)
          ;;メインループ
          (loop until (glfw:window-should-close-p)
         do (gl:clear :depth-buffer-bit)
         ;;描画
           (main-loop)
           (glfw:swap-buffers)
           (glfw:poll-events);;イベントに対する反応を書いておかないとウィンドウが表示されない.消去できない
           (sleep (/ 1 60));更新を60fpsに
           )
          ))))
    
    (defun run ()
      #+sbcl(sb-int:with-float-traps-masked (:invalid) (main));;SBCLはこれがないとエラー
      #-sbcl(main)
      )
    (run)
    
[/code]

となっています.ライブラリは事前にquicklispで導入しました.replでこれをloadするとエラーになってしまいます.


CC BY-SA 3.0
2017-08-25T03:54:34.053
37478
2020-11-24T08:08:35.947
2017-08-25T17:25:40.620
19110
23130
question
common-lisp opengl
cl-openglのgem-vertex-arrayのエラー


この行が問題です。

[code]

    (gl:bind-vertex-array (vertex-buffer shader))
    
[/code]

bind すべきは `(vertex-buffer shader)` ではなく `(vertex-array shader)` です。この部分を修正すれば
`(CL-OPENGL-BINDINGS:BIND-VERTEX-ARRAY (1))` でのエラーは出なくなりますが、続いて `(CL-OPENGL-
BINDINGS:BIND-BUFFER :ARRAY-BUFFER (1))` でエラーがでるようになります。これは `gl:gen-buffers`
の戻り値をそのまま `(vertex-buffer shader)` としているからです（正しくはその第0要素を `setf` することになります）。

また GLSL 3.30 を利用するために、環境によっては `glfw:with-init-window` で `:context-version-
major` などを設定する必要があるかもしれません。シェーダースクリプトをコンパイルしたときのログに "error: GLSL 3.30 is not
supported." が出てきた場合は参考にしてください。

ひとまず cl-opengl の examples にある [shader-vao.lisp](https://github.com/3b/cl-
opengl/blob/master/examples/misc/shader-vao.lisp) が参考になるのではないかと思います。


CC BY-SA 3.0
2017-08-25T19:53:07.123
37497
2017-08-25T20:09:57.327
2017-08-25T20:09:57.327
19110
19110
37478
answer