Skip to content

Instantly share code, notes, and snippets.

@bsergean
Created August 26, 2015 03:07
Show Gist options
  • Save bsergean/db3f500f05584fa3f2dc to your computer and use it in GitHub Desktop.
Save bsergean/db3f500f05584fa3f2dc to your computer and use it in GitHub Desktop.
(buggy) render of a bunny to a texture / png, using headless-gl
#!/usr/bin/env coffee
PNG = require('pngjs').PNG
fs = require('fs')
bunny = require('bunny')
normals = require('normals')
Shader = require('gl-shader')
camera = require('lookat-camera')()
# Create context
width = 600
height = 400
gl = require("gl").createContext(width, height)
# Create texture
tex = gl.createTexture()
gl.bindTexture(gl.TEXTURE_2D, tex)
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null)
# Create frame buffer
fbo = gl.createFramebuffer()
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)
#
# Clear screen to red
#
gl.clearColor(1.0, 0.0, 0.0, 1.0)
gl.clear(gl.COLOR_BUFFER_BIT)
#
# Load the bunny
#
Geometry = require('gl-geometry')
geometry = Geometry(gl)
geometry.attr('aPosition', bunny.positions)
geometry.attr('aNormal', normals.vertexNormals(
bunny.cells
, bunny.positions
))
geometry.faces(bunny.cells)
#
# Using the look at camera
#
mat4 = require('gl-mat4')
projection = mat4.create()
model = mat4.create()
view = mat4.create()
vertShader = """
attribute vec3 aPosition;
uniform mat4 uProjection;
uniform mat4 uModel;
uniform mat4 uView;
void main() {
gl_Position = uProjection * uView *
uModel * vec4(aPosition, 1.0);
}
"""
fragShader = """
void main() {
gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
}
"""
shader = Shader(gl
, vertShader
, fragShader
)
update = (width, height) ->
camera.target = new Float32Array([0, 0, 0])
camera.position = new Float32Array([20, 20, 20])
view = camera.view(view)
aspectRatio = width / height
fieldOfView = Math.PI / 4
near = 0.01
far = 100
mat4.perspective(projection, fieldOfView, aspectRatio, near, far)
render = (width, height) ->
update(width, height)
gl.viewport(0, 0, width, height)
gl.enable(gl.DEPTH_TEST)
gl.enable(gl.CULL_FACE)
geometry.bind(shader)
shader.uniforms.uProjection = projection
shader.uniforms.uView = view
shader.uniforms.uModel = model
geometry.draw(gl.TRIANGLES)
render(width, height)
# Grab pixels and write output to out.png
path = "out.png"
pixels = new Uint8Array(width * height * 4)
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels)
png = new PNG({ width: width, height: height })
for i in [0...pixels.length]
png.data[i] = pixels[i]
stream = fs.createWriteStream(path)
png.pack().pipe stream
stream.on 'close', () ->
console.log("Image written: #{ path }")
gl.destroy()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment