Here is a simple example of OpenGL code using
OpenTK library:
- Code: Select all
use System
use System.Diagnostics
use System.Drawing
use System.IO
use OpenTK
use OpenTK.Graphics
use OpenTK.Graphics.OpenGL
class HelloGL3 inherits GameWindow
var vertexShaderHandle as int
var fragmentShaderHandle as int
var shaderProgramHandle as int
var modelviewMatrixLocation as int
var projectionMatrixLocation as int
var vaoHandle as int
var positionVboHandle as int
var normalVboHandle as int
var eboHandle as int
var vertexShaderSource as String = '\n#version 130\n\nprecision highp float;\n\nuniform mat4 projection_matrix;\nuniform mat4 modelview_matrix;\n\nin vec3 in_position;\nin vec3 in_normal;\n\nout vec3 normal;\n\nvoid main(void)\n{\n //works only for orthogonal modelview\n normal = (modelview_matrix * vec4(in_normal, 0)).xyz;\n \n gl_Position = projection_matrix * modelview_matrix * vec4(in_position, 1);\n}\n\t'
var fragmentShaderSource as String = '\n#version 130\n\nprecision highp float;\n\nconst vec3 ambient = vec3(0.1, 0.1, 0.1);\nconst vec3 lightVecNormalized = normalize(vec3(0.5, 0.5, 2.0));\nconst vec3 lightColor = vec3(0.9, 0.9, 0.7);\n\nin vec3 normal;\n\nout vec4 out_frag_color;\n\nvoid main(void)\n{\n float diffuse = clamp(dot(lightVecNormalized, normalize(normal)), 0.0, 1.0);\n out_frag_color = vec4(ambient + diffuse * lightColor, 1.0);\n}\t\n\t'
var positionVboData as Vector3[] = @[Vector3(-1.0 to float32, -1.0 to float32, 1.0 to float32), Vector3( 1.0 to float32, -1.0 to float32, 1.0 to float32), Vector3( 1.0 to float32, 1.0 to float32, 1.0 to float32), Vector3(-1.0 to float32, 1.0 to float32, 1.0 to float32), Vector3(-1.0 to float32, -1.0 to float32, -1.0 to float32), Vector3( 1.0 to float32, -1.0 to float32, -1.0 to float32), Vector3( 1.0 to float32, 1.0 to float32, -1.0 to float32), Vector3(-1.0 to float32, 1.0 to float32, -1.0 to float32) ]
var indicesVboData as int[] = @[ 0, 1, 2, 2, 3, 0, 3, 2, 6, 6, 7, 3, 7, 6, 5, 5, 4, 7, 4, 0, 3, 3, 7, 4, 0, 1, 5, 5, 4, 0, 1, 5, 6, 6, 2, 1, ]
# // front face
# 0, 1, 2, 2, 3, 0,
# // top face
# 3, 2, 6, 6, 7, 3,
# // back face
# 7, 6, 5, 5, 4, 7,
# // left face
# 4, 0, 3, 3, 7, 4,
# // bottom face
# 0, 1, 5, 5, 4, 0,
# // right face
# 1, 5, 6, 6, 2, 1,
# ]
var projectionMatrix as Matrix4
var modelviewMatrix as Matrix4
cue init
base.init(
640 , 480 ,
GraphicsMode(),
"OpenGL 3 Example",
0 to OpenTK.GameWindowFlags, DisplayDevice.default,
3, 0, GraphicsContextFlags.ForwardCompatible | GraphicsContextFlags.Debug
)
def onLoad(e as System.EventArgs?) is override,protected
.vSync = VSyncMode.On
.createShaders
.createVBOs
.createVAOs
# // Other state
GL.enable(EnableCap.DepthTest)
GL.clearColor(System.Drawing.Color.midnightBlue)
def createShaders # is override,protected
.vertexShaderHandle = GL.createShader(ShaderType.VertexShader)
.fragmentShaderHandle = GL.createShader(ShaderType.FragmentShader)
GL.shaderSource(.vertexShaderHandle, .vertexShaderSource)
GL.shaderSource(.fragmentShaderHandle, .fragmentShaderSource)
GL.compileShader(.vertexShaderHandle)
GL.compileShader(.fragmentShaderHandle)
Debug.writeLine(GL.getShaderInfoLog(.vertexShaderHandle))
Debug.writeLine(GL.getShaderInfoLog(.fragmentShaderHandle))
# Create program
.shaderProgramHandle = GL.createProgram
GL.attachShader(.shaderProgramHandle, .vertexShaderHandle)
GL.attachShader(.shaderProgramHandle, .fragmentShaderHandle)
GL.linkProgram(.shaderProgramHandle)
Debug.writeLine(GL.getProgramInfoLog(.shaderProgramHandle))
GL.useProgram(.shaderProgramHandle)
# Set uniforms
.projectionMatrixLocation = GL.getUniformLocation(.shaderProgramHandle, "projection_matrix")
.modelviewMatrixLocation = GL.getUniformLocation(.shaderProgramHandle, "modelview_matrix")
aspectRatio as float = .clientSize.width / (.clientSize.height to float)
Matrix4.createPerspectiveFieldOfView((Math.pi / 4) to float32, aspectRatio to float32, 1 to float32, 100 to float32, out .projectionMatrix)
.modelviewMatrix = Matrix4.lookAt(Vector3(0, 3, 5), Vector3(0, 0, 0), Vector3(0, 1, 0))
GL.uniformMatrix4(.projectionMatrixLocation, false , inout .projectionMatrix)
GL.uniformMatrix4(.modelviewMatrixLocation , false , inout .modelviewMatrix)
def createVBOs # is override,protected
GL.genBuffers(1, out .positionVboHandle)
GL.bindBuffer(BufferTarget.ArrayBuffer, .positionVboHandle)
GL.bufferData<of Vector3>(
BufferTarget.ArrayBuffer,
IntPtr(.positionVboData.length * Vector3.sizeInBytes),
.positionVboData,
BufferUsageHint.StaticDraw
)
GL.genBuffers(1, out .normalVboHandle)
GL.bindBuffer(BufferTarget.ArrayBuffer, .normalVboHandle)
GL.bufferData<of Vector3>(
BufferTarget.ArrayBuffer,
IntPtr(.positionVboData.length * Vector3.sizeInBytes),
.positionVboData,
BufferUsageHint.StaticDraw
)
GL.genBuffers(1, out .eboHandle)
GL.bindBuffer(BufferTarget.ElementArrayBuffer, .eboHandle)
GL.bufferData(
BufferTarget.ElementArrayBuffer,
IntPtr(Cobra.Lang.NumericTypeInfo(uint).size * .indicesVboData.length),
.indicesVboData,
BufferUsageHint.StaticDraw
)
GL.bindBuffer(BufferTarget.ArrayBuffer, 0)
GL.bindBuffer(BufferTarget.ElementArrayBuffer, 0)
def createVAOs # is override,protected
# GL3 allows us to store the vertex layout in a "vertex array object" (VAO).
# This means we do not have to re-issue VertexAttribPointer calls
# every time we try to use a different vertex layout - these calls are
# stored in the VAO so we simply need to bind the correct VAO.
GL.genVertexArrays(1, out .vaoHandle)
GL.bindVertexArray(.vaoHandle)
GL.enableVertexAttribArray(0)
GL.bindBuffer(BufferTarget.ArrayBuffer, .positionVboHandle)
GL.vertexAttribPointer(0, 3, VertexAttribPointerType.Float, true, Vector3.sizeInBytes, 0)
GL.bindAttribLocation(.shaderProgramHandle, 0, "in_position")
GL.enableVertexAttribArray(1)
GL.bindBuffer(BufferTarget.ArrayBuffer, .normalVboHandle)
GL.vertexAttribPointer(1, 3, VertexAttribPointerType.Float, true, Vector3.sizeInBytes, 0)
GL.bindAttribLocation(.shaderProgramHandle, 1, "in_normal")
GL.bindBuffer(BufferTarget.ElementArrayBuffer, .eboHandle)
GL.bindVertexArray(0)
def onUpdateFrame(e as FrameEventArgs?) is override,protected
rotation as Matrix4 = Matrix4.createRotationY(e.time to float32)
Matrix4.mult(inout rotation, inout .modelviewMatrix, out .modelviewMatrix)
GL.uniformMatrix4(.modelviewMatrixLocation, false, inout .modelviewMatrix)
if .keyboard[OpenTK.Input.Key.Escape]
.exit
def onRenderFrame(e as FrameEventArgs?) is override,protected
GL.viewport(0, 0, .width, .height)
GL.clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit)
GL.bindVertexArray(.vaoHandle)
GL.drawElements(BeginMode.Triangles, .indicesVboData.length,
DrawElementsType.UnsignedInt, IntPtr.zero)
.swapBuffers
class Program
def main has STAThread
example = HelloGL3()
# Utilities.SetWindowTitle(example)
# example.run(30)
example.run
# Application.run(MyForm())
Notice how ugly is vertexShaderSource that is not multiline string. I didn`t realize that only docstrings can be multiline. For now I am using python to do
- Code: Select all
print repr(""" ... shader code ... """)
then copypasta that into source.
Also if I erase brackets from
- Code: Select all
example = HelloGL3()
to get
- Code: Select all
example = HelloGL3
I get compiler error
- Code: Select all
error: Cannot find a definition for "run" in "example" whose type is "Type".
Does this mean that brackets are needed to indicate object instantination or else class object would be assigned ?