(phixonline)--> -- -- demo\rosetta\OpenGL.exw -- ======================= -- with javascript_semantics requires("1.0.1") include pGUI.e include opengl.e Ihandln dlg Ihandle canvas constant fragment_shader = """ precision highp float; varying vec4 v_color; void main(void) { // "Varying" variables are implicitly interpolated across triangles. gl_FragColor = v_color; }""", vertex_shader = """ attribute vec3 a_position; attribute vec4 a_color; varying vec4 v_color; void main(void) { gl_Position = vec4(a_position, 1.0); v_color = a_color; }""" function get_shader(string src, integer stype) integer shader = glCreateShader(stype) glShaderSource(shader, src) glCompileShader(shader) if not glGetShaderParameter(shader, GL_COMPILE_STATUS) then crash(glGetShaderInfoLog(shader)) end if return shader end function constant vertices = { -0.5, -0.5, 0, -- (bl) +0.5, -0.5, 0, -- (br) -0.5, +0.5, 0 }, -- (tl) -- +0.5, +0.5, 0 }, -- (tr) colours = { 1, 0, 0, 1, -- red (bl) 0, 1, 0, 1, -- green (br) 0, 0, 1, 1 } -- blue (tl) procedure set_shader() IupGLMakeCurrent(canvas) integer shaderProgram = glCreateProgram() glAttachShader(shaderProgram, get_shader(vertex_shader,GL_VERTEX_SHADER)) glAttachShader(shaderProgram, get_shader(fragment_shader,GL_FRAGMENT_SHADER)) glLinkProgram(shaderProgram) if not glGetProgramParameter(shaderProgram, GL_LINK_STATUS) then crash(glGetProgramInfoLog(shaderProgram)) end if glUseProgram(shaderProgram) // Get the indexes to communicate vertex attributes to the program. integer positionAttr = glGetAttribLocation(shaderProgram, "a_position"), colorAttr = glGetAttribLocation(shaderProgram, "a_color") // And specify that we will be actually delivering data to those attributes. glEnableVertexAttribArray(positionAttr) glEnableVertexAttribArray(colorAttr) // Store vertex positions and colors in array buffer objects. integer positionBuffer = glCreateBuffer() glBindBuffer(GL_ARRAY_BUFFER, positionBuffer) {integer size, atom pData} = glFloat32Array(vertices) glBufferData(GL_ARRAY_BUFFER, size, pData, GL_STATIC_DRAW) glEnableVertexAttribArray(positionBuffer) integer colorBuffer = glCreateBuffer() glBindBuffer(GL_ARRAY_BUFFER, colorBuffer) {size, pData} = glFloat32Array(colours) glBufferData(GL_ARRAY_BUFFER, size, pData, GL_STATIC_DRAW) glEnableVertexAttribArray(colorBuffer) glEnable(GL_DEPTH_TEST) // Specify the array data to render. // 3 and 4 are the lengths of the vectors (3 for XYZ, 4 for RGBA). glBindBuffer(GL_ARRAY_BUFFER, positionBuffer) glVertexAttribPointer(positionAttr, 3, GL_FLOAT, false, 0, 0) glEnableVertexAttribArray(positionAttr) glBindBuffer(GL_ARRAY_BUFFER, colorBuffer) glVertexAttribPointer(colorAttr, 4, GL_FLOAT, false, 0, 0) glEnableVertexAttribArray(colorAttr) end procedure bool drawn = false function action(Ihandle /*ih*/) if not drawn or platform()!=JS then glClearColor(0.3, 0.3, 0.3, 1.0) integer {w,h} = IupGetIntInt(canvas,"DRAWSIZE") glViewport(0, 0, w, h) glClear(GL_COLOR_BUFFER_BIT || GL_DEPTH_BUFFER_BIT) // Draw triangles using the specified arrays. integer numVertices = length(vertices)/3 // 3 coordinates per vertex glDrawArrays(GL_TRIANGLES, 0, numVertices) // Check for errors. while true do integer e = glGetError() if e=GL_NO_ERROR then exit end if printf(1,"GL error %d\n", e) end while glFlush() drawn = true end if return IUP_DEFAULT end function procedure main() IupOpen() canvas = IupGLCanvas(Icallback("action"), "RASTERSIZE=640x480") dlg = IupDialog(canvas, "TITLE=OpenGLShader, SHRINK=YES") IupMap(dlg) set_shader() IupShow(dlg) if platform()!=JS then IupMainLoop() dlg = IupDestroy(dlg) IupClose() end if end procedure main()