Browse Source

Changed glShaderSource to take a BlitzMax String and no length.

Added learnopengl examples.
Brucey 5 years ago
parent
commit
4f53a8eb1e

+ 0 - 62
examples/basic_window.bmx

@@ -1,62 +0,0 @@
-SuperStrict
-
-Framework GLFW.GLFWWindow
-Import GLFW.GLFWOpenGL
-
-
-' settings
-Const SCR_WIDTH:Int = 800
-Const SCR_HEIGHT:Int = 600
-
-' glfw: initialize and configure
-TGLFWWindow.Hint(GLFW_CONTEXT_VERSION_MAJOR, 3)
-TGLFWWindow.Hint(GLFW_CONTEXT_VERSION_MINOR, 3)
-TGLFWWindow.Hint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)
-
-' glfw window creation
-Local window:TGLFWWindow = New TMyWindow.Create(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL")
-
-If Not window Then
-	Throw "Failed to create GLFW window"
-End If
-
-window.MakeContextCurrent()
-
-' glad: load all OpenGL function pointers
-gladLoadGL(glfwGetProcAddress)
-
-
-' render loop
-While Not window.ShouldClose()
-
-	' input
-	ProcessInput(window)
-
-	' render
-	glClearColor(0.2, 0.3, 0.3, 1.0)
-	glClear(GL_COLOR_BUFFER_BIT)
-
-	' glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
-	window.SwapBuffers()
-	PollSystem
-
-Wend
-
-' process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
-Function ProcessInput(window:TGLFWWindow)
-	If window.IsKeyDown(GLFW_KEY_ESCAPE) Then
-		window.SetShouldClose(True)
-	End If
-End Function
-
-Type TMyWindow Extends TGLFWWindow
-
-	' glfw: whenever the window size changed (by OS or user resize) this callback function executes
-	Method OnFramebufferSize(width:Int, height:Int) Override
-	
-		' make sure the viewport matches the new window dimensions; note that width and
-		' height will be significantly larger than specified on retina displays.
-		glViewport(0, 0, width, height)
-	End Method
-
-End Type

+ 59 - 0
examples/learnopengl/1.getting_started/1.1.hello_window.bmx

@@ -0,0 +1,59 @@
+' https://learnopengl.com/
+
+SuperStrict
+
+Framework GLFW.GLFWWindow
+
+Import GLFW.GLFW
+Import GLFW.GLFWOpenGL
+Import GLFW.GLFWSystem
+
+Import BRL.StandardIO
+
+Local app_name:String = "Hello Window"
+
+Const SCR_WIDTH:UInt	= 800
+Const SCR_HEIGHT:UInt	= 600
+
+Type TGameWindow Extends TGLFWWindow
+	
+	Method OnFrameBufferSize (width:Int, height:Int)
+		glViewport (0, 0, width, height)
+	EndMethod
+	
+EndType
+
+Function ProcessInput (window:TGLFWWindow)
+	
+	If window.IsKeyDown (GLFW_KEY_ESCAPE)
+		window.SetShouldClose (True)
+	EndIf
+	
+EndFunction
+
+TGLFWWindow.Hint (GLFW_CONTEXT_VERSION_MAJOR, 3)
+TGLFWWindow.Hint (GLFW_CONTEXT_VERSION_MINOR, 3)
+TGLFWWindow.Hint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)
+
+?MacOS ' Ewww...
+	TGLFWWindow.Hint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE)
+?
+
+Local window:TGLFWWindow = New TGameWindow.Create(SCR_WIDTH, SCR_HEIGHT, app_name)
+
+If Not window
+	Print "Failed to create GLFW window!"
+	End
+EndIf
+
+window.MakeContextCurrent ()
+
+gladLoadGL (glfwGetProcAddress)
+
+While Not window.ShouldClose ()
+	ProcessInput (window)
+	window.SwapBuffers ()
+	PollSystem ()
+Wend
+
+End

+ 65 - 0
examples/learnopengl/1.getting_started/1.2.hello_window_clear.bmx

