(* This code comes from: http://gpwiki.org/index.php/OpenGL:Codes:Simple_GLSL_example which is under GNU::FDL license (ported to OCaml/glMLite by Florent Monnier) *) open GL open Glu open Glut let waveTime = ref 0.0 let waveWidth = ref 0.1 let waveHeight = ref 3.0 let waveFreq = ref 0.1 let waveTimeLoc = ref 0 let waveWidthLoc = ref 0 let waveHeightLoc = ref 0 let ( += ) a b = a := !a +. b; ;; let ( -= ) a b = a := !a -. b; ;; let display() = glClear [GL_COLOR_BUFFER_BIT]; glLoadIdentity(); glTranslate 0.0 0.0 (-150.0); glRotate (-45.0) 1.0 0.0 0.0; (* Change time *) glUniform1f !waveTimeLoc !waveTime; glUniform1f !waveWidthLoc !waveWidth; glUniform1f !waveHeightLoc !waveHeight; (* Draw here a plain surface *) glBegin GL_QUADS; for i = -50 to pred 50 do for j = -50 to pred 50 do let glVertex2i a b = glVertex2 (float a) (float b) in glVertex2i i j; glVertex2i (i + 1) j; glVertex2i (i + 1) (j + 1); glVertex2i i (j + 1); done; done; glEnd(); waveTime += !waveFreq; glFlush(); glutSwapBuffers(); glutPostRedisplay(); ;; let setShaders() = (* The vertex shader *) let vsSource = " /* Vertex shader */ uniform float waveTime; uniform float waveWidth; uniform float waveHeight; void main(void) { vec4 v = vec4(gl_Vertex); v.z = sin(waveWidth * v.x + waveTime) * cos(waveWidth * v.y + waveTime) * waveHeight; gl_Position = gl_ModelViewProjectionMatrix * v; } " in let fsSource = " /* Vertex shader */ uniform float waveTime; uniform float waveWidth; uniform float waveHeight; void main(void) { vec4 v = vec4(gl_Vertex); v.z = sin(waveWidth * v.x + waveTime) * cos(waveWidth * v.y + waveTime) * waveHeight; gl_Position = gl_ModelViewProjectionMatrix * v; } " in (* Compile and load the program *) let vs = glCreateShader GL_VERTEX_SHADER in glShaderSource vs vsSource; glCompileShader vs; print_string(glGetShaderInfoLog vs); let fs = glCreateShader GL_FRAGMENT_SHADER in glShaderSource fs fsSource; glCompileShader fs; print_string(glGetShaderInfoLog fs); let sp = glCreateProgram() in glAttachShader sp vs; glAttachShader sp fs; glLinkProgram sp; print_string(glGetProgramInfoLog sp); glUseProgram sp; waveTimeLoc := glGetUniformLocation sp "waveTime"; waveWidthLoc := glGetUniformLocation sp "waveWidth"; waveHeightLoc := glGetUniformLocation sp "waveHeight"; print_string(glGetProgramInfoLog sp); Printf.printf "wave parameters location: %d %d %d\n%!" !waveTimeLoc !waveWidthLoc !waveHeightLoc; ;; let keyboard ~key ~x ~y = match key with | '\027' -> (* glDeleteShader vs; glDeleteShader fs; glDeleteProgram sp; *) exit(0) | '+' -> waveFreq += 0.1; Printf.printf "Modified time waveFreq + 0.1: %f\n%!" !waveFreq; | '-' -> waveFreq -= 0.1; Printf.printf "Modified time waveFreq - 0.1: %f\n%!" !waveFreq; | 'w' -> waveWidth += 0.1; Printf.printf "Modified width waveWidth + 0.1: %f\n%!" !waveWidth; | 'q' -> waveWidth -= 0.1; Printf.printf "Modified width waveWidth - 0.1: %f\n%!" !waveWidth; | 'h' -> waveHeight += 0.1; Printf.printf "Modified width waveWidth + 0.1: %f\n%!" !waveHeight; | 'g' -> waveHeight -= 0.1; Printf.printf "Modified width waveWidth - 0.1: %f\n%!" !waveHeight; | _ -> () ;; let reshape ~width ~height = glViewport 0 0 width height; glMatrixMode GL_PROJECTION; glLoadIdentity(); gluPerspective 40. 1. 0.0001 1000.0; glMatrixMode GL_MODELVIEW; glutPostRedisplay(); ;; let init_gl ~width ~height = glShadeModel GL_SMOOTH; glViewport 0 0 width height; glMatrixMode GL_PROJECTION; glLoadIdentity(); gluPerspective 40. 1. 0.0001 1000.0; glMatrixMode GL_MODELVIEW; glPolygonMode GL_FRONT_AND_BACK GL_LINE; ;; let () = ignore(glutInit Sys.argv); let width, height = 400, 400 in glutInitDisplayMode[GLUT_RGBA; GLUT_DOUBLE; GLUT_DEPTH]; glutInitWindowPosition ~x:100 ~y:100; glutInitWindowSize ~width ~height; ignore(glutCreateWindow ~title:"GLSL demo"); (* init openGL *) glEnable GL_DEPTH_TEST; setShaders(); init_gl ~width ~height; (* callback functions *) glutDisplayFunc ~display; glutKeyboardFunc ~keyboard; (* glutReshapeFunc ~reshape; *) (* enter the main loop *) glutMainLoop(); ;;