Skip to content

Commit

Permalink
Added win32 gl 3.x context support.
Browse files Browse the repository at this point in the history
  • Loading branch information
patzy committed Oct 31, 2011
1 parent 61283a1 commit 8d67df1
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 6 deletions.
28 changes: 22 additions & 6 deletions src/win32/glop-win32.lisp
Expand Up @@ -18,19 +18,35 @@
(defstruct wgl-context (defstruct wgl-context
ctx) ctx)


;; FIXME: we should use specific context creation if available regardless of
;; :major and :minor being nil
(defmethod create-gl-context ((win win32-window) &key (make-current t) major minor (defmethod create-gl-context ((win win32-window) &key (make-current t) major minor
forward-compat debug forward-compat debug
profile) profile)


(when (or major minor forward-compat debug profile)
(warn "Specific context version is not implemented, MAJOR and MINOR arguments ignored."))
(let ((ctx (make-wgl-context))) (let ((ctx (make-wgl-context)))
(let ((wgl-ctx (glop-wgl:wgl-create-context (win32-window-dc win)))) (setf (wgl-context-ctx ctx)
(unless wgl-ctx (if (and major minor)
(format t "Error creating GL context: ~S~%" (glop-win32:get-last-error))) (let ((attrs (list :major-version major :minor-version minor)))
(setf (wgl-context-ctx ctx) wgl-ctx)) (when profile
(case profile
(:core (push :core-profile-bit attrs))
(:compat (push :compatibility-profile-bit attrs)))
(push :profile-mask attrs))
(when (or forward-compat debug)
(let ((flags '()))
(when forward-compat (push :forward-compatible-bit flags))
(when debug (push :debug-bit flags))
(push flags attrs)
(push :flags attrs)))
(glop-wgl:wgl-create-specific-context (win32-window-dc win) attrs))
(glop-wgl:wgl-create-context (win32-window-dc win))))
(unless wgl-ctx
(format t "Error creating GL context: ~S~%" (glop-win32:get-last-error)))
(when make-current (when make-current
(attach-gl-context win ctx)) (attach-gl-context win ctx))
(when (and major minor)
(glop-glx:correct-context? major minor))
ctx)) ctx))


(defmethod destroy-gl-context ((ctx wgl-context)) (defmethod destroy-gl-context ((ctx wgl-context))
Expand Down
68 changes: 68 additions & 0 deletions src/win32/wgl.lisp
Expand Up @@ -53,6 +53,19 @@
(:pfd-type-rgba 0) (:pfd-type-rgba 0)
(:pfd-type-color-index 1)) (:pfd-type-color-index 1))


(defcenum (wgl-context-attributes :unsigned-int)
(:major-version #x2091)
(:minor-version #x2092)
(:layer-planes #x2093)
(:flags #x2094)
(:profile-mask #x9126)
(:core-profile-bit #x00000001)
(:compatibility-profile-bit #x00000002))

(defbitfield (wgl-context-attribute-flags :unsigned-int)
(:debug-bit #x00000001)
(:forward-compatible-bit #x00000002))

(define-foreign-library opengl (define-foreign-library opengl
(t (:default "opengl32"))) (t (:default "opengl32")))
(use-foreign-library opengl) (use-foreign-library opengl)
Expand All @@ -62,6 +75,41 @@
(defcfun ("wglCreateContext" wgl-create-context) hglrc (defcfun ("wglCreateContext" wgl-create-context) hglrc
(dc hdc)) (dc hdc))


(defun wgl-create-specific-context (hdc context-attribs)
(with-foreign-object ( atts :int (1+ (length context-attribs)))
(loop
for i below (length context-attribs)
for attr in context-attribs do
(setf (mem-aref atts :int i)
(typecase attr
(keyword (foreign-enum-value 'glx-context-attributes attr))
(list (foreign-bitfield-value 'glx-context-attribute-flags attr))
(t attr))))
(setf (mem-aref atts :int (length context-attribs)) 0)
;; we need a fake gl context to be able to use wgl-get-proc-address
;; see http://www.opengl.org/wiki/Creating_an_OpenGL_Context#Proper_Context_Creation
;; FIXME: need some more error checking here
(let ((tmp-ctx (wgl-create-context hdc)))
(wgl-make-current hdc tmp-ctx)
(let ((ptr (glx-get-proc-address "wglCreateContextAttribsARB")))
;; remove out temporary context
(wgl-make-current (cffi:null-pointer) (cffi:null-pointer))
(wgl-delete-context tmp-ctx)
(when (null-pointer-p ptr)
(error "wglCreateContextAttribsARB unavailable"))
(let ((ctx (cffi:foreign-funcall-pointer ptr ()
:pointer hdc
:int 0
(:pointer :int) atts
:pointer)))
(when (null-pointer-p ctx)
(error "Unable to create context"))
ctx)))))


(defcfun ("glGetString" get-string) :pointer
(name :unsigned-int))

(defcfun ("wglMakeCurrent" wgl-make-current) bool (defcfun ("wglMakeCurrent" wgl-make-current) bool
(dc hdc) (rc hglrc)) (dc hdc) (rc hglrc))


Expand Down Expand Up @@ -136,3 +184,23 @@


(defcfun ("SwapBuffers" swap-buffers) bool (defcfun ("SwapBuffers" swap-buffers) bool
(dc hdc)) (dc hdc))


;; FIXME: this is copied from x11/glx.lisp, we should put this in some common file
(defun parse-gl-version-string-values (string)
;; major version is integer value up to first #\.
;; minor version is integer from first #\. to a #\. or #\space
(let ((dot (position #\. string)))
(values
(values (parse-integer string :end dot :junk-allowed t)) ; major
(if dot ; minor
(values (parse-integer string :start (1+ dot) :junk-allowed t))
0))))

(defun correct-context? (major-desired minor-desired)
(multiple-value-bind (major minor)
(parse-gl-version-string-values
(foreign-string-to-lisp (get-string (foreign-enum-value 'gl-enum :version))))
(when (or (< major major-desired)
(and (= major major-desired) (< minor minor-desired)))
(error "unable to create requested context"))))
2 changes: 2 additions & 0 deletions src/x11/glop-x11.lisp
Expand Up @@ -42,6 +42,8 @@
display ;; X display ptr display ;; X display ptr
) )


;; FIXME: we should use specific context creation if available regardless of
;; :major and :minor being nil
(defmethod create-gl-context ((win x11-window) &key (make-current t) major minor (defmethod create-gl-context ((win x11-window) &key (make-current t) major minor
forward-compat debug forward-compat debug
profile) profile)
Expand Down

0 comments on commit 8d67df1

Please sign in to comment.