@@ -0,0 +1,65 @@
+' https://learnopengl.com/
+
+SuperStrict
+
+Framework GLFW.GLFWWindow
+
+Import GLFW.GLFW
+Import GLFW.GLFWOpenGL
+Import GLFW.GLFWSystem
+
+Import BRL.StandardIO
+
+Local app_name:String = "Hello Window Clear"
+
+Const SCR_WIDTH:UInt	= 800
+Const SCR_HEIGHT:UInt	= 600
+
+Type TGameWindow Extends TGLFWWindow
+	
+	Method OnFrameBufferSize (width:Int, height:Int)
+		glViewport (0, 0, width, height)
+	EndMethod
+	
+EndType
+
+Function ProcessInput (window:TGLFWWindow)
+	
+	If window.IsKeyDown (GLFW_KEY_ESCAPE)
+		window.SetShouldClose (True)
+	EndIf
+	
+EndFunction
+
+TGLFWWindow.Hint (GLFW_CONTEXT_VERSION_MAJOR, 3)
+TGLFWWindow.Hint (GLFW_CONTEXT_VERSION_MINOR, 3)
+TGLFWWindow.Hint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)
+
+?MacOS ' Ewww...
+	TGLFWWindow.Hint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE)
+?
+
+Local window:TGLFWWindow = New TGameWindow.Create (SCR_WIDTH, SCR_HEIGHT, app_name)
+
+If Not window
+	Print "Failed to create GLFW window!"
+	End
+EndIf
+
+window.MakeContextCurrent ()
+
+gladLoadGL (glfwGetProcAddress)
+
+While Not window.ShouldClose ()
+	
+	ProcessInput (window)
+
+	glClearColor (0.2, 0.3, 0.3, 1.0)
+	glClear (GL_COLOR_BUFFER_BIT)
+	
+	window.SwapBuffers ()
+	PollSystem ()
+	
+Wend
+
+End

+ 182 - 0
examples/learnopengl/1.getting_started/2.1.hello_triangle.bmx

