-
-
Save swannodette/1f1b6d2a7926b22f019b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Gamma (shader-generation): https://github.com/kovasb/gamma | |
;; Gamma Driver (WebGL resource management, aka "Om for WebGL"): https://github.com/kovasb/gamma-driver | |
;; Gamma examples: https://github.com/kovasb/gamma-examples | |
(ns gampg.learn-gamma.lesson-01 | |
(:require [clojure.string :as s] | |
[gamma.api :as g] | |
[gamma.program :as p] | |
[gamma.tools :as gt] | |
[gamma-driver.drivers.basic :as driver] | |
[gamma-driver.protocols :as dp] | |
[goog.webgl :as ggl] | |
[thi.ng.geom.core :as geom] | |
[thi.ng.geom.core.matrix :as mat :refer [M44]] | |
[thi.ng.geom.webgl.arrays :as arrays])) | |
(def title | |
"1. A triangle and a square") | |
(def u-p-matrix | |
(g/uniform "uPMatrix" :mat4)) | |
(def u-mv-matrix | |
(g/uniform "uMVMatrix" :mat4)) | |
(def a-position | |
(g/attribute "aVertexPosition" :vec3)) | |
(def program-source | |
(p/program | |
{:vertex-shader {(g/gl-position) (-> u-p-matrix | |
(g/* u-mv-matrix) | |
(g/* (g/vec4 a-position 1)))} | |
:fragment-shader {(g/gl-frag-color) (g/vec4 1 1 1 1)}})) | |
(defn get-perspective-matrix | |
"Be sure to | |
1. pass the WIDTH and HEIGHT of the canvas *node*, not | |
the GL context | |
2. (set! (.-width/height canvas-node) | |
width/height), respectively, or you may see no results, or strange | |
results" | |
[width height] | |
(mat/perspective 45 (/ width height) 0.1 100)) | |
(defn get-data [p mv vertices] | |
{u-p-matrix p | |
u-mv-matrix mv | |
a-position vertices}) | |
(defn make-driver [gl] | |
(driver/basic-driver gl)) | |
(defn reset-gl-canvas! [canvas-node] | |
(let [gl (.getContext canvas-node "webgl") | |
width (.-clientWidth canvas-node) | |
height (.-clientHeight canvas-node)] | |
;; Set the width/height (in terms of GL-resolution) to actual | |
;; canvas-element width/height (or else you'll see blurry results) | |
(set! (.-width canvas-node) width) | |
(set! (.-height canvas-node) height) | |
;; Setup GL Canvas | |
(.viewport gl 0 0 width height))) | |
(defn main [gl node] | |
(let [w (.-clientWidth node) | |
h (.-clientHeight node) | |
driver (make-driver gl) | |
program (dp/program driver program-source) | |
p (get-perspective-matrix w h) | |
mv (mat/matrix44) | |
triangle-vertices [[ 0 1 0] | |
[-1 -1 0] | |
[ 1 -1 0]] | |
square-vertices [[ 1 1 0] | |
[-1 1 0] | |
[ 1 -1 0] | |
[-1 -1 0]]] | |
(reset-gl-canvas! node) | |
(.clearColor gl 0 0 0 1) | |
(.clear gl (bit-or (.-COLOR_BUFFER_BIT gl) (.-DEPTH_BUFFER_BIT gl))) | |
(let [mv (geom/translate mv [-1.5 0 -7])] | |
(driver/draw-program driver program (get-data p mv triangle-vertices) {:draw-mode :triangles})) | |
(let [mv (geom/translate mv [3 0 -7])] | |
(driver/draw-program driver program (get-data p mv square-vertices) {:draw-mode :triangle-strip})))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<!-- From http://learningwebgl.com/blog/?p=3322 --> | |
<head> | |
<title>Learning WebGL — lesson 1</title> | |
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"> | |
<script type="text/javascript" src="glMatrix-0.9.5.min.js"></script> | |
<script id="shader-fs" type="x-shader/x-fragment"> | |
precision mediump float; | |
void main(void) { | |
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); | |
} | |
</script> | |
<script id="shader-vs" type="x-shader/x-vertex"> | |
attribute vec3 aVertexPosition; | |
uniform mat4 uMVMatrix; | |
uniform mat4 uPMatrix; | |
void main(void) { | |
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); | |
} | |
</script> | |
<script type="text/javascript"> | |
var gl; | |
function initGL(canvas) { | |
try { | |
gl = canvas.getContext("experimental-webgl"); | |
gl.viewportWidth = canvas.width; | |
gl.viewportHeight = canvas.height; | |
} catch (e) { | |
} | |
if (!gl) { | |
alert("Could not initialise WebGL, sorry :-("); | |
} | |
} | |
function getShader(gl, id) { | |
var shaderScript = document.getElementById(id); | |
if (!shaderScript) { | |
return null; | |
} | |
var str = ""; | |
var k = shaderScript.firstChild; | |
while (k) { | |
if (k.nodeType == 3) { | |
str += k.textContent; | |
} | |
k = k.nextSibling; | |
} | |
var shader; | |
if (shaderScript.type == "x-shader/x-fragment") { | |
shader = gl.createShader(gl.FRAGMENT_SHADER); | |
} else if (shaderScript.type == "x-shader/x-vertex") { | |
shader = gl.createShader(gl.VERTEX_SHADER); | |
} else { | |
return null; | |
} | |
gl.shaderSource(shader, str); | |
gl.compileShader(shader); | |
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { | |
alert(gl.getShaderInfoLog(shader)); | |
return null; | |
} | |
return shader; | |
} | |
var shaderProgram; | |
function initShaders() { | |
var fragmentShader = getShader(gl, "shader-fs"); | |
var vertexShader = getShader(gl, "shader-vs"); | |
shaderProgram = gl.createProgram(); | |
gl.attachShader(shaderProgram, vertexShader); | |
gl.attachShader(shaderProgram, fragmentShader); | |
gl.linkProgram(shaderProgram); | |
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { | |
alert("Could not initialise shaders"); | |
} | |
gl.useProgram(shaderProgram); | |
shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); | |
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); | |
shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); | |
shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); | |
} | |
var mvMatrix = mat4.create(); | |
var pMatrix = mat4.create(); | |
function setMatrixUniforms() { | |
gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix); | |
gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix); | |
} | |
var triangleVertexPositionBuffer; | |
var squareVertexPositionBuffer; | |
function initBuffers() { | |
triangleVertexPositionBuffer = gl.createBuffer(); | |
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer); | |
var vertices = [ | |
0.0, 1.0, 0.0, | |
-1.0, -1.0, 0.0, | |
1.0, -1.0, 0.0 | |
]; | |
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); | |
triangleVertexPositionBuffer.itemSize = 3; | |
triangleVertexPositionBuffer.numItems = 3; | |
squareVertexPositionBuffer = gl.createBuffer(); | |
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer); | |
vertices = [ | |
1.0, 1.0, 0.0, | |
-1.0, 1.0, 0.0, | |
1.0, -1.0, 0.0, | |
-1.0, -1.0, 0.0 | |
]; | |
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); | |
squareVertexPositionBuffer.itemSize = 3; | |
squareVertexPositionBuffer.numItems = 4; | |
} | |
function drawScene() { | |
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); | |
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); | |
mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix); | |
mat4.identity(mvMatrix); | |
mat4.translate(mvMatrix, [-1.5, 0.0, -7.0]); | |
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer); | |
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, triangleVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0); | |
setMatrixUniforms(); | |
gl.drawArrays(gl.TRIANGLES, 0, triangleVertexPositionBuffer.numItems); | |
mat4.translate(mvMatrix, [3.0, 0.0, 0.0]); | |
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer); | |
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0); | |
setMatrixUniforms(); | |
gl.drawArrays(gl.TRIANGLE_STRIP, 0, squareVertexPositionBuffer.numItems); | |
} | |
function webGLStart() { | |
var canvas = document.getElementById("lesson01-canvas"); | |
initGL(canvas); | |
initShaders(); | |
initBuffers(); | |
gl.clearColor(0.0, 0.0, 0.0, 1.0); | |
gl.enable(gl.DEPTH_TEST); | |
drawScene(); | |
} | |
</script> | |
</head> | |
<body onload="webGLStart();"> | |
<a href="http://learningwebgl.com/blog/?p=28"><< Back to Lesson 1</a><br /> | |
<canvas id="lesson01-canvas" style="border: none;" width="500" height="500"></canvas> | |
<br/> | |
<a href="http://learningwebgl.com/blog/?p=28"><< Back to Lesson 1</a><br /> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment