3.3 KiB
3.3 KiB
| title |
|---|
| OpenGL - Triangle |
OpenGL: Triangle
The following code depends on the opengl and nim-glfw packages which
can be installed via babel by executing babel install opengl@#head nim-glfw@#head.
You will need the GLFW DLL in order to run this on Windows.
One thing to keep in mind when writing OpenGL code in Nim is that float
is actually float64. But vertices must be float32 so you must explicitly
specify that by casting or using 'f32 as is done in the example.
import os, glfw/glfw, opengl, times, math
proc assertShader(shader: GLuint) =
var status: GLint
glGetShaderiv(shader, GL_COMPILE_STATUS, addr status)
if status != GL_TRUE:
var buff: array[512, char]
glGetShaderInfoLog(shader, 512, nil, buff)
echo(buff)
assert false
const
vertexSource = """
#version 150
in vec2 position;
in vec3 color;
out vec3 Color;
void main()
{
Color = color;
gl_Position = vec4(position, 0.0, 1.0);
}
"""
fragmentSource = """
#version 150
in vec3 Color;
out vec4 outColor;
void main()
{
outColor = vec4(Color, 1.0);
}
"""
proc setup(shaderProgram: var TGLUint) =
var vertices = [
0.0'f32, 0.5, 1, 0, 0,
0.5, -0.5, 0, 1, 0,
-0.5, -0.5, 0, 0, 1
]
echo(vertices.repr)
var vertexBuffer: GLuint
glGenBuffers(1, addr vertexBuffer)
echo("Verter Buff: ", vertexBuffer)
var vertexArray: GLuint
glGenVertexArrays(1, addr vertexArray)
glBindVertexArray(vertexArray)
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer)
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices).int32, addr vertices,
GL_STATIC_DRAW)
var vertexShader = glCreateShader(GL_VERTEX_SHADER)
var vertexSrcArray = [vertexSource.cstring]
glShaderSource(vertexShader, 1, cast[cstringArray](addr vertexSrcArray), nil)
glCompileShader(vertexShader)
assertShader(vertexShader)
var fragmentShader = glCreateShader(GL_FRAGMENT_SHADER)
var fragmentSrcArray = [fragmentSource.cstring]
glShaderSource(fragmentShader, 1, cast[cstringArray](addr fragmentSrcArray),
nil)
glCompileShader(fragmentShader)
assertShader(fragmentShader)
shaderProgram = glCreateProgram()
glAttachShader(shaderProgram, vertexShader)
glAttachShader(shaderProgram, fragmentShader)
# Apparently this is not necessary according to http://open.gl
glBindFragDataLocation(shaderProgram, 0, "outColor")
glLinkProgram(shaderProgram)
glUseProgram(shaderProgram)
# Vertex data <-> attributes
var posAttrib = glGetAttribLocation(shaderProgram, "position").gluint
glEnableVertexAttribArray(posAttrib)
glVertexAttribPointer(posAttrib, 2, cGL_FLOAT, false,
5*sizeof(GLFloat).int32, nil)
var colAttrib = glGetAttribLocation(shaderProgram, "color").gluint
glEnableVertexAttribArray(colAttrib)
glVertexAttribPointer(colAttrib, 3, cGL_FLOAT, false,
5*sizeof(GLFloat).int32,
cast[pointer](2*sizeof(GLFloat)))
when isMainModule:
glfw.init()
var win = newWin()
win.makeContextCurrent()
loadExtensions()
var shaderProgram: TGLuint
setup(shaderProgram)
while not win.shouldClose:
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
glDrawArrays(GL_TRIANGLES, 0, 3)
win.swapBufs()
pollEvents()
win.destroy()
glfw.terminate()