@@ -0,0 +1,182 @@
+' https://learnopengl.com/
+
+SuperStrict
+
+Framework GLFW.GLFWWindow
+
+Import GLFW.GLFW
+Import GLFW.GLFWOpenGL
+Import GLFW.GLFWSystem
+
+Import BRL.StandardIO
+
+Local app_name:String = "Hello Triangle"
+
+' settings
+Const SCR_WIDTH:UInt	= 800
+Const SCR_HEIGHT:UInt	= 600
+
+Type TGameWindow Extends TGLFWWindow
+	
+	' whenever the window size changed (by OS or user resize) this callback method executes
+	Method OnFrameBufferSize (width:Int, height:Int)
+		' make sure the viewport matches the new window dimensions; note that width and
+		' height will be significantly larger than specified on retina displays.
+		glViewport (0, 0, width, height)
+	EndMethod
+	
+EndType
+
+' process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
+Function ProcessInput (window:TGLFWWindow)
+	
+	If window.IsKeyDown (GLFW_KEY_ESCAPE)
+		window.SetShouldClose (True)
+	EndIf
+	
+EndFunction
+
+' glfw: initialize and configure
+TGLFWWindow.Hint (GLFW_CONTEXT_VERSION_MAJOR, 3)
+TGLFWWindow.Hint (GLFW_CONTEXT_VERSION_MINOR, 3)
+TGLFWWindow.Hint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)
+
+?MacOS ' Ewww...
+	TGLFWWindow.Hint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE)
+?
+
+' glfw window creation
+Local window:TGLFWWindow = New TGameWindow.Create (SCR_WIDTH, SCR_HEIGHT, app_name)
+
+If Not window
+	Print "Failed to create GLFW window!"
+	End
+EndIf
+
+window.MakeContextCurrent ()
+
+' glad: load all OpenGL function pointers
+gladLoadGL (glfwGetProcAddress)
+
+Local vertexShaderSource:String
+
+vertexShaderSource :+ "#version 330 core~n"
+vertexShaderSource :+ "layout (location = 0) in vec3 aPos;~n"
+vertexShaderSource :+ "void main()~n"
+vertexShaderSource :+ "{~n"
+vertexShaderSource :+ "   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);~n"
+vertexShaderSource :+ "}~n"
+
+Local fragmentShaderSource:String
+
+fragmentShaderSource :+ "#version 330 core~n"
+fragmentShaderSource :+ "out vec4 FragColor;~n"
+fragmentShaderSource :+ "void main()~n"
+fragmentShaderSource :+ "{~n"
+fragmentShaderSource :+ "   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);~n"
+fragmentShaderSource :+ "}~n"
+
+' vertex shader
+Local vertexShader:Int = glCreateShader (GL_VERTEX_SHADER)
+
+glShaderSource (vertexShader, 1, vertexShaderSource)
+glCompileShader (vertexShader)
+
+Local success:Int
+Local infoLog:Byte [512]
+
+' check for shader compile errors
+glGetShaderiv (vertexShader, GL_COMPILE_STATUS, Varptr success)
+
+If Not success
+	glGetShaderInfoLog (vertexShader, 512, Null, infoLog)
+	Print "Vertex shader compilation failed: " + String.FromCString (infoLog)
+EndIf
+
+Local fragmentShader:Int = glCreateShader (GL_FRAGMENT_SHADER)
+
+glShaderSource (fragmentShader, 1, fragmentShaderSource)
+glCompileShader (fragmentShader)
+
+' check for shader compile errors
+glGetShaderiv (fragmentShader, GL_COMPILE_STATUS, Varptr success)
+
+If Not success
+	glGetShaderInfoLog (fragmentShader, 512, Null, infoLog)
+	Print "Fragment shader compilation failed: " + String.FromCString (infoLog)
+EndIf
+
+' link shaders
+Local shaderProgram:Int = glCreateProgram ()
+
+glAttachShader (shaderProgram, vertexShader)
+glAttachShader (shaderProgram, fragmentShader)
+glLinkProgram (shaderProgram)
+
+' check for linking errors
+glGetProgramiv (shaderProgram, GL_LINK_STATUS, Varptr success)
+
+If Not success
+	glGetProgramInfoLog (shaderProgram, 512, Null, infoLog)
+	Print "Shader program linking failed: " + String.FromCString (infoLog)
+EndIf
+
+glDeleteShader (vertexShader)
+glDeleteShader (fragmentShader)
+
+' set up vertex data (and buffer(s)) and configure vertex attributes
+Local vertices:Float [] = [..
+	-0.5, -0.5, 0.0, ..
+	0.5, -0.5, 0.0, ..
+	0.0, 0.5, 0.0]
+
+Local VBO:UInt
+Local VAO:UInt
+
+glGenVertexArrays (1, Varptr VAO)
+glGenBuffers (1, Varptr VBO)
+' bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
+glBindVertexArray (VAO)
+
+glBindBuffer (GL_ARRAY_BUFFER, VBO)
+glBufferData (GL_ARRAY_BUFFER, vertices.length * SizeOf (0:Float), vertices, GL_STATIC_DRAW)
+
+glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 3 * SizeOf (0:Float), 0:Byte Ptr)
+glEnableVertexAttribArray (0)
+
+' note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
+glBindBuffer (GL_ARRAY_BUFFER, 0)
+
+' You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
+' VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
+glBindVertexArray (0)
+
+' render loop
+' -----------
+While Not window.ShouldClose ()
+	
+	' input
+	' -----
+	ProcessInput (window)
+
+	' render
+	' ------
+	glClearColor (0.2, 0.3, 0.3, 1.0)
+	glClear (GL_COLOR_BUFFER_BIT)
+	
+	' draw our first triangle
+	glUseProgram (shaderProgram)
+	glBindVertexArray (VAO) ' seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized
+	glDrawArrays (GL_TRIANGLES, 0, 3)
+
+	' swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
+	window.SwapBuffers ()
+	PollSystem ()
+	
+Wend
+
+' optional: de-allocate all resources once they've outlived their purpose
+glDeleteVertexArrays (1, Varptr VAO)
+glDeleteBuffers (1, Varptr VBO)
+
+End

+ 196 - 0
examples/learnopengl/1.getting_started/2.2.hello_triangle_indexed.bmx

@@ -0,0 +1,196 @@
+' https://learnopengl.com/
+
+SuperStrict
+
+Framework GLFW.GLFWWindow
+
+Import GLFW.GLFW
+Import GLFW.GLFWOpenGL
+Import GLFW.GLFWSystem
+
+Import BRL.StandardIO
+
+Local app_name:String = "Hello Triangle Indexed"
+
+Const SCR_WIDTH:UInt	= 800
+Const SCR_HEIGHT:UInt	= 600
+
+Type TGameWindow Extends TGLFWWindow
+	
+	' glfw: whenever the window size changed (by OS or user resize) this callback method executes
+	Method OnFrameBufferSize (width:Int, height:Int)
+		' make sure the viewport matches the new window dimensions; note that width and 
+		' height will be significantly larger than specified on retina displays.
+		glViewport (0, 0, width, height)
+	EndMethod
+	
+EndType
+
+' process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
+Function ProcessInput (window:TGLFWWindow)
+	
+	If window.IsKeyDown (GLFW_KEY_ESCAPE)
+		window.SetShouldClose (True)
+	EndIf
+	
+EndFunction
+
+' glfw: initialize and configure
+TGLFWWindow.Hint (GLFW_CONTEXT_VERSION_MAJOR, 3)
+TGLFWWindow.Hint (GLFW_CONTEXT_VERSION_MINOR, 3)
+TGLFWWindow.Hint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)
+
+?MacOS ' Ewww...
+	TGLFWWindow.Hint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE)
+?
+
+' glfw window creation
+Local window:TGLFWWindow = New TGameWindow.Create (SCR_WIDTH, SCR_HEIGHT, app_name)
+
+If Not window
+	Print "Failed to create GLFW window!"
+	End
+EndIf
+
+window.MakeContextCurrent ()
+
+' glad: load all OpenGL function pointers
+gladLoadGL (glfwGetProcAddress)
+
+Local vertexShaderSource:String
+
+vertexShaderSource :+ "#version 330 core~n"
+vertexShaderSource :+ "layout (location = 0) in vec3 aPos;~n"
+vertexShaderSource :+ "void main()~n"
+vertexShaderSource :+ "{~n"
+vertexShaderSource :+ "   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);~n"
+vertexShaderSource :+ "}~n"
+
+Local fragmentShaderSource:String
+
+fragmentShaderSource :+ "#version 330 core~n"
+fragmentShaderSource :+ "out vec4 FragColor;~n"
+fragmentShaderSource :+ "void main()~n"
+fragmentShaderSource :+ "{~n"
+fragmentShaderSource :+ "   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);~n"
+fragmentShaderSource :+ "}~n"
+
+' build and compile our shader program
+' ------------------------------------
+
+' vertex shader
+Local vertexShader:Int = glCreateShader (GL_VERTEX_SHADER)
+
+glShaderSource (vertexShader, 1, vertexShaderSource)
+glCompileShader (vertexShader)
+
+Local success:Int
+Local infoLog:Byte [512]
+
+' check for shader compile errors
+glGetShaderiv (vertexShader, GL_COMPILE_STATUS, Varptr success)
+
+If Not success
+	glGetShaderInfoLog (vertexShader, 512, Null, infoLog)
+	Print "Vertex shader compilation failed: " + String.FromCString (infoLog)
+EndIf
+
+' fragment shader
+Local fragmentShader:Int = glCreateShader (GL_FRAGMENT_SHADER)
+
+glShaderSource (fragmentShader, 1, fragmentShaderSource)
+glCompileShader (fragmentShader)
+
+' check for shader compile errors
+glGetShaderiv (fragmentShader, GL_COMPILE_STATUS, Varptr success)
+
+If Not success
+	glGetShaderInfoLog (fragmentShader, 512, Null, infoLog)
+	Print "Fragment shader compilation failed: " + String.FromCString (infoLog)
+EndIf
+
+' link shaders
+Local shaderProgram:Int = glCreateProgram ()
+
+glAttachShader (shaderProgram, vertexShader)
+glAttachShader (shaderProgram, fragmentShader)
+glLinkProgram (shaderProgram)
+
+glGetProgramiv (shaderProgram, GL_LINK_STATUS, Varptr success)
+
+If Not success
+	glGetProgramInfoLog (shaderProgram, 512, Null, infoLog)
+	Print "Shader program linking failed: " + String.FromCString (infoLog)
+EndIf
+
+glDeleteShader (vertexShader)
+glDeleteShader (fragmentShader)
+
+' set up vertex data (and buffer(s)) and configure vertex attributes
+Local vertices:Float [] = [..
+	0.5, 0.5, 0.0, ..
+	0.5, -0.5, 0.0, ..
+	-0.5, -0.5, 0.0, ..
+	-0.5, 0.5, 0.0]
+
+Local indices:UInt [] = [..
+	0, 1, 3, ..
+	1, 2, 3]
+
+Local VBO:UInt
+Local VAO:UInt
+Local EBO:UInt
+
+glGenVertexArrays (1, Varptr VAO)
+glGenBuffers (1, Varptr VBO)
+glGenBuffers (1, Varptr EBO)
+
+' bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
+glBindVertexArray (VAO)
+
+glBindBuffer (GL_ARRAY_BUFFER, VBO)
+glBufferData (GL_ARRAY_BUFFER, vertices.length * SizeOf (0:Float), vertices, GL_STATIC_DRAW)
+
+glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, EBO)
+glBufferData (GL_ELEMENT_ARRAY_BUFFER, indices.length * SizeOf (0:Float), indices, GL_STATIC_DRAW)
+
+glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 3 * SizeOf (0:Float), 0:Byte Ptr)
+glEnableVertexAttribArray (0)
+
+' note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
+glBindBuffer (GL_ARRAY_BUFFER, 0)
+
+' You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
+' VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
+glBindVertexArray (0)
+
+' render loop
+' -----------
+While Not window.ShouldClose ()
+	
+	' input
+	' -----
+	ProcessInput (window)
+
+	' render
+	' ------
+	glClearColor (0.2, 0.3, 0.3, 1.0)
+	glClear (GL_COLOR_BUFFER_BIT)
+	
+	' draw our first triangle
+	glUseProgram (shaderProgram)
+	glBindVertexArray (VAO) ' seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized
+	glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0)
+
+	' swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
+	window.SwapBuffers ()
+	PollSystem ()
+	
+Wend
+
+' optional: de-allocate all resources once they've outlived their purpose
+glDeleteVertexArrays (1, Varptr VAO)
+glDeleteBuffers (1, Varptr VBO)
+glDeleteBuffers (1, Varptr EBO)
+
+End

+ 181 - 0
examples/learnopengl/1.getting_started/3.1_shaders_uniform.bmx

@@ -0,0 +1,181 @@
+' https://learnopengl.com/
+
+SuperStrict
+
+Framework GLFW.GLFWWindow
+
+Import GLFW.GLFW
+Import GLFW.GLFWOpenGL
+Import GLFW.GLFWSystem
+
+Import BRL.StandardIO
+
+Local app_name:String = "Shaders Uniform"
+
+' settings
+Const SCR_WIDTH:UInt	= 800
+Const SCR_HEIGHT:UInt	= 600
+
+Type TGameWindow Extends TGLFWWindow
+	
+	Method OnFrameBufferSize (width:Int, height:Int)
+		glViewport (0, 0, width, height)
+	EndMethod
+	
+EndType
+
+Function ProcessInput (window:TGLFWWindow)
+	
+	If window.IsKeyDown (GLFW_KEY_ESCAPE)
+		window.SetShouldClose (True)
+	EndIf
+	
+EndFunction
+
+' initialize and configure
+TGLFWWindow.Hint (GLFW_CONTEXT_VERSION_MAJOR, 3)
+TGLFWWindow.Hint (GLFW_CONTEXT_VERSION_MINOR, 3)
+TGLFWWindow.Hint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)
+
+?MacOS ' Ewww...
+	TGLFWWindow.Hint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE)
+?
+
+' glfw window creation
+Local window:TGLFWWindow = New TGameWindow.Create (SCR_WIDTH, SCR_HEIGHT, app_name)
+
+If Not window
+	Print "Failed to create GLFW window!"
+	End
+EndIf
+
+window.MakeContextCurrent ()
+
+' glad: load all OpenGL function pointers
+gladLoadGL (glfwGetProcAddress)
+
+' build and compile our shader program
+Local vertexShaderSource:String
+
+vertexShaderSource :+ "#version 330 core~n"
+vertexShaderSource :+ "layout (location = 0) in vec3 aPos;~n"
+vertexShaderSource :+ "void main()~n"
+vertexShaderSource :+ "{~n"
+vertexShaderSource :+ "   gl_Position = vec4(aPos, 1.0);~n"
+vertexShaderSource :+ "}~n"
+
+Local fragmentShaderSource:String
+
+fragmentShaderSource :+ "#version 330 core~n"
+fragmentShaderSource :+ "out vec4 FragColor;~n"
+fragmentShaderSource :+ "uniform vec4 ourColor;~n"
+fragmentShaderSource :+ "void main()~n"
+fragmentShaderSource :+ "{~n"
+fragmentShaderSource :+ "   FragColor = ourColor;~n"
+fragmentShaderSource :+ "}~n"
+
+Local vertexShader:Int = glCreateShader (GL_VERTEX_SHADER)
+
+glShaderSource (vertexShader, 1, vertexShaderSource)
+glCompileShader (vertexShader)
+
+Local success:Int
+Local infoLog:Byte [512]
+
+glGetShaderiv (vertexShader, GL_COMPILE_STATUS, Varptr success)
+
+If Not success
+	glGetShaderInfoLog (vertexShader, 512, Null, infoLog)
+	Print "Vertex shader compilation failed: " + String.FromCString (infoLog)
+EndIf
+
+Local fragmentShader:Int = glCreateShader (GL_FRAGMENT_SHADER)
+
+glShaderSource (fragmentShader, 1, fragmentShaderSource)
+glCompileShader (fragmentShader)
+
+glGetShaderiv (fragmentShader, GL_COMPILE_STATUS, Varptr success)
+
+If Not success
+	glGetShaderInfoLog (fragmentShader, 512, Null, infoLog)
+	Print "Fragment shader compilation failed: " + String.FromCString (infoLog)
+EndIf
+
+' link shaders
+Local shaderProgram:Int = glCreateProgram ()
+
+glAttachShader (shaderProgram, vertexShader)
+glAttachShader (shaderProgram, fragmentShader)
+glLinkProgram (shaderProgram)
+
+glGetProgramiv (shaderProgram, GL_LINK_STATUS, Varptr success)
+
+If Not success
+	glGetProgramInfoLog (shaderProgram, 512, Null, infoLog)
+	Print "Shader program linking failed: " + String.FromCString (infoLog)
+EndIf
+
+glDeleteShader (vertexShader)
+glDeleteShader (fragmentShader)
+
+' set up vertex data (and buffer(s)) and configure vertex attributes
+Local vertices:Float [] = [..
+	0.5, -0.5, 0.0, ..
+	-0.5, -0.5, 0.0, ..
+	0.0, 0.5, 0.0]
+
+Local VBO:UInt
+Local VAO:UInt
+
+glGenVertexArrays (1, Varptr VAO)
+glGenBuffers (1, Varptr VBO)
+
+' bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
+glBindVertexArray (VAO)
+
+glBindBuffer (GL_ARRAY_BUFFER, VBO)
+glBufferData (GL_ARRAY_BUFFER, vertices.length * SizeOf (0:Float), vertices, GL_STATIC_DRAW)
+
+glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 3 * SizeOf (0:Float), 0:Byte Ptr)
+glEnableVertexAttribArray (0)
+
+' bind the VAO (it was already bound, but just to demonstrate): seeing as we only have a single VAO we can
+' just bind it beforehand before rendering the respective triangle; this is another approach.
+
+glBindVertexArray (VAO)
+
+While Not window.ShouldClose ()
+	
+	' input
+	' -----
+	ProcessInput (window)
+
+	' render
+	' ------
+	glClearColor (0.2, 0.3, 0.3, 1.0)
+	glClear (GL_COLOR_BUFFER_BIT)
+	
+	' be sure to activate the shader before any calls to glUniform
+	glUseProgram (shaderProgram)
+
+	' update shader uniform
+	Local timeValue:Float = GetTime()
+	Local greenValue:Float = Sin (timeValue * 57.2958) / 2.0 + 0.5
+
+	Local vertexColorLocation:Int = glGetUniformLocation (shaderProgram, "ourColor")
+	glUniform4f (vertexColorLocation, 0.0, greenValue, 0.0, 1.0)
+
+	' render the triangle
+	glDrawArrays (GL_TRIANGLES, 0, 3)
+
+	' swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
+	window.SwapBuffers ()
+	PollSystem ()
+	
+Wend
+
+' optional: de-allocate all resources once they've outlived their purpose
+glDeleteVertexArrays (1, Varptr VAO)
+glDeleteBuffers (1, Varptr VBO)
+
+End

+ 10 - 1
glfwopengl.mod/g2bmx.bmx

@@ -206,7 +206,9 @@ Type TCodeGenerator
 								Local key$="PFN"+sym[5..].ToUpper()+"PROC"
 								Local val:Tproto=Tproto( funMap.ValueForKey( key ) )
 								If val
-									GenerateApi ( "Global "+id+val.proto+"=~q"+val.exproto.Replace("XXXXXXXX", sym).Trim()+"~q", "GL Global "+id+val.proto )
+									Local prefix:String
+									If id = "glShaderSource" prefix = "_"
+									GenerateApi ( "Global "+prefix+id+val.proto+"=~q"+val.exproto.Replace("XXXXXXXX", sym).Trim()+"~q", "GL Global "+id+val.proto )
 								Else
 									DebugLog "***** "+sym+" *****"
 								EndIf
@@ -466,6 +468,13 @@ Type TCodeGenerator
 		Next
 		
 		WriteLine OutGlad, ""
+		
+		WriteLine OutGlad, "Function glShaderSource(shader_:Int,count_:Int,source:String)"
+		WriteLine OutGlad, "~tLocal s:Byte Ptr = source.ToUTF8String()"
+		WriteLine OutGlad, "~t_glShaderSource(shader_, count_, Varptr s, Null)"
+		WriteLine OutGlad, "~tMemFree s"
+		WriteLine OutGlad, "End Function"
+		
 		'WriteLine OutGlad, "?"
 		
 		OutGlad.Close

+ 1 - 1
glfwopengl.mod/glad00.bmx

@@ -1,6 +1,6 @@
 '
 ' NOTE : Generated file. Do not edit. Your changes may be lost on the next update!
-'        Generated by g2bmx on 10 Mar 2020
+'        Generated by g2bmx on 18 Mar 2020
 '
 Strict
 

+ 6 - 1
glfwopengl.mod/glfwopengl.bmx

@@ -1,6 +1,6 @@
 '
 ' NOTE : Generated file. Do not edit. Your changes may be lost on the next update!
-'        Generated by g2bmx on 10 Mar 2020
+'        Generated by g2bmx on 18 Mar 2020
 '
 Strict
 
@@ -19,3 +19,8 @@ Import "../glfw.mod/glfw/deps/*.h"
 Import "opengl.bmx"
 Import "glad00.bmx"
 
+Function glShaderSource(shader_:Int,count_:Int,source:String)
+	Local s:Byte Ptr = source.ToUTF8String()
+	_glShaderSource(shader_, count_, Varptr s, Null)
+	MemFree s
+End Function

+ 2 - 2
glfwopengl.mod/opengl.bmx

@@ -1,6 +1,6 @@
 '
 ' NOTE : Generated file. Do not edit. Your changes may be lost on the next update!
-'        Generated by g2bmx on 10 Mar 2020
+'        Generated by g2bmx on 18 Mar 2020
 '
 Strict
 
@@ -1837,7 +1837,7 @@ Global glSecondaryColorP3uiv(type_:Int,color_:Int Ptr)="void glad_glSecondaryCol
 Global glSecondaryColorPointer(size_:Int,type_:Int,stride_:Int,pointer_:Byte Ptr)="void glad_glSecondaryColorPointer( GLint, GLenum, GLsizei,const void*)!"
 Global glSelectBuffer(size_:Int,buffer_:Int Ptr)="void glad_glSelectBuffer( GLsizei, GLuint*)!"
 Global glShadeModel(mode_:Int)="void glad_glShadeModel( GLenum)!"
-Global glShaderSource(shader_:Int,count_:Int,string_:Byte Ptr Ptr,length_:Int Ptr)="void glad_glShaderSource( GLuint, GLsizei,const GLchar* const*,const GLint*)!"
+Global _glShaderSource(shader_:Int,count_:Int,string_:Byte Ptr Ptr,length_:Int Ptr)="void glad_glShaderSource( GLuint, GLsizei,const GLchar* const*,const GLint*)!"
 Global glStencilFunc(func_:Int,ref_:Int,mask_:Int)="void glad_glStencilFunc( GLenum, GLint, GLuint)!"
 Global glStencilFuncSeparate(face_:Int,func_:Int,ref_:Int,mask_:Int)="void glad_glStencilFuncSeparate( GLenum, GLenum, GLint, GLuint)!"
 Global glStencilMask(mask_:Int)="void glad_glStencilMask( GLuint)!"