SyntaxBomb - Indie Coders

Languages & Coding => BlitzMax / BlitzMax NG => Brucey's Modules => Topic started by: DruggedBunny on March 10, 2020, 02:04:32

Title: Any chance of a GLFW port?
Post by: DruggedBunny on March 10, 2020, 02:04:32
Hi Brucey,

Just wondering if you've looked at GLFW and how easy/difficult it would be to port?

I've been playing with this site (https://learnopengl.com/)'s tutorials in Visual Studio, but would much rather be doing it in Blitz!

But I can't for the life of me figure out the basics of setting up an OpenGL window in Max with the right context version/profile, totally confused by the potential mixes of GLEW, GLAD, SDL, GLGraphics, etc, etc and I've been trawling through the mod sources for hours trying to figure it out, to no avail!

I'm basically hoping to be able to implement the window setup here using GLFW:

https://learnopengl.com/Getting-started/Hello-Window (https://learnopengl.com/Getting-started/Hello-Window)

I don't know if you're big on new library requests, but if you don't ask... !

Failing that, does anyone have a simple example that would implement a version 3.3 core profile??

Thanks for reading,
James Boyd/DruggedBunny.
Title: Re: Any chance of a GLFW port?
Post by: Brucey on March 10, 2020, 06:30:04
Hi James :)

You may find this interesting : https://github.com/bmx-ng/ray.mod

It is a binding for raylib, which actually uses GLFW for windowing and events, etc.

Okay, so it's not directly using it in actual BlitzMax code.. so it's a bit of a cheat. However, I guess it proves it wouldn't be a giant leap to implement it properly.
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on March 10, 2020, 08:18:58
Oh, cool, thanks, Brucey!

I'll have a look tonight to see if I can see how it's been done, but if you find yourself bored one day... !

I know GLAD is in there already, so it would make NG pretty darn handy for use with LearnOpenGL.

Thanks again.
Title: Re: Any chance of a GLFW port?
Post by: Brucey on March 10, 2020, 16:37:05
If I was going to do it, I'd be more inclined to make it more "BlitzMaxy", so rather than have to pass a window handle into all the window functions, there'd be a Type that hides that...

Although if you really wanted to stay true to the examples, you could still work with the "raw" functions.
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on March 10, 2020, 21:56:50
No complaints from me, Brucey, if you find yourself with time on your hands... ;)

I just want a nice easy way to set up windows/contexts with particular feature sets of OpenGL (eg. 3.3 in the tutorial, with Core Profile) so I can play with the actual GL code, and this was nice and easy for me to grasp in C++ with GLFW, but it's just... no fun!

Thanks for considering, appreciated!
Title: Re: Any chance of a GLFW port?
Post by: Brucey on March 11, 2020, 07:12:31
Would something like this work for you?

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


It's a bit rough around the edges at the moment - for example, I'm still toying with having the "load gl" bit done automagically somewhere...

The window handles all the callbacks, so you just override the ones you are interested in...
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on March 11, 2020, 08:21:03
Yeah, that looks great to me!

It is relatively low-level stuff, especially since half the point is to get into 'raw' OpenGL, so I don't think it's too much of a hardship to have to call the one-line GLAD loader, though I get where you're coming from.

Look forward to trying it -- I'll basically be going through the tutorial (admittedly rather slowly), so should get to give it a good test anyway.
Title: Re: Any chance of a GLFW port?
Post by: Brucey on March 11, 2020, 17:26:37
Evening  8)

See how you get on with : https://github.com/bmx-ng/glfw.mod

There is one example - which is basically the first learnOpenGL example.
I've used the default GLAD header from which to generate the sources from. If that doesn't cover everything you need, let me know and I'll see about generating a new header with a higher OpenGL level.

It's only been tested on Win32 64-bit so far, so YMMV anywhere else.
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on March 11, 2020, 23:36:02
Wow, Brucey, I'm sure I've said it a fair few times, but you are truly a god among men! I only posted thinking you might add it to a list of possibles, if I was lucky!

The sample works here (I'm on Windows 7 64-bit anyway), so I'll dig in over the next few days and see if I can implement a few more samples, and try keep them in order to add to the mod examples.

I'll buy you a few pints at the end of the month... thank you so much for this!
Title: Re: Any chance of a GLFW port?
Post by: Brucey on March 12, 2020, 06:21:35
Heh, glad I could be useful :)

It's all gone rather smoothly so far. No major hiccups as yet - although I should probably get around to trying it on some of the other platforms at some point.
I'll get the rest of the apis implemented and document it a bit more too.


And as it happens, we are doing a special on github sponsorship at the moment, available from only $1 a month. But no worries either way ;)

Have fun!
Title: Re: Any chance of a GLFW port?
Post by: Derron on March 12, 2020, 07:12:24
Quote from: Brucey on March 12, 2020, 06:21:35
And as it happens, we are doing a special on github sponsorship at the moment, available from only $1 a month. But no worries either way ;)

Dunno how long (it is for "one year") but the next few months github will double what you sponsor. So my fiver becomes a tenner.


Will try the sample on linux when back at home.


bye
Ron
Title: Re: Any chance of a GLFW port?
Post by: Brucey on March 12, 2020, 07:14:50
As I say, I haven't tried it on any other targets yet, and usually it requires a few tweaks to get things sorted.... don't hold your breath.
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on March 12, 2020, 08:09:48
Ha, didn't even know GitHub sponsorship was a thing! I'll look into it!
Title: Re: Any chance of a GLFW port?
Post by: Brucey on March 12, 2020, 16:30:07
It now builds and runs on 64-bit Linux (Ubuntu).
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on March 13, 2020, 05:53:33
Nice!

Just to show I'm doing something with this, I've started converting some of the GitHub samples (https://github.com/JoeyDeVries/LearnOpenGL/tree/master/src/1.getting_started).

Done 1.1 and 1.2, which basically puts me at your sample! However, I'm attempting to implement each from scratch myself, just referencing your sample to get the hang of the differences.

I'll do a few more tonight/tomorrow (oh, and will look at patronage) and post somewhere, then move on to the tutorial proper, which I was trying to do in C++ without reference to the 'answers' (ie. final source) so as to better understand what was going on.

It's ten to six, so I'm going back to bed...

Thanks again, Brucey.
Title: Re: Any chance of a GLFW port?
Post by: Brucey on March 13, 2020, 06:23:53
Cool.
If you want, we can end up having a "learnopengl" sub folder/s in examples with all of them there for future learners to reference :)
(assuming you make it that far! - as there are a few)
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on March 13, 2020, 08:12:15
Yeah, I'll submit whatever I manage to get through anyway!
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on March 13, 2020, 23:10:38
Hi Brucey, I get an error with the latest release when building the example, or my code (deleted .bmx folder), on Windows 7 64-bit:

[  9%] Processing:source.bmx
[ 11%] Processing:common.bmx
[ 13%] Processing:glad00.bmx
[ 14%] Processing:opengl.bmx
[ 16%] Processing:common.bmx
[ 26%] Processing:common.bmx
[ 27%] Processing:glfwmonitor.bmx
[ 29%] Processing:glfwopengl.bmx
Compile Error: Operator [] with 'Int' index is not defined for type 'SGLFWvidmode'
[d:/DevTools/Blitz/BlitzMaxNG/mod/glfw.mod/glfwmonitor.mod/glfwmonitor.bmx;126;0]
Build Error: failed to compile (-1) d:/DevTools/Blitz/BlitzMaxNG/mod/glfw.mod/glfwmonitor.mod/glfwmonitor.bmxThe terminal process terminated with exit code: 4294967295


Going back to previous version still builds properly.
Title: Re: Any chance of a GLFW port?
Post by: therevills on March 14, 2020, 09:07:29
Whats the advantage of using GLFW over the normal Blitz/NG drivers of OpenGL/DX?
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on March 14, 2020, 10:53:45
My main reason: I've no idea how to use them!

That tutorial site uses GLFW so it's easy to get along with it.

And it's a popular system, so good to have.
Title: Re: Any chance of a GLFW port?
Post by: Brucey on March 14, 2020, 20:34:20
Oh, sorry James. You'll need the latest bcc... Assuming you are fairly up-to-date, that should be all you need. (otherwise, after updating bcc, you may also need to update brl...)
(I've been making enhancements/fixes to the Struct stuff, which lets you do much more with them than previously)

Title: Re: Any chance of a GLFW port?
Post by: Brucey on March 14, 2020, 20:38:14
@therevills

For now, GLFW is not going to be much used to you, unless you are happy to start doing some low-level coding - I've only implemented GLFW, and nothing much to integrate it with max2d etc.

But for what James wanted - to use the learnopengl stuff - it's an almost complete implementation. I've just got some joystick/gamepad stuff to finish, but everything else is done, I think.

At some point, I may consider using it as a "backend" for the standard BRL stuff - much in the way SDL works now.
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on March 14, 2020, 21:28:26
That would be really cool, but I'll let you take a breather for now!  :D

I'll update and report back, cheers.
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on March 14, 2020, 23:26:16
Hmm, I've spent about 2 hours trying to get latest bcc/brl/pub to build, but all to no avail! (Got bcc going, but a simple Print "Hello" just ends with (3)/BlitzMax/mod/brl.mod/max2d.mod/.bmx/max2d.bmx.release.win32.x64.c:915:12: error: incompatible types when assigning to type 'struct brl_color_SColor8' from type.)

I'll stick with the previous version for the moment, should do me fine for now!
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on March 15, 2020, 23:56:03
Here are my straight conversions of the official samples (https://github.com/JoeyDeVries/LearnOpenGL/tree/master/src/1.getting_started) so far:

1.1 Hello Window



' 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



1.2 Hello Window Clear



' 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


2.1 Hello Triangle:



' 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"

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)

Local vertexShaderSource:Byte Ptr
Local vertexShaderString:String

vertexShaderString :+ "#version 330 core~n"
vertexShaderString :+ "layout (location = 0) in vec3 aPos;~n"
vertexShaderString :+ "void main()~n"
vertexShaderString :+ "{~n"
vertexShaderString :+ "   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);~n"
vertexShaderString :+ "}~n"

vertexShaderSource = vertexShaderString.ToCString ()

Local fragmentShaderSource:Byte Ptr
Local fragmentShaderString:String

fragmentShaderString :+ "#version 330 core~n"
fragmentShaderString :+ "out vec4 FragColor;~n"
fragmentShaderString :+ "void main()~n"
fragmentShaderString :+ "{~n"
fragmentShaderString :+ "   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);~n"
fragmentShaderString :+ "}~n"

fragmentShaderSource = fragmentShaderString.ToCString ()

Local vertexShader:Int = glCreateShader (GL_VERTEX_SHADER)

glShaderSource (vertexShader, 1, Varptr vertexShaderSource, Null)
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, Varptr fragmentShaderSource, Null)
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

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)

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)
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)

glBindBuffer (GL_ARRAY_BUFFER, 0)

glBindVertexArray (0)

While Not window.ShouldClose ()

ProcessInput (window)

glClearColor (0.2, 0.3, 0.3, 1.0)
glClear (GL_COLOR_BUFFER_BIT)

glUseProgram (shaderProgram)
glBindVertexArray (VAO)
glDrawArrays (GL_TRIANGLES, 0, 3)

window.SwapBuffers ()
PollSystem ()

Wend

glDeleteVertexArrays (1, Varptr VAO)
glDeleteBuffers (1, Varptr VBO)

End
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on March 17, 2020, 02:31:22
Fourth sample:

2.2 Hello Triangle Indexed



' 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

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)

Local vertexShaderSource:Byte Ptr
Local vertexShaderString:String

vertexShaderString :+ "#version 330 core~n"
vertexShaderString :+ "layout (location = 0) in vec3 aPos;~n"
vertexShaderString :+ "void main()~n"
vertexShaderString :+ "{~n"
vertexShaderString :+ "   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);~n"
vertexShaderString :+ "}~n"

vertexShaderSource = vertexShaderString.ToCString ()

Local fragmentShaderSource:Byte Ptr
Local fragmentShaderString:String

fragmentShaderString :+ "#version 330 core~n"
fragmentShaderString :+ "out vec4 FragColor;~n"
fragmentShaderString :+ "void main()~n"
fragmentShaderString :+ "{~n"
fragmentShaderString :+ "   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);~n"
fragmentShaderString :+ "}~n"

fragmentShaderSource = fragmentShaderString.ToCString ()

Local vertexShader:Int = glCreateShader (GL_VERTEX_SHADER)

glShaderSource (vertexShader, 1, Varptr vertexShaderSource, Null)
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, Varptr fragmentShaderSource, Null)
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

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)

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)

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)

glBindBuffer (GL_ARRAY_BUFFER, 0)

glBindVertexArray (0)

While Not window.ShouldClose ()

ProcessInput (window)

glClearColor (0.2, 0.3, 0.3, 1.0)
glClear (GL_COLOR_BUFFER_BIT)

glUseProgram (shaderProgram)
glBindVertexArray (VAO)
glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0)

window.SwapBuffers ()
PollSystem ()

Wend

glDeleteVertexArrays (1, Varptr VAO)
glDeleteBuffers (1, Varptr VBO)
glDeleteBuffers (1, Varptr EBO)

End


Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on March 17, 2020, 02:53:49
One more for tonight!

Note: Uses MilliSecs in place of glfwGetTime as that's not in yet. Subtle differences possible against other code as MilliSecs is based off computer start time, while glfwGetTime is based off GLFW's own initialisation.

I'll probably do the remaining 3.x samples (https://github.com/JoeyDeVries/LearnOpenGL/tree/master/src/1.getting_started) and then call it quits, so I can get on and try to 'LearnOpenGL (https://learnopengl.com/)'!

Feel free to add these, Brucey, and thanks again! Awesome!  :D

3.1 Shaders Uniform



' 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"

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)

Local vertexShaderSource:Byte Ptr
Local vertexShaderString:String

vertexShaderString :+ "#version 330 core~n"
vertexShaderString :+ "layout (location = 0) in vec3 aPos;~n"
vertexShaderString :+ "void main()~n"
vertexShaderString :+ "{~n"
vertexShaderString :+ "   gl_Position = vec4(aPos, 1.0);~n"
vertexShaderString :+ "}~n"

vertexShaderSource = vertexShaderString.ToCString ()

Local fragmentShaderSource:Byte Ptr
Local fragmentShaderString:String

fragmentShaderString :+ "#version 330 core~n"
fragmentShaderString :+ "out vec4 FragColor;~n"
fragmentShaderString :+ "uniform vec4 ourColor;~n"
fragmentShaderString :+ "void main()~n"
fragmentShaderString :+ "{~n"
fragmentShaderString :+ "   FragColor = ourColor;~n"
fragmentShaderString :+ "}~n"

fragmentShaderSource = fragmentShaderString.ToCString ()

Local vertexShader:Int = glCreateShader (GL_VERTEX_SHADER)

glShaderSource (vertexShader, 1, Varptr vertexShaderSource, Null)
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, Varptr fragmentShaderSource, Null)
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

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)

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)

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)

glBindVertexArray (VAO)

While Not window.ShouldClose ()

ProcessInput (window)

glClearColor (0.2, 0.3, 0.3, 1.0)
glClear (GL_COLOR_BUFFER_BIT)

glUseProgram (shaderProgram)

Local timeValue:Float = MilliSecs ()
Local greenValue:Float = Sin (timeValue) / 2.0 + 0.5

Local vertexColorLocation:Int = glGetUniformLocation (shaderProgram, "ourColor")
glUniform4f (vertexColorLocation, 0.0, greenValue, 0.0, 1.0)

glDrawArrays (GL_TRIANGLES, 0, 3)

window.SwapBuffers ()
PollSystem ()

Wend

glDeleteVertexArrays (1, Varptr VAO)
glDeleteBuffers (1, Varptr VBO)

End


Title: Re: Any chance of a GLFW port?
Post by: Derron on March 17, 2020, 06:32:48
You know you could always have a

Global MillisecsOnStart:Int = Millisecs() 'or even just before your loop

and
Function MillisecsSinceStart:Int()
  Return Millisecs() - MillisecsOnStart
End Function



bye
Ron
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on March 17, 2020, 08:18:46
Good call! I was only pointing it out, though, on the off-chance someone got different results with 3rd-party code -- MilliSecs will do me fine!
Title: Re: Any chance of a GLFW port?
Post by: Brucey on March 18, 2020, 12:50:19
I've added GetTime and SetTime functions.

I've changed glShaderSource() to take a BlitzMax String (and dropped the length arg), rather than have the user need to remember to free memory etc. It just makes it easier to use in the BlitzMax environment.

I've added your examples. Thanks! :o)
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on March 19, 2020, 01:20:58
Cool... all working for me here! Thank you.
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on March 20, 2020, 00:49:46
Last one before the GLFW samples get into separation of shader files, reworking everything into classes, etc.

We finally get the interpolated RGB triangle!

3.2 Shaders Interpolation



' https://learnopengl.com/

SuperStrict

Framework GLFW.GLFWWindow

Import GLFW.GLFW
Import GLFW.GLFWOpenGL
Import GLFW.GLFWSystem

Import BRL.StandardIO

Local app_name:String = "Shaders Interpolation"

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)

Local vertexShaderSource:String

vertexShaderSource :+ "#version 330 core~n"
vertexShaderSource :+ "layout (location = 0) in vec3 aPos;~n"
vertexShaderSource :+ "layout (location = 1) in vec3 aColor;~n"
vertexShaderSource :+ "out vec3 ourColor;~n"
vertexShaderSource :+ "void main()~n"
vertexShaderSource :+ "{~n"
vertexShaderSource :+ "   gl_Position = vec4(aPos, 1.0);~n"
vertexShaderSource :+ "   ourColor = aColor;~n"
vertexShaderSource :+ "}~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 fragmentShaderSource:String

fragmentShaderSource :+ "#version 330 core~n"
fragmentShaderSource :+ "out vec4 FragColor;~n"
fragmentShaderSource :+ "in vec3 ourColor;~n"
fragmentShaderSource :+ "void main()~n"
fragmentShaderSource :+ "{~n"
fragmentShaderSource :+ "   FragColor = vec4(ourColor, 1.0f);~n"
fragmentShaderSource :+ "}~n"

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

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)

Local vertices:Float [] = [..
0.5, -0.5, 0.0, 1.0, 0.0, 0.0, ..
-0.5, -0.5, 0.0, 0.0, 1.0, 0.0, ..
0.0, 0.5, 0.0, 0.0, 0.0, 1.0]

Local VBO:UInt
Local VAO:UInt

glGenVertexArrays (1, Varptr VAO)
glGenBuffers (1, Varptr VBO)

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, 6 * Sizeof (0:Float), 0:Byte Ptr)
glEnableVertexAttribArray (0)

Local attribute_offset:Int = 3 * Sizeof (0:Float)

glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, 6 * Sizeof (0:Float), Byte Ptr (attribute_offset))
glEnableVertexAttribArray (1)

glUseProgram (shaderProgram)

While Not window.ShouldClose ()

ProcessInput (window)

glClearColor (0.2, 0.3, 0.3, 1.0)
glClear (GL_COLOR_BUFFER_BIT)

glBindVertexArray (VAO)
glDrawArrays (GL_TRIANGLES, 0, 3)

window.SwapBuffers ()
PollSystem ()

Wend

glDeleteVertexArrays (1, Varptr VAO)
glDeleteBuffers (1, Varptr VBO)

End


Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 17, 2020, 01:46:21
I like this glfw.mod. I have some codes in glfw3 which I like to convert to Blitzmax. I downloaded glfw.mod, but it seems bmk makemods -a glfw.mod is not the way. Can someone help me how to use glfw.mod?
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on April 18, 2020, 16:46:53
Are you using bmx-ng? If you place the mod folder at BlitzMaxNG\mod\glfw.mod it should just build by itself when you run one of the examples.

Note that you'll need the latest bmx-ng, from blitzmax.org (http://blitzmax.org) if you don't have it.
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 18, 2020, 18:10:17
I use NG because of its clear editor. It worked, thanks.
Title: Re: Any chance of a GLFW port?
Post by: Brucey on April 20, 2020, 15:50:47
Quote from: medi71 on April 17, 2020, 01:46:21
I like this glfw.mod. I have some codes in glfw3 which I like to convert to Blitzmax. I downloaded glfw.mod, but it seems bmk makemods -a glfw.mod is not the way. Can someone help me how to use glfw.mod?

FYI, the correct command would be bmk makemods -a glfw
Without the ".mod" part.
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 20, 2020, 16:35:41
The way DruggedBunny said, worked for me. Also, yes, .mod shouldn't be there. I could manually install on an old laptop the way you said, the old way. All good. 
I may have a question about reading shader source file. I am working on the 2.1.hello_triangle. I am trying to make it work with two external shader files. So far, reading seems good, but I get:" Shader program linking failed: "  without any explanation, I mean nothing in infolog. If I get nowhere, I will paste my code tonight. Thanks.
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 20, 2020, 20:06:32
This works for reading the shader file in the example:

Function readShaderFile:String(file:String)
Local shaderSource:String
Local lineFromFile:String
Local in:TStream = OpenStream(file)
While Not Eof(in)
lineFromFile = ReadLine(in)
shaderSource :+ lineFromFile + "~n"
Wend
CloseStream(in)
Return shaderSource
End Function
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 21, 2020, 22:07:39
Very nice to see a shader class in glfw mod folder. I haven't use it, good to have it. The Camera class helps me to see how BRL.Matrix is being used. About the Mesh class, is it to be used for a model loader?
I like this work, if the glfw mod project needs donation to be alive, I can begin with little, later more.
I think BlitzMax need a morale boost because of its previous disappointments. Good working modules and examples help a lot. It is sad to see it fade away and things like Python becomes international!!
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on April 22, 2020, 15:21:06
Hi all, wondering if a grown-up could have a look at this! I've been stuck for about a week, totally confused as to why I need vastly different settings to the tutorials I've been reading in order to render my cube!

I've tried the original C code and that works fine with the original settings, but in my version I have to use different camera position and far values.

No doubt I'm doing something stupid, but I want to try and get this working correctly before going any further...

This will show nothing at first -- enable the HACK const to use the 'working' settings.

Main difference is I'm not using a texture, but vertex colours instead... but I think I have my strides and offsets correct!

I've attached the runnable code, with copy below, if anyone's feeling helpful!  :D

shaders/fragment.glsl:

#version 330 core

out vec4 FragColor;
in vec3 ourColor;

void main()
{
   FragColor = vec4(ourColor, 1.0f);
}


shaders/vertex.glsl:


#version 330 core

layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;

uniform mat4 projection;
uniform mat4 camera;

out vec3 ourColor;

void main()
{
gl_Position = projection * camera * vec4(aPos, 1.0);
ourColor = aColor;
}



Main code:



SuperStrict

Framework GLFW.GLFWWindow

Import GLFW.GLFW
Import GLFW.GLFWMonitor
Import GLFW.GLFWOpenGL
Import GLFW.GLFWSystem

Import BRL.StandardIO
Import BRL.LinkedList

Import BRL.Matrix
Import BRL.Quaternion
Import BRL.Vector

' CAMERA STUFF

Local view_matrix:SMat4F
Local projection_matrix:SMat4F

' -----------------------------------------------------------------------------
Const HACK:Int = False ' H A C K    M E !
' -----------------------------------------------------------------------------

Local near:Float
Local far:Float
Local fov:Float
Local position:SVec3F
Local tri_scale:Float

If Not HACK ' Settings used in tutorials
near = 0.1
far = 10.0
fov = Radians (50.0)
position = New SVec3F (3.0, 3.0, 3.0)
tri_scale = 1.0
Else ' Settings that render something!
near = 0.1
far = 250.0
fov = Radians (50.0)
position = New SVec3F (3.5, 3.5, 3.5)
tri_scale = 0.5
EndIf

' https://learnopengl.com/Getting-started/Transformations
' https://www.tomdalling.com/blog/modern-opengl/03-matrices-depth-buffering-animation/
' https://github.com/tomdalling/opengl-series/blob/master/source/03_matrices/source/main.cpp

Local TMP_BasicCube:Float [] = [..
..
..
.. ' x y z
-tri_scale, tri_scale, tri_scale, 1.0, 0.0, 0.0, .. ' Near - Red
tri_scale, -tri_scale, tri_scale, 1.0, 0.0, 0.0, ..
-tri_scale, -tri_scale, tri_scale, 1.0, 0.0, 0.0, ..

-tri_scale, tri_scale, tri_scale, 0.5, 0.0, 0.0, ..
tri_scale, tri_scale, tri_scale, 0.5, 0.0, 0.0, ..
tri_scale, -tri_scale, tri_scale, 0.5, 0.0, 0.0, ..

tri_scale, tri_scale, -tri_scale, 0.0, 1.0, 0.0, .. ' Far - Green
-tri_scale, -tri_scale, -tri_scale, 0.0, 1.0, 0.0, ..
tri_scale, -tri_scale, -tri_scale, 0.0, 1.0, 0.0, ..

tri_scale, tri_scale, -tri_scale, 0.0, 0.5, 0.0, ..
-tri_scale, tri_scale, -tri_scale, 0.0, 0.5, 0.0, ..
-tri_scale, -tri_scale, -tri_scale, 0.0, 0.5, 0.0, ..

-tri_scale, tri_scale, -tri_scale, 0.0, 0.0, 1.0, .. ' Left - Blue
-tri_scale, -tri_scale, tri_scale, 0.0, 0.0, 1.0, ..
-tri_scale, -tri_scale, -tri_scale, 0.0, 0.0, 1.0, ..
'
-tri_scale, tri_scale, -tri_scale, 0.0, 0.0, 0.5, ..
-tri_scale, tri_scale, tri_scale, 0.0, 0.0, 0.5, ..
-tri_scale, -tri_scale, tri_scale, 0.0, 0.0, 0.5, ..

tri_scale, tri_scale, tri_scale, 1.0, 1.0, 0.0, .. ' Right - Yellow
tri_scale, -tri_scale, -tri_scale, 1.0, 1.0, 0.0, ..
tri_scale, -tri_scale, tri_scale, 1.0, 1.0, 0.0, ..
'
tri_scale, tri_scale, tri_scale, 0.5, 0.5, 0.0, ..
tri_scale, tri_scale, -tri_scale, 0.5, 0.5, 0.0, ..
tri_scale, -tri_scale, -tri_scale, 0.5, 0.5, 0.0, ..

-tri_scale, tri_scale, -tri_scale, 0.0, 1.0, 1.0, .. ' Top - Cyan
tri_scale, tri_scale, tri_scale, 0.0, 1.0, 1.0, ..
-tri_scale, tri_scale, tri_scale, 0.0, 1.0, 1.0, ..

-tri_scale, tri_scale, -tri_scale, 0.0, 0.5, 0.5, ..
tri_scale, tri_scale, -tri_scale, 0.0, 0.5, 0.5, ..
tri_scale, tri_scale, tri_scale, 0.0, 0.5, 0.5, ..

-tri_scale, -tri_scale, tri_scale, 1.0, 0.0, 1.0, .. ' Bottom - Magenta
tri_scale, -tri_scale, -tri_scale, 1.0, 0.0, 1.0, ..
-tri_scale, -tri_scale, -tri_scale, 1.0, 0.0, 1.0, ..

-tri_scale, -tri_scale, tri_scale, 0.5, 0.0, 0.5, ..
tri_scale, -tri_scale, tri_scale, 0.5, 0.0, 0.5, ..
tri_scale, -tri_scale, -tri_scale, 0.5, 0.0, 0.5]

' Demo window control...

Global AppWindow:TGLFWWindow ' Application window

Global _RetroGraphicsWidth:Int = 800 ' Display width
Global _RetroGraphicsHeight:Int = 600 ' Display height

'Retro3D (UInt (_RetroGraphicsWidth), UInt (_RetroGraphicsHeight))

'TGLFWWindow.Hint (GLFW_SAMPLES, msaa_level)
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 monitor:TGLFWMonitor = Null

'If full_screen Then monitor = TGLFWMonitor.GetPrimaryMonitor ()

AppWindow = New RetroGameWindow.Create (_RetroGraphicsWidth, _RetroGraphicsHeight, "Demo", monitor)

If Not AppWindow
Print "Failed to create GLFW window!"
End
EndIf

AppWindow.MakeContextCurrent ()

gladLoadGL (glfwGetProcAddress)

' DEPTH TESTING

glEnable (GL_DEPTH_TEST)
glDepthFunc (GL_LESS)

AppWindow.GetFrameBufferSize (_RetroGraphicsWidth, _RetroGraphicsHeight)

' SHADER PROGRAM

Local program:Int

' MESH

Local vertex_data:Float [] ' Mesh vertices (3D points)
Local vao:UInt, vbo:UInt ' VAO and VBO
Local triangle_count:Int ' Pre-calc number of triangles
Local vertex_count:Int ' Pre-calc number of vertices

' ASSIGN CUBE DATA TO MESH

vertex_data = TMP_BasicCube

triangle_count = (vertex_data.length / ATTRIBUTES_PER_VERTEX) / FLOATS_PER_ATTRIBUTE / VERTICES_PER_TRIANGLE
vertex_count = triangle_count * VERTICES_PER_TRIANGLE

Const FLOATS_PER_ATTRIBUTE:Int = 3 ' R, G, B and X, Y, Z each contain 3 floats... for now.
Const ATTRIBUTES_PER_VERTEX:Int = 2 ' Vertex data contains both RGB and XYZ attributes
Const VERTICES_PER_TRIANGLE:Int = 3 ' Just to avoid Magic Number in code!

Global RetroFloatSize:Int = Sizeof (0:Float) ' Avoiding reallocating a 0 for obtaining pointer each time!

Global VA_Offset:Int = FLOATS_PER_ATTRIBUTE * RetroFloatSize
Global VA_Stride:Int = VA_Offset * ATTRIBUTES_PER_VERTEX

' LOAD SHADERS

Local vertex_source_file:String = "vertex.glsl"
Local fragment_source_file:String = "fragment.glsl"

If Not FileType (vertex_source_file) Then vertex_source_file = "shaders/" + vertex_source_file
If Not FileType (fragment_source_file) Then fragment_source_file = "shaders/" + fragment_source_file

Local vertex_source:String = LoadString (vertex_source_file)
Local fragment_source:String = LoadString (fragment_source_file)

' ---------------------------------------------------------------------
' Create vertex shader object...
' ---------------------------------------------------------------------

Local vertex_shader:Int = glCreateShader (GL_VERTEX_SHADER)

' ---------------------------------------------------------------------
' Build and check vertex shader...
' ---------------------------------------------------------------------

glShaderSource (vertex_shader, 1, vertex_source)
glCompileShader (vertex_shader)

Local success:Int

glGetShaderiv (vertex_shader, GL_COMPILE_STATUS, Varptr success)

If Not success
'ShaderCompilationError (fragment_shader, fragment_source, vertex_source_file)
Print "Failed to compile shader"
End
EndIf

' ---------------------------------------------------------------------
' Create vertex shader object...
' ---------------------------------------------------------------------

Local fragment_shader:Int = glCreateShader (GL_FRAGMENT_SHADER)

' ---------------------------------------------------------------------
' Build and check fragment shader...
' ---------------------------------------------------------------------

glShaderSource (fragment_shader, 1, fragment_source)
glCompileShader (fragment_shader)

glGetShaderiv (fragment_shader, GL_COMPILE_STATUS, Varptr success)

If Not success
'ShaderCompilationError (fragment_shader, fragment_source, vertex_source_file)
Print "Failed to compile shader"
End
EndIf

' ---------------------------------------------------------------------
' Create shader program and attach compiled shader objects...
' ---------------------------------------------------------------------

program:Int = glCreateProgram ()

glAttachShader (program, vertex_shader)
glAttachShader (program, fragment_shader)

' ---------------------------------------------------------------------
' Link and check shader program...
' ---------------------------------------------------------------------

glLinkProgram (program)

glGetProgramiv (program, GL_LINK_STATUS, Varptr success)

If Not success
Print ""
Print "Shader program linking failed: " + glGetProgramInfoLog (program)
End
EndIf

' ---------------------------------------------------------------------
' Detach and delete shaders as no longer needed, now part of program...
' ---------------------------------------------------------------------

glDetachShader (program, vertex_shader)
glDetachShader (program, fragment_shader)

glDeleteShader (vertex_shader)
glDeleteShader (fragment_shader)

' ---------------------------------------------------------------------
' Needs to be active before uniforms can be used!
' ---------------------------------------------------------------------

glUseProgram (program)

' ---------------------------------------------------------------------
' VAO: Container for raw data...
' ---------------------------------------------------------------------

' Create and bind as current VAO...

glGenVertexArrays (1, Varptr vao) ' NB. 1 is NUMBER of buffers, not an ID!
glBindVertexArray (vao)

' ---------------------------------------------------------------------
' VBO: Raw data...
' ---------------------------------------------------------------------

' Create and bind as current VBO for currently-bound VAO...

glGenBuffers (1, Varptr vbo) ' NB. 1 is NUMBER of buffers, not an ID!
glBindBuffer (GL_ARRAY_BUFFER, vbo)

' Set buffer data for currently-bound VBO...

glBufferData (GL_ARRAY_BUFFER, SizeOf (vertex_data), vertex_data, GL_STATIC_DRAW)

glEnableVertexAttribArray (0)
glEnableVertexAttribArray (1)

' ---------------------------------------------------------------------
' Vertex attribute pointers operate on the currently-bound VAO...
' ---------------------------------------------------------------------

' Vertex attribute pointers below refer to those declared in vertex.glsl:

' layout (location = 0) in vec3 aPos;
' layout (location = 1) in vec3 aColor;

' Vertices data format description (aPos)...

glVertexAttribPointer (0, FLOATS_PER_ATTRIBUTE, GL_FLOAT, GL_FALSE, VA_Stride, Null)

' Colour data format description (aColor)...

glVertexAttribPointer (1, FLOATS_PER_ATTRIBUTE, GL_FLOAT, GL_FALSE, VA_Stride, Byte Ptr (VA_Offset))

glBindBuffer (GL_ARRAY_BUFFER, 0)
glBindVertexArray (0)

glDisableVertexAttribArray (1)
glDisableVertexAttribArray (0)

' WINDING (clockwise) AND CULLING

glFrontFace (GL_CW)
glEnable (GL_CULL_FACE)

' CAMERA

view_matrix = SMat4F.LookAt (position, New SVec3f (0.0, 0.0, 0.0), New SVec3f (0.0, 1.0, 0.0))
projection_matrix = SMat4F.Perspective (fov, _RetroGraphicsWidth, _RetroGraphicsHeight, near, far)

Local uni_cam:Int = glGetUniformLocation (program, "camera")
glUniformMatrix4fv (uni_cam, 1, False, Varptr view_matrix.a)

Local uni_prj:Int = glGetUniformLocation (program, "projection")
glUniformMatrix4fv (uni_prj, 1, False, Varptr projection_matrix.a)

' SET CLS COLOUR

glClearColor (0.1, 0.2, 0.75, 1.0)

' MAIN LOOP

While Not AppWindow.GetKey (GLFW_KEY_ESCAPE)

' CLEAR SCREEN/DEPTH BUFFER

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

glUseProgram (program)

' Using vertex attributes 0 and 1 from vertex.glsl...

glEnableVertexAttribArray (0)
glEnableVertexAttribArray (1)

glBindVertexArray (vao)

' Draw using currently-bound VAO...

glDrawArrays (GL_TRIANGLES, 0, vertex_count)

glBindVertexArray (0)

' Done using vertex attributes 0 and 1...

glDisableVertexAttribArray (1)
glDisableVertexAttribArray (0)

AppWindow.SwapBuffers ()

PollSystem ()

Wend

AppWindow.SetShouldClose (True)

glDeleteBuffers (1, Varptr vbo)
glDeleteVertexArrays (1, Varptr vao)

End

' WINDOW

Function Retro3D:TGLFWWindow (width:UInt, height:UInt, full_screen:Int = False, msaa_level:Int = 0)

TGLFWWindow.Hint (GLFW_SAMPLES, msaa_level)
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 monitor:TGLFWMonitor = Null

If full_screen Then monitor = TGLFWMonitor.GetPrimaryMonitor ()

AppWindow = New RetroGameWindow.Create (width, height, "Demo", monitor)

If Not AppWindow
Print "Failed to create GLFW window!"
End
EndIf

AppWindow.MakeContextCurrent ()

gladLoadGL (glfwGetProcAddress)

' DEPTH TESTING

glEnable (GL_DEPTH_TEST)
glDepthFunc (GL_LESS)

AppWindow.GetFrameBufferSize (_RetroGraphicsWidth, _RetroGraphicsHeight)

Return AppWindow

EndFunction

Type RetroGameWindow Extends TGLFWWindow

Method OnFrameBufferSize (width:Int, height:Int)
glViewport (0, 0, width, height)
AppWindow.GetFrameBufferSize (_RetroGraphicsWidth, _RetroGraphicsHeight)
EndMethod

EndType

Const RETRO_RAD_DIVIDER:Float = 180.0 / Pi
Const RETRO_DEG_DIVIDER:Float = Pi / 180.0

Function Degrees:Float (radians:Float)
Return radians * RETRO_RAD_DIVIDER
EndFunction

Function Radians:Float (degrees:Float)
Return degrees * RETRO_DEG_DIVIDER
EndFunction
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 22, 2020, 16:48:07
Are you working on one of the examples from learnopengl.com? Which one?
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on April 22, 2020, 18:00:26
I thought I'd grasped enough to try something for myself, so it's a mix of the tutorials noted in my source comments, both of which use similar fov/projection settings and vertices:

https://learnopengl.com/Getting-started/Transformations (https://learnopengl.com/Getting-started/Transformations) [Scroll halfway down to "In Practice".]

https://www.tomdalling.com/blog/modern-opengl/03-matrices-depth-buffering-animation/ (https://www.tomdalling.com/blog/modern-opengl/03-matrices-depth-buffering-animation/) [See the related code below.]
https://github.com/tomdalling/opengl-series/blob/master/source/03_matrices/source/main.cpp (https://github.com/tomdalling/opengl-series/blob/master/source/03_matrices/source/main.cpp)
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 22, 2020, 18:17:24
I just saw the links in your codes too, sorry for asking again.

glfw mod is new to me, and I am not expert in OpenGL. I am learning just like you. So, your problems help me too. 

About fov degree to radian conversion, it seems to me that BlitzMax's matrix uses degree, because I see it uses Tan, which in BlitzMax, requires degree. I tried degree with your code, it didn't help. I am struggling with my own example too, I will work on yours after a while, if I see something, I will let you know. But, don't count on it.


Function Perspective:SMat4F(fov:Float, w:Float, h:Float, n:Float, f:Float)
Local ft:Float = 1.0 / Tan(fov * 0.5)
Local nf:Float = 1.0 / (n - f)
Return New SMat4F(ft, 0, 0, 0, ..
0, ft * w / h, 0, 0, ..
0, 0, (f + n) * nf, -1, ..
0, 0, (2.0 * f * n) * nf, 0)
End Function
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on April 23, 2020, 00:50:06
Interesting, I wondered if there was something possibly wrong in the module itself, but of course can't really tell. I did try degrees, though not with the insight you had! Just in case 'our' version used degrees instead of radians.

Thanks for having a look, though, really appreciate it.

I think I'll have to convert the C source to really tell, though there's more to it than there appears at first, so was hoping to avoid that!
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 23, 2020, 01:07:10
Take a look at my code too, it doesn't show the cube, just like yours. The C++ version works. This is the first example of this book:
https://www.amazon.com/COMPUTER-GRAPHICS-PROGRAMMING-OPENGL-C-ebook/dp/B07MHD8TKB/ref=sr_1_4?dchild=1&keywords=opengl+programming+c%2B%2B&qid=1587599826&sr=8-4

I think there is something wrong with sending the uniform matrices to shader program. Either our way is bad, or something wrong with the module.


SuperStrict

Framework GLFW.GLFWWindow

Import GLFW.GLFW
Import GLFW.GLFWOpenGL
Import GLFW.GLFWSystem

Import BRL.StandardIO

Import BRL.Matrix

'------------------------- gl & window setup --------------
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
TGLFWWindow.Hint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE)
?

Local  width:Int = 800, height:Int = 600
Local app_name:String = "Medi Cube"

Local window:TGLFWWindow = New TGameWindow.Create (width, height, app_name)

If Not window
Print "Failed to create GLFW window!"
End
EndIf

window.MakeContextCurrent ()

gladLoadGL (glfwGetProcAddress)

'-----------------------------------------------------
Local numVAOs:Int=1
Local numVBOs:Int=2

Local cameraX:Float= 0, cameraY:Float=0, cameraZ:Float=8
Local cubeLocX:Float = 0.0, cubeLocY:Float = 0.0, cubeLocZ:Float = 0.0
Local renderProgram:Int
Local vbo:UInt[numVBOs]
Local vao:UInt[numVAOs]

Local mvLoc:UInt, projLoc:UInt

Local aspect:Float
Local pMat:SMat4F, vMat:SMat4F, mMat:SMat4F, mvMat:SMat4F

'--------------------------- setup vertecies  -------------------
renderProgram = CreateShaderProgram("vshader.glsl", "fshader.glsl")
Local vertexPositions:Float[] = [..
-1.0,  1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, ..
1.0, -1.0, -1.0, 1.0,  1.0, -1.0, -1.0,  1.0, -1.0, ..
1.0, -1.0, -1.0, 1.0, -1.0,  1.0, 1.0,  1.0, -1.0, ..
1.0, -1.0,  1.0, 1.0,  1.0,  1.0, 1.0,  1.0, -1.0, ..
1.0, -1.0,  1.0, -1.0, -1.0,  1.0, 1.0,  1.0,  1.0, ..
-1.0, -1.0,  1.0, -1.0,  1.0,  1.0, 1.0,  1.0,  1.0, ..
-1.0, -1.0,  1.0, -1.0, -1.0, -1.0, -1.0,  1.0,  1.0, ..
-1.0, -1.0, -1.0, -1.0,  1.0, -1.0, -1.0,  1.0,  1.0, ..
-1.0, -1.0,  1.0,  1.0, -1.0,  1.0,  1.0, -1.0, -1.0, ..
1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0,  1.0, ..
-1.0,  1.0, -1.0, 1.0,  1.0, -1.0, 1.0,  1.0,  1.0, ..
1.0,  1.0,  1.0, -1.0,  1.0,  1.0, -1.0,  1.0, -1.0]

glGenVertexArrays (1, Varptr vao)
glBindVertexArray (vao[0])
glGenBuffers (numVBOs, Varptr vbo)

glBindBuffer (GL_ARRAY_BUFFER, vbo[0])
glBufferData (GL_ARRAY_BUFFER, SizeOf (vertexPositions ), vertexPositions, GL_STATIC_DRAW)


' -------------- ------------- main loop -----------------------------------
While Not window.ShouldClose ()
ProcessInput (window)
glClearColor (0.2, 0.3, 0.3, 1.0)
glClear (GL_COLOR_BUFFER_BIT)

glUseProgram (renderProgram)

mvLoc = glGetUniformLocation(renderProgram, "mv_matrix")
projLoc = glGetUniformLocation(renderProgram, "proj_matrix")

pMat = SMat4F.Perspective(60, width , height, 0.1, 1000.0)

vMat = SMat4F.Translation(New SVec3F(-cameraX, -cameraY, -cameraZ))
mMat = SMat4F.Translation(New SVec3F(cubeLocX, cubeLocY, cubeLocZ))
mvMat = vMat * mMat; 'model-view

glUniformMatrix4fv(mvLoc, 1, GL_FALSE,  Varptr mvMat.a)
glUniformMatrix4fv(projLoc, 1, GL_FALSE, Varptr pMat.a)

glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glVertexAttribPointer(0, 3, GL_FLOAT, False, 0, 0);
glEnableVertexAttribArray(0);

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);

glDrawArrays(GL_TRIANGLES, 0, 36);

window.SwapBuffers ()
PollSystem ()
Wend

glDeleteVertexArrays (1, Varptr vao)
glDeleteBuffers (1, Varptr vbo)

End

'------------------------- end --------------------------------

'------------ function read shader file  ----------------------
Function readShaderFile:String(file:String)
Local shaderSource:String
Local lineFromFile:String
Local in:TStream = OpenStream(file)
While Not Eof(in)
lineFromFile = ReadLine(in)
shaderSource :+ lineFromFile + "~n"
Wend
CloseStream(in)
Return shaderSource
End Function
'------------- function create shader program ------------------
Function CreateShaderProgram:Int(vsFile:String, frFile:String)

' read and compile vertex shader
Local infoLog:String
Local success:Int
Local vertexShaderSource:String
vertexShaderSource = readShaderFile(vsFile)
Local vertexShader:Int = glCreateShader (GL_VERTEX_SHADER)
glShaderSource (vertexShader, 1, vertexShaderSource)
glCompileShader (vertexShader)
glGetShaderiv (vertexShader, GL_COMPILE_STATUS, Varptr success)
If Not success
infoLog = glGetShaderInfoLog (vertexShader )
Print "Vertex shader compilation failed: " + String.FromCString (infoLog)
EndIf

' read and compile fragment shader
Local fragmentShaderSource:String
fragmentShaderSource = readShaderFile("fshader.glsl")
Local fragmentShader:Int = glCreateShader (GL_FRAGMENT_SHADER)
glShaderSource (fragmentShader, 1, fragmentShaderSource)
glCompileShader (fragmentShader)
glGetShaderiv (fragmentShader, GL_COMPILE_STATUS, Varptr success)
If Not success
infoLog = glGetShaderInfoLog (fragmentShader)
Print "Fragment shader compilation failed: " + String.FromCString (infoLog)
EndIf

' link, attach and check
Local shaderProgram:Int = glCreateProgram ()
glAttachShader (shaderProgram, vertexShader)
glAttachShader (shaderProgram, fragmentShader)
glLinkProgram (shaderProgram)
glGetProgramiv (shaderProgram, GL_LINK_STATUS, Varptr success)
If Not success
infoLog = glGetProgramInfoLog (shaderProgram)
Print "Shader program linking failed: " + String.FromCString (infoLog)
EndIf

' have the program, don't need anymore
glDeleteShader (vertexShader)
glDeleteShader (fragmentShader)

Return shaderProgram
End Function



vertex shader:


#version 330

layout (location=0) in vec3 position;

uniform mat4 mv_matrix;
uniform mat4 proj_matrix;

void main(void)
{
gl_Position = proj_matrix * mv_matrix * vec4(position,1.0);
}


fragment shader:

#version 330

out vec4 color;

void main(void)
{ color = vec4(1.0, 0.0, 1.0, 1.0);
}


Simple stuff, but doesn't work!  :(
Here I say it doesn't but it does, read later posts.
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 23, 2020, 02:14:29
DruggedBunny,
I studied the c++ code that you are trying to convert. I think that code is too complex to be a good learning example for beginners. For example, I don't suggest using complex shader class to begin with. That code uses its own shader class. I wish you continue steps in learnopengl.com so that I can leave the book that I am reading and stick to your examples.
What I am doing is to learn how glfw.mod can handle OpenGL's various tasks so that I can confidently spend time on converting a simple space simulator code that I wrote few years ago in C++/GLFW to BlitzMax. I just began to converts code in that book because I realized that the glfw.mod examples are not enough.
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on April 23, 2020, 02:27:27
I'm probably not going to convert much more myself -- my plan was to get just enough working/understood to make my own really basic 3D engine (basically, flat-shading and pixel shaders!), so my own code is admittedly becoming a little too complex as it's been arranged into a load of project files. I've had to cut and paste it down into a single file for this example... obviously being a little too ambitious, ha ha.

I'm glad you've run into the same problem, though, as it suggests I may still be on the right track and that the library is at fault! I'd like to get this basic stuff working and understood before going any further.

I've raised an issue on GitHub so Brucey can try our examples... and hopefully not point out why we're both wrong!

https://github.com/bmx-ng/glfw.mod/issues/1
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 23, 2020, 15:56:59
My example above (from the book) works, but the cube is not visible. To make it visible, just comment out glEnable(GL_DEPTH_TEST) in the bottom of the code. To see it better, bring down the cube position by 2: cubeLocY:Float = -2.0.

Change shader to see it in color:
Vertex shader:

#version 330
layout (location=0) in vec3 position;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
out vec4 varyingColor;
void main(void)
{
gl_Position = proj_matrix * mv_matrix * vec4(position,1.0);
varyingColor = vec4(position,1.0) * .5 + vec4(.5,.5,.5,.5);
}

fragment shader:

#version 330
out vec4 color;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
in vec4 varyingColor;
void main(void)
{
//color = vec4(1.0, 0.0, 1.0, 1.0);
color = varyingColor;
}


Notes:
1 - Uniforms in fragment shader are not necessary for this program.
2 - The depth test shouldn't remove the cube. In C++ version it doesn't. With the mod, it seems front face is removed. This could be my mistake somewhere too. The good thing is that I can go further now.
3 - In the above shader program, simple position vertices are colored as they come in one after the other. Uniforms are used for transforming the spaces.
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on April 23, 2020, 17:28:31
I think your problem may be this:

   glClear (GL_COLOR_BUFFER_BIT)

You also need to clear the depth buffer, I believe, as this is something I read about while trying to figure it out.

I'll have another look at your code, too!
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on April 23, 2020, 17:33:31
Yeah, changing to glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) allows your code to work! So it looks like I'm at fault...
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 23, 2020, 18:39:26
Thanks DruggedBunny,
Previous examples (from the book) were good enough for me to continue. Now I have a new example.
In this example, cube moves around and rotates. Shaders are the same.
A model matrix is built out of two changing matrices, one from translation and another from rotation. Finally, the model-view matrix is updated based on those two.
I removed perspective and view matrix out of the main loop because they don't change in this example.

SuperStrict

Framework GLFW.GLFWWindow

Import GLFW.GLFW
Import GLFW.GLFWOpenGL
Import GLFW.GLFWSystem

Import BRL.StandardIO

Import BRL.Matrix

'------------------------- gl & window setup --------------
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, 4)
TGLFWWindow.Hint (GLFW_CONTEXT_VERSION_MINOR, 3)
TGLFWWindow.Hint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)

?MacOS
TGLFWWindow.Hint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE)
?

Local  width:Int = 800, height:Int = 600
Local app_name:String = "Medi Cube"

Local window:TGLFWWindow = New TGameWindow.Create (width, height, app_name)

If Not window
Print "Failed to create GLFW window!"
End
EndIf

window.MakeContextCurrent ()

gladLoadGL (glfwGetProcAddress)

'-----------------------------------------------------
Local numVAOs:Int=1
Local numVBOs:Int=2

Local cameraX:Float= 0, cameraY:Float=0, cameraZ:Float=8
Local cubeLocX:Float = 0.0, cubeLocY:Float = -2.0, cubeLocZ:Float = 0.0
Local renderProgram:Int
Local vbo:UInt[numVBOs]
Local vao:UInt[numVAOs]

Local mvLoc:UInt, projLoc:UInt

Local aspect:Float
Local pMat:SMat4F, vMat:SMat4F, mMat:SMat4F, mvMat:SMat4F, tMat:SMat4F, rMat:SMat4F

'--------------------------- setup vertecies  -------------------
renderProgram = CreateShaderProgram("vshader.glsl", "fshader.glsl")

Local vertexPositions:Float[] = [..
-1.0,  1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, ..
1.0, -1.0, -1.0, 1.0,  1.0, -1.0, -1.0,  1.0, -1.0, ..
1.0, -1.0, -1.0, 1.0, -1.0,  1.0, 1.0,  1.0, -1.0, ..
1.0, -1.0,  1.0, 1.0,  1.0,  1.0, 1.0,  1.0, -1.0, ..
1.0, -1.0,  1.0, -1.0, -1.0,  1.0, 1.0,  1.0,  1.0, ..
-1.0, -1.0,  1.0, -1.0,  1.0,  1.0, 1.0,  1.0,  1.0, ..
-1.0, -1.0,  1.0, -1.0, -1.0, -1.0, -1.0,  1.0,  1.0, ..
-1.0, -1.0, -1.0, -1.0,  1.0, -1.0, -1.0,  1.0,  1.0, ..
-1.0, -1.0,  1.0,  1.0, -1.0,  1.0,  1.0, -1.0, -1.0, ..
1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0,  1.0, ..
-1.0,  1.0, -1.0, 1.0,  1.0, -1.0, 1.0,  1.0,  1.0, ..
1.0,  1.0,  1.0, -1.0,  1.0,  1.0, -1.0,  1.0, -1.0]

glGenVertexArrays (1, Varptr vao)
glBindVertexArray (vao[0])
glGenBuffers (numVBOs, Varptr vbo)

glBindBuffer (GL_ARRAY_BUFFER, vbo[0])
glBufferData (GL_ARRAY_BUFFER, SizeOf (vertexPositions ), vertexPositions, GL_STATIC_DRAW)

' perspective 3d
projLoc = glGetUniformLocation(renderProgram, "proj_matrix")
pMat = SMat4F.Perspective(60, width , height, 0.1, 1000.0)

'cam
mvLoc = glGetUniformLocation(renderProgram, "mv_matrix")
vMat = SMat4F.Translation(New SVec3F(-cameraX, -cameraY, -cameraZ))

' -------------- ------------- main loop -----------------------------------
While Not window.ShouldClose ()

ProcessInput (window)
glClearColor (0.2, 0.3, 0.3, 1.0)
glClear(GL_DEPTH_BUFFER_BIT)
glClear (GL_COLOR_BUFFER_BIT)

glUseProgram (renderProgram)

Local xt:Double = Sin(56*GetTime()) *2.0
Local yt:Double = Cos(23*GetTime())*2.0
Local zt:Double = Sin(76*GetTime())*2.0
Local v:SVec3F = New SVec3F(Float(xt),Float(yt),Float(zt))
tMat=SMat4F.Translation(v)

rMat = SMat4F.Rotation(New SVec3F(0, 1, 0),50*Float(GetTime()))
rMat = SMat4F.Rotation(New SVec3F(1, 0, 1),29*Float(GetTime()))
rMat = SMat4F.Rotation(New SVec3F(0, 0, 1),75*Float(GetTime()))

mMat = tMat*rMat
mvMat = vMat * mMat 'model-view

glUniformMatrix4fv(mvLoc, 1, GL_FALSE,  Varptr mvMat.a)
glUniformMatrix4fv(projLoc, 1, GL_FALSE, Varptr pMat.a)

glBindBuffer(GL_ARRAY_BUFFER, vbo[0])
glVertexAttribPointer(0, 3, GL_FLOAT, False, 0, 0);
glEnableVertexAttribArray(0)

'glEnable(GL_DEPTH_TEST)
'glDepthFunc(GL_LEQUAL)

glDrawArrays(GL_TRIANGLES, 0, 36)

window.SwapBuffers ()
PollSystem ()
Wend

glDeleteVertexArrays (1, Varptr vao)
glDeleteBuffers (1, Varptr vbo)

End

'------------------------- end --------------------------------

'------------ function read shader file  ----------------------
Function readShaderFile:String(file:String)
Local shaderSource:String
Local lineFromFile:String
Local in:TStream = OpenStream(file)
While Not Eof(in)
lineFromFile = ReadLine(in)
shaderSource :+ lineFromFile + "~n"
Wend
CloseStream(in)
Return shaderSource
End Function
'------------- function create shader program ------------------
Function CreateShaderProgram:Int(vsFile:String, frFile:String)

' read and compile vertex shader
Local infoLog:String
Local success:Int
Local vertexShaderSource:String
vertexShaderSource = readShaderFile(vsFile)
Local vertexShader:Int = glCreateShader (GL_VERTEX_SHADER)
glShaderSource (vertexShader, 1, vertexShaderSource)
glCompileShader (vertexShader)
glGetShaderiv (vertexShader, GL_COMPILE_STATUS, Varptr success)
If Not success
infoLog = glGetShaderInfoLog (vertexShader )
Print "Vertex shader compilation failed: " + String.FromCString (infoLog)
EndIf

' read and compile fragment shader
Local fragmentShaderSource:String
fragmentShaderSource = readShaderFile("fshader.glsl")
Local fragmentShader:Int = glCreateShader (GL_FRAGMENT_SHADER)
glShaderSource (fragmentShader, 1, fragmentShaderSource)
glCompileShader (fragmentShader)
glGetShaderiv (fragmentShader, GL_COMPILE_STATUS, Varptr success)
If Not success
infoLog = glGetShaderInfoLog (fragmentShader)
Print "Fragment shader compilation failed: " + String.FromCString (infoLog)
EndIf

' link, attach and check
Local shaderProgram:Int = glCreateProgram ()
glAttachShader (shaderProgram, vertexShader)
glAttachShader (shaderProgram, fragmentShader)
glLinkProgram (shaderProgram)
glGetProgramiv (shaderProgram, GL_LINK_STATUS, Varptr success)
If Not success
infoLog = glGetProgramInfoLog (shaderProgram)
Print "Shader program linking failed: " + String.FromCString (infoLog)
EndIf

' have the program, don't need anymore
glDeleteShader (vertexShader)
glDeleteShader (fragmentShader)

Return shaderProgram
End Function

Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 23, 2020, 19:04:45
Ok, the cube will be drawn correctly, if we add these three depth test stuff:

glEnable(GL_DEPTH_TEST)
glDepthFunc(GL_LEQUAL)
glFrontFace(GL_CW)

So, all the previous code must be modified.

The second one is not necessary for now.
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 23, 2020, 19:16:00
DruggedBunny, you were right, I was just confused. Now, I can work on many more examples.  ;D
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on April 23, 2020, 21:28:49
Hmm, I'm still confused -- I notice you're not using SMat4F.LookAt, and if I replace your line:

vMat = SMat4F.Translation(New SVec3F(-cameraX, -cameraY, -cameraZ))

... with what I think is the same offset:

vMat = SMat4F.LookAt (New SVec3f (cameraX, cameraY, cameraZ), New SVec3f (0.0, 0.0, 0.0), New SVec3f (0.0, 1.0, 0.0))

... it still doesn't work. Is LookAt broken after all?
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on April 23, 2020, 21:58:16
Hmm, trying to use the original tutorials' camera position of 3, 3, 3 in your code also fails, in that the cube doesn't appear in the scene unless I use your camera's z=8 position... something seems to be wrong still.
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on April 23, 2020, 22:42:53
OK, not convinced I'm right, but I tried adapting SMat4F.LookAt to be somewhat similar to GLM's, and with a bit of trial and error it gives close results using the 3, 3, 3 position. Not sure why it doesn't quite match the OS X version, but the viewpoint looks the same.

Also, it seems SMat4F.Perspective does use degrees for the first parameter, as I see you've done!

Here's my experimental SMat4F.LookAt, with references:


' https://github.com/g-truc/glm/blob/master/glm/ext/matrix_transform.inl
' Adapted from lookAtRH
' https://github.com/g-truc/glm/blob/master/copying.txt
' "GLM is licensed under The Happy Bunny License or MIT License"

Function LookAt:SMat4F(eye:SVec3F, center:SVec3F, up:SVec3F)

Local f:SVec3F = (center - eye).Normal ()
Local s:SVec3F = f.Cross (up).Normal ()
Local u:SVec3F = s.Cross (f)

Return New SMat4F (s.x, u.x, -f.x, 0, s.y, u.y, -f.y, 0, s.z, u.z, -f.z, 0, -s.Dot (eye), -u.Dot (eye), f.Dot (eye), 1)
End Function


Not saying it's right (notice slightly more zoomed/filling window), but it looks more like it's meant to! The faces are in the right positions too.

Code and screenshot showing my 3, 3, 3-positioned cube, versus tutorial version, attached... remember to change matrix.mod -> LookAt:SMat4F !
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 23, 2020, 22:46:21
3,3,3 moves the camera space out of where the cube is. Try .7, .2, 5. You will see that part of the cube is visible.
About the LookAt, it works.
Here I have modified my example to draw the cube using LookAt. Shaders are as before.

SuperStrict

Framework GLFW.GLFWWindow

Import GLFW.GLFW
Import GLFW.GLFWOpenGL
Import GLFW.GLFWSystem

Import BRL.StandardIO

Import BRL.Matrix

'------------------------- gl & window setup --------------
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, 4)
TGLFWWindow.Hint (GLFW_CONTEXT_VERSION_MINOR, 3)
TGLFWWindow.Hint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)

?MacOS
TGLFWWindow.Hint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE)
?

Local  width:Int = 800, height:Int = 600
Local app_name:String = "Medi Cube"

Local window:TGLFWWindow = New TGameWindow.Create (width, height, app_name)

If Not window
Print "Failed to create GLFW window!"
End
EndIf

window.MakeContextCurrent ()

gladLoadGL (glfwGetProcAddress)

'-----------------------------------------------------
Local numVAOs:Int=1
Local numVBOs:Int=2

Local cameraX:Float= 1.5, cameraY:Float=1.5, cameraZ:Float=1.5
Local cubeLocX:Float = 0.0, cubeLocY:Float = 0.0, cubeLocZ:Float = 0.0
Local renderProgram:Int
Local vbo:UInt[numVBOs]
Local vao:UInt[numVAOs]

Local mvLoc:UInt, projLoc:UInt

Local aspect:Float
Local pMat:SMat4F, vMat:SMat4F, mMat:SMat4F, mvMat:SMat4F, rMat:SMat4F, tMat:SMat4F

'--------------------------- setup vertecies  -------------------
renderProgram = CreateShaderProgram("vshader.glsl", "fshader.glsl")

Local vertexPositions:Float[] = [..
-1.0,  1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, ..
1.0, -1.0, -1.0, 1.0,  1.0, -1.0, -1.0,  1.0, -1.0, ..
1.0, -1.0, -1.0, 1.0, -1.0,  1.0, 1.0,  1.0, -1.0, ..
1.0, -1.0,  1.0, 1.0,  1.0,  1.0, 1.0,  1.0, -1.0, ..
1.0, -1.0,  1.0, -1.0, -1.0,  1.0, 1.0,  1.0,  1.0, ..
-1.0, -1.0,  1.0, -1.0,  1.0,  1.0, 1.0,  1.0,  1.0, ..
-1.0, -1.0,  1.0, -1.0, -1.0, -1.0, -1.0,  1.0,  1.0, ..
-1.0, -1.0, -1.0, -1.0,  1.0, -1.0, -1.0,  1.0,  1.0, ..
-1.0, -1.0,  1.0,  1.0, -1.0,  1.0,  1.0, -1.0, -1.0, ..
1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0,  1.0, ..
-1.0,  1.0, -1.0, 1.0,  1.0, -1.0, 1.0,  1.0,  1.0, ..
1.0,  1.0,  1.0, -1.0,  1.0,  1.0, -1.0,  1.0, -1.0]

glGenVertexArrays (1, Varptr vao)
glBindVertexArray (vao[0])
glGenBuffers (numVBOs, Varptr vbo)

glBindBuffer (GL_ARRAY_BUFFER, vbo[0])
glBufferData (GL_ARRAY_BUFFER, SizeOf (vertexPositions ), vertexPositions, GL_STATIC_DRAW)

mvLoc = glGetUniformLocation(renderProgram, "mv_matrix")
projLoc = glGetUniformLocation(renderProgram, "proj_matrix")

' projection
pMat = SMat4F.Perspective(45, width , height, 0.1, 1000.0)

'view
vMat = SMat4F.LookAt(New SVec3F(cameraX, cameraY, cameraZ), ..
New SVec3F(0, 0, 0), ..
New SVec3F(0, 1, 0))
' -------------- ------------- main loop -----------------------------------
While Not window.ShouldClose ()
ProcessInput (window)
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT)
glClearColor (0.2, 0.4, 0.6, 1.0)

glUseProgram (renderProgram)

'model
Global rot:Float
rot:+1.5
If rot>360 Then rot = 0
tMat = SMat4F.Translation(New SVec3F(cubeLocX, cubeLocY, cubeLocZ)) 'no move, all zero
rMat = SMat4F.Rotation(New SVec3F(0, 1, 0),rot)

mMat = tMat*rMat
mvMat = vMat * mMat 'model-view

glUniformMatrix4fv(mvLoc, 1, GL_FALSE,  Varptr mvMat.a)
glUniformMatrix4fv(projLoc, 1, GL_FALSE, Varptr pMat.a)

glBindBuffer(GL_ARRAY_BUFFER, vbo[0])
glVertexAttribPointer(0, 3, GL_FLOAT, False, 0, 0);
glEnableVertexAttribArray(0)

glEnable(GL_DEPTH_TEST)
glDepthFunc(GL_LEQUAL)
glFrontFace(GL_CW)

glDrawArrays(GL_TRIANGLES, 0, 36)

window.SwapBuffers ()
PollSystem ()
Wend

glDeleteVertexArrays (1, Varptr vao)
glDeleteBuffers (1, Varptr vbo)

End

'------------------------- end --------------------------------

'------------ function read shader file  ----------------------
Function readShaderFile:String(file:String)
Local shaderSource:String
Local lineFromFile:String
Local in:TStream = OpenStream(file)
While Not Eof(in)
lineFromFile = ReadLine(in)
shaderSource :+ lineFromFile + "~n"
Wend
CloseStream(in)
Return shaderSource
End Function
'------------- function create shader program ------------------
Function CreateShaderProgram:Int(vsFile:String, frFile:String)

' read and compile vertex shader
Local infoLog:String
Local success:Int
Local vertexShaderSource:String
vertexShaderSource = readShaderFile(vsFile)
Local vertexShader:Int = glCreateShader (GL_VERTEX_SHADER)
glShaderSource (vertexShader, 1, vertexShaderSource)
glCompileShader (vertexShader)
glGetShaderiv (vertexShader, GL_COMPILE_STATUS, Varptr success)
If Not success
infoLog = glGetShaderInfoLog (vertexShader )
Print "Vertex shader compilation failed: " + String.FromCString (infoLog)
EndIf

' read and compile fragment shader
Local fragmentShaderSource:String
fragmentShaderSource = readShaderFile("fshader.glsl")
Local fragmentShader:Int = glCreateShader (GL_FRAGMENT_SHADER)
glShaderSource (fragmentShader, 1, fragmentShaderSource)
glCompileShader (fragmentShader)
glGetShaderiv (fragmentShader, GL_COMPILE_STATUS, Varptr success)
If Not success
infoLog = glGetShaderInfoLog (fragmentShader)
Print "Fragment shader compilation failed: " + String.FromCString (infoLog)
EndIf

' link, attach and check
Local shaderProgram:Int = glCreateProgram ()
glAttachShader (shaderProgram, vertexShader)
glAttachShader (shaderProgram, fragmentShader)
glLinkProgram (shaderProgram)
glGetProgramiv (shaderProgram, GL_LINK_STATUS, Varptr success)
If Not success
infoLog = glGetProgramInfoLog (shaderProgram)
Print "Shader program linking failed: " + String.FromCString (infoLog)
EndIf

' have the program, don't need anymore
glDeleteShader (vertexShader)
glDeleteShader (fragmentShader)

Return shaderProgram
End Function

Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on April 23, 2020, 22:52:39
OK, that's cool (and thanks for all your code!)... but what I don't get is why 3, 3, 3 actually works in the original C versions, yet not here.
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on April 23, 2020, 22:56:16
Ha ha, now I'm even more confused! I was still using my LookAt when I ran yours. When I change back to the original, I get this, using:

Local cameraX:Float= .7, cameraY:Float=.2, cameraZ:Float=5
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on April 23, 2020, 23:01:16
I notice you're using a large far value too, where the original near=0.1, far=10 doesn't seem to work here.

It surely ought to be possible to get the same/similar results using the values from the tutorials' C code.
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 24, 2020, 19:22:09
Which image loader to use for texturing and how?
I see blitzmax has stbimageloader. How to use it in this case:


unsigned char *data = stbi_load("container.jpg", &width, &height, &nrChannels, 0);
if (data)
{
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
    std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);

Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on April 25, 2020, 08:58:24
Brucey has added a few examples in recent days:

https://github.com/bmx-ng/glfw.mod/blob/master/examples/learnopengl/1.getting_started/4.1.textures.bmx

He's using LoadPixmap here.
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 25, 2020, 14:30:48
I thought that pixmap loader's type won't work so I didn't even try. Vow, nice and easy!
I will post my examples of a quad (made of two triangles) and a pyramid (from the book) today.
Thanks to Brucey and DruggedBunny.
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 25, 2020, 14:33:35
 BlitzMax rocks  ;D
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on April 25, 2020, 15:27:53
It definitely does!

I've opened a new issue for what I think is still a problem -- I converted the original C code and the results are definitely different.

https://github.com/bmx-ng/glfw.mod/issues/2

You might want to be aware, just in case a fix* causes all your stuff to change!

* If one is required and I'm not just barking up the wrong tree...
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 25, 2020, 19:33:21
I am working on your program. It may take long because I will reduce your program then add your other code gradually.
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 25, 2020, 23:18:48
I changed some area of your code and at least I could make it show something. The cube shows being shattered! I think something wrong with our or my handling of incidences or vertices.
I couldn't make LookAt() to show something so I used translation() to just move camera back to the right.



SuperStrict

Framework GLFW.GLFWWindow

Import GLFW.GLFW
Import GLFW.GLFWMonitor
Import GLFW.GLFWOpenGL
Import GLFW.GLFWSystem

Import BRL.StandardIO
Import BRL.LinkedList

Import BRL.Matrix
Import BRL.Quaternion
Import BRL.Vector

Import BRL.JpgLoader

'-----------------------------
Global AppWindow:TGLFWWindow
Global gVAO:Int = 0
Global gVBO:Int = 0
Global gDegreesRotated:Float = 0.0
Global Program:Int
Global Texture:UInt
Global vertex_shader:Int
Global fragment_shader:Int


'Const FLOATS_PER_ATTRIBUTE:Int = 5 ' R, G, B and X, Y, Z each contain 3 floats... for now.
'Const ATTRIBUTES_PER_VERTEX:Int = 1 ' Vertex data contains both RGB and XYZ attributes
'Const VERTICES_PER_TRIANGLE:Int = 3 ' Just to avoid Magic Number in code!

Global RetroFloatSize:Int = SizeOf (0:Float) ' Avoiding reallocating a 0 for obtaining pointer each time!

Global _RetroGraphicsWidth:Int = 800 ' Display width
Global _RetroGraphicsHeight:Int = 600 ' Display height

' TGLFWWindow.Hint (GLFW_SAMPLES, msaa_level)
TGLFWWindow.Hint (GLFW_CONTEXT_VERSION_MAJOR, 3)
TGLFWWindow.Hint (GLFW_CONTEXT_VERSION_MINOR, 3) ' TODO: Change to 3! ******************
TGLFWWindow.Hint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)

AppWindow = New RetroGameWindow.Create (_RetroGraphicsWidth, _RetroGraphicsHeight, "Hello", Null)

If Not AppWindow
Print "Failed to create GLFW window!"
End
EndIf

AppWindow.MakeContextCurrent ()

gladLoadGL (glfwGetProcAddress)

'-------------------------------
' glFrontFace (GL_CW) ' TODO: Optional?
' glEnable (GL_CULL_FACE) ' TODO: If face_cull

' cube


LoadShaders ()
loadTexture()

Local vertexData:Float [] = [..
..        '  X     Y     Z       U     V
        -1.0,-1.0,-1.0,   0.0, 0.0, ' bottom
         1.0,-1.0,-1.0,   1.0, 0.0,
        -1.0,-1.0, 1.0,   0.0, 1.0,
         1.0,-1.0,-1.0,   1.0, 0.0,
         1.0,-1.0, 1.0,   1.0, 1.0,
        -1.0,-1.0, 1.0,   0.0, 1.0,
..
        -1.0, 1.0,-1.0,   0.0, 0.0, ' top
        -1.0, 1.0, 1.0,   0.0, 1.0,
         1.0, 1.0,-1.0,   1.0, 0.0,
         1.0, 1.0,-1.0,   1.0, 0.0,
        -1.0, 1.0, 1.0,   0.0, 1.0,
         1.0, 1.0, 1.0,   1.0, 1.0,
..
    -1.0,-1.0, 1.0,   1.0, 0.0, ' front
         1.0,-1.0, 1.0,   0.0, 0.0,
        -1.0, 1.0, 1.0,   1.0, 1.0,
         1.0,-1.0, 1.0,   0.0, 0.0,
         1.0, 1.0, 1.0,   0.0, 1.0,
        -1.0, 1.0, 1.0,   1.0, 1.0,
..
        -1.0,-1.0,-1.0,   0.0, 0.0, ' back
        -1.0, 1.0,-1.0,   0.0, 1.0,
         1.0,-1.0,-1.0,   1.0, 0.0,
         1.0,-1.0,-1.0,   1.0, 0.0,
        -1.0, 1.0,-1.0,   0.0, 1.0,
         1.0, 1.0,-1.0,   1.0, 1.0,
..
        -1.0,-1.0, 1.0,   0.0, 1.0, ' left
        -1.0, 1.0,-1.0,   1.0, 0.0,
        -1.0,-1.0,-1.0,   0.0, 0.0,
        -1.0,-1.0, 1.0,   0.0, 1.0,
        -1.0, 1.0, 1.0,   1.0, 1.0,
        -1.0, 1.0,-1.0,   1.0, 0.0,
..
         1.0,-1.0, 1.0,   1.0, 1.0, ' right
         1.0,-1.0,-1.0,   1.0, 0.0,
         1.0, 1.0,-1.0,   0.0, 0.0,
         1.0,-1.0, 1.0,   1.0, 1.0,
         1.0, 1.0,-1.0,   0.0, 0.0,
         1.0, 1.0, 1.0,   0.0, 1.0]


glGenVertexArrays(1, Varptr gVAO)
glBindVertexArray(gVAO)   
glGenBuffers(1, Varptr gVBO)
glBindBuffer(GL_ARRAY_BUFFER, gVBO)

glBufferData (GL_ARRAY_BUFFER, SizeOf(vertexData), vertexData, GL_STATIC_DRAW)

Local offset:Int = 3 * RetroFloatSize

glEnableVertexAttribArray (0)
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 5 * RetroFloatSize, Null);

glEnableVertexAttribArray (1)
glVertexAttribPointer (1, 2, GL_FLOAT, GL_TRUE, 5 * RetroFloatSize,  Byte Ptr (offset))

glBindVertexArray(0)

'gProgram->setUniform("camera", camera);

'PrintErrors ()
'LoadShaders ()
'LoadTexture ()


'Local lastTime:Double = GetTime ()

While Not AppWindow.ShouldClose ()

'If AppWindow.GetKey (GLFW_KEY_ESCAPE) Then AppWindow.SetShouldClose (True)
'Local thisTime:Double = GetTime ()
'Update (Float (thisTime - lastTime))
'lastTime = thisTime

Render ()

AppWindow.SwapBuffers ()
PollSystem ()

Wend



End

'-------------------------------------- END ----------------------------------------------

Function Render()

    glClearColor (0.1, 0.2, 0.3, 1)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
   
    glUseProgram (Program)

Local view_matrix:SMat4F
Local projection_matrix:SMat4F

'proj
Local uni_prj:Int = glGetUniformLocation (Program, "projection")
projection_matrix = SMat4F.Perspective (50, _RetroGraphicsWidth, _RetroGraphicsHeight, 0.1, 1000.0)
glUniformMatrix4fv (uni_prj, 1, False, Varptr projection_matrix.a)

' view
Local uni_cam:Int = glGetUniformLocation (Program, "camera")
'view_matrix = SMat4F.LookAt (New SVec3F (0, 0, 8), New SVec3F (0.0, 0.0, 0.0), New SVec3F (0.0, 1.0, 0.0))
view_matrix = SMat4F.Translation(New SVec3F(1, -2, -10))
glUniformMatrix4fv (uni_cam, 1, False, Varptr view_matrix.a)

'--------
Local uni_mod:Int = glGetUniformLocation (Program, "model")
Local mMat:SMat4F = SMat4F.Identity ()
glUniformMatrix4fv (uni_mod, 1, False, Varptr mMat.a)

'--------
    glActiveTexture (GL_TEXTURE0)
Local uni_tex:Int = glGetUniformLocation (Program, "tex")
    glBindTexture (GL_TEXTURE_2D, Texture) ' Was gTexture
glUniform1i (uni_tex, 0)
'--------

glBindVertexArray (gVAO)

glBindBuffer(GL_ARRAY_BUFFER, gVBO)
glVertexAttribPointer(0, 3, GL_FLOAT, False, 0, 0);
glEnableVertexAttribArray(0)

    'glBindVertexArray (gVAO)

'glEnable (GL_DEPTH_TEST)
'glDepthFunc (GL_LESS)
'glEnable (GL_BLEND)
'glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

    glDrawArrays (GL_TRIANGLES, 0, 6*2*3)

    'glBindVertexArray (0)
    'glBindTexture (GL_TEXTURE_2D, 0)
    'glUseProgram (0)


   

EndFunction

Function LoadShaders ()

' LOAD SHADERS



Local vertex_source_file:String = "vertex-shader.txt"
Local fragment_source_file:String = "fragment-shader.txt"

If Not FileType (vertex_source_file) Then vertex_source_file = "resources/" + vertex_source_file
If Not FileType (fragment_source_file) Then fragment_source_file = "resources/" + fragment_source_file


Local vertex_source:String = LoadString (vertex_source_file)
Local  fragment_source:String = LoadString (fragment_source_file)

' ---------------------------------------------------------------------
' Create vertex shader object...
' ---------------------------------------------------------------------

vertex_shader:Int = glCreateShader (GL_VERTEX_SHADER)

' ---------------------------------------------------------------------
' Build and check vertex shader...
' ---------------------------------------------------------------------

glShaderSource (vertex_shader, 1, vertex_source)
glCompileShader (vertex_shader)

Local success:Int

glGetShaderiv (vertex_shader, GL_COMPILE_STATUS, Varptr success)

If Not success
'ShaderCompilationError (fragment_shader, fragment_source, vertex_source_file)
Print "Failed to compile shader"
End
EndIf

' ---------------------------------------------------------------------
' Create vertex shader object...
' ---------------------------------------------------------------------

fragment_shader:Int = glCreateShader (GL_FRAGMENT_SHADER)

' ---------------------------------------------------------------------
' Build and check fragment shader...
' ---------------------------------------------------------------------

glShaderSource (fragment_shader, 1, fragment_source)
glCompileShader (fragment_shader)

glGetShaderiv (fragment_shader, GL_COMPILE_STATUS, Varptr success)

If Not success
'ShaderCompilationError (fragment_shader, fragment_source, vertex_source_file)
Print "Failed to compile shader"
End
EndIf

' ---------------------------------------------------------------------
' Create shader program and attach compiled shader objects...
' ---------------------------------------------------------------------

Program = glCreateProgram ()

glAttachShader (Program, vertex_shader)
glAttachShader (Program, fragment_shader)

' ---------------------------------------------------------------------
' Link and check shader program...
' ---------------------------------------------------------------------

glLinkProgram (Program)

glGetProgramiv (Program, GL_LINK_STATUS, Varptr success)

If Not success
Print ""
Print "Shader program linking failed: " + glGetProgramInfoLog (Program)
End
EndIf

' ---------------------------------------------------------------------
' Detach and delete shaders as no longer needed, now part of program...
' ---------------------------------------------------------------------

Rem
glDetachShader (Program, vertex_shader)
glDetachShader (Program, fragment_shader)

glDeleteShader (vertex_shader)
glDeleteShader (fragment_shader)
End Rem
'glUseProgram (Program)

    'glUseProgram (0)


glDetachShader (Program, vertex_shader)
glDetachShader (Program, fragment_shader)

glDeleteShader (vertex_shader)
glDeleteShader (fragment_shader)

EndFunction




Function LoadTexture ()

' load and create a texture
' -------------------------

glGenTextures (1, Varptr Texture)
glBindTexture (GL_TEXTURE_2D, Texture)

' set the texture wrapping parameters
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)

' set texture filtering parameters
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

Local pixmap:TPixmap = LoadPixmap ("resources/container.jpg")

If pixmap Then
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, pixmap.width, pixmap.height, 0, GL_RGB, GL_UNSIGNED_BYTE, pixmap.pixels)
glGenerateMipmap (GL_TEXTURE_2D)
Else
Print "Failed to load texture"
End
End If

EndFunction



Function PrintErrors (ref:String = " ... ")

'Return

Local error:Int = glGetError ()

While error
Print "OpenGL Error " + error + " (" + ref + ")"
Wend

EndFunction


Function Update (secondsElapsed:Float)
    Local degreesPerSecond:Float = 180.0
    gDegreesRotated =gDegreesRotated + secondsElapsed * degreesPerSecond
    While gDegreesRotated > 360.0
gDegreesRotated = gDegreesRotated - 360.0
Wend
EndFunction

Type RetroGameWindow Extends TGLFWWindow

Method OnFrameBufferSize (width:Int, height:Int)
glViewport (0, 0, width, height)
AppWindow.GetFrameBufferSize (_RetroGraphicsWidth, _RetroGraphicsHeight)
EndMethod

EndType

Const RETRO_RAD_DIVIDER:Float = 180.0 / Pi
Const RETRO_DEG_DIVIDER:Float = Pi / 180.0

Function Degrees:Float (radians:Float)
Return radians * RETRO_RAD_DIVIDER
EndFunction

Function Radians:Float (degrees:Float)
Return degrees * RETRO_DEG_DIVIDER
EndFunction



Good enough for me for today, I may work on this later or tomorrow. Just run it and see what I have changed. Some changes are just personal. I kept your global variables, but I always avoid global.
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on April 26, 2020, 23:12:12
Hi medi71, just to let you know, Brucey has done some fixes to matrix.mod, so you might want to update -- or you might end up having to change stuff later on!

https://github.com/bmx-ng/brl.mod/tree/master/matrix.mod

It's now working correctly with the tutorial code I was using, copy attached!
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 27, 2020, 00:02:40
Yes, it works now. I was half a way in writing my own LookAt! So, you saved me a lot of time,thanks.
I increased your cameraFar to let the camera have more z to maneuver.
I like Brucey's texture examples. They show what to do when a model has many attributes. My example has only vertices and coordinates and uses DrawArrays.
So far, everything good.   ^-^
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 27, 2020, 00:04:12
Good luck on your game engine. Don't rush it.
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 27, 2020, 00:21:36
My example started to work after the matrix fix.
I have to use OpenGL 4.3 for this because the shader uses:

layout(binding=0) uniform sampler2D samp;

Binding is available after 4.1, as the book says.
However, we can see that we can go up to OpenGL 4.3!
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on April 27, 2020, 01:20:25
Interesting, didn't know it went as high as 4.3! Binding is new to me...

QuoteI was half a way in writing my own LookAt!

Yeah, don't be shy about reporting potential problems with bmx-ng and its modules... Brucey sorted this within a day, given some evidence!

I've still got TONS to learn, but I'm now more confident that I understand what I've learned so far, and that my silly little plans might even be achievable!  :o
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 27, 2020, 04:41:25
The kind of dream you have is achievable, you just need to be persistent and patiently learn to pass its knowledge obstacle. In fact, you did exactly that regarding the LookAt issue.
I don't make games, so I cannot give you any first hand suggestion. But, I can say I learn from game tutorials. When I was learning, I found that a game engine (bunch of libraries) is actually being made to make the game creation easier to organize to finish the job.
A tutorial that help me a lot long time ago was this:
https://jnoodle.com/Blitz3D/
You can try to create the game using BlitzMax's opengl rather than simple to use Blitz3D's commands. You will see that you have to make lots of libraries to do so. In this way you get close to what you want. Or at least you grasp what is needed to be done. In that stage, you can read game engine books to leap to higher level. That game in the linked tutorial doesn't have shadows. You can say, I will feel I have had progress by adding shadows.
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 27, 2020, 11:15:12
Another however, I will limit myself to OpenGL 3.3.
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on April 28, 2020, 00:37:30
I chose 3.3 too -- the best balance between reasonably far-back compatibility and ease-of-feature-access as far as I can tell.

I've been dabbling in Blitz3D/BlitzMax for many years, but never got into the fairly low-level stuff until now. I wouldn't have even considered it seriously prior to playing with mojo3d in Monkey2 (sadly both now defunct), where it exposed the programmer to use of vectors and matrices in a good way.

I've just added keyboard control to my cube -- all rather hacky for now (global abuse, as you mentioned, no frame-limiting on the movement, etc), but cool to see it working!

Cursors plus A/Z move the cube;
W toggles wireframe (dependent on driver support);
C toggle backface culling (go inside cube to see).
Title: Re: Any chance of a GLFW port?
Post by: medi71 on April 28, 2020, 04:36:14
I will look at what you have done.
Title: Re: Any chance of a GLFW port?
Post by: degac on May 02, 2020, 14:09:33
Dumbest question of all the time.
With so much different 'drivers' and 'engines' (SDL and GLFW are 'duplication' of many things already present in BlitzMax - events, keyboard, sounds etc) it will be useful or not having a 'mega wrapper' at the top of them?

The idea is like in BlitzMax, just to setup a 'driver' (OpenGL, DirectX) to compile for that 'engine'.
(I know that sound so easy writing on the keyboard!!! but a sort of hell to realize! - maybe impossible!)
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on May 05, 2020, 01:19:14
@degac: makes sense, though a lot of work for Brucey! Not that that seems to stop him...

Just posting an update with my latest efforts -- LOTS of hackery involved, but I started putting stuff into classes again and a few Blitz3D-like wrapper functions, been fun this evening... it's a mess, but it's my mess, and I'm gradually tidying while also trying things out. Keeping single-file for now.

I can do around 10,000 cubes without any slowdown (after some pausing at startup), even with zero optimisation on my part!

There's also optional PS1-style texture warping (see LoadShaders to enable the alternative .glsl files, and if you edit resources\vertex-shader-affine-warping.glsl, you can even have wobbling vertices!).

The rotation is a quick hack, there's only (global) translation at present.

Controls are in the title-bar! C culls backfaces (not culled by default), but it's hard to tell here, and W does wireframe, but this is driver-dependent so don't be surprised if it doesn't do anything...

I've left the .exe in there for quick testing -- run through VirusTotal with no detections, but use normal precautions.

Thanks to Brucey for getting GLFW going... I've got a couple of OpenGL 3.3 books on order now as well, so I'm using it!
Title: Re: Any chance of a GLFW port?
Post by: Derron on May 05, 2020, 08:06:46
Quote from: degac on May 02, 2020, 14:09:33
The idea is like in BlitzMax, just to setup a 'driver' (OpenGL, DirectX) to compile for that 'engine'.
(I know that sound so easy writing on the keyboard!!! but a sort of hell to realize! - maybe impossible!)

What might work is some kind of "meta package". So you would do

Framework Brl.SDLBackend
or
Framework Brl.DefaultBackend

and these both modules import DefaultSystem / SDLSystem / .... for you.
The SDLBackend would also provide GLMax2DDriver() etc - so "drivers" which simply extend the SDL drivers to return the same stuff as the default drivers do. Dunno if they should identify themselves as "SDL DirectX Drivers" or not (so that your app eg. can display properly what driver it _really_ uses).



bye
Ron
Title: Re: Any chance of a GLFW port?
Post by: degac on May 05, 2020, 09:09:53
Thanks both.

I suspected that it isnt' an easy solution.... maybe a 'source' of new problems or limitations.
But I just imagined you write a game for SDL. And it works.
Then if you want to 'port' using GLFW, you need to rewrite it for some/big part...
Not a great motivation to jump.

ps: I know that SDL provides better 'coverage' (PC, Android, NX etc) so - at this point - should be the 'basic render' in NG.

At this point should be interesting thinking if a possible 'relifting' of the BlitzMax NG module (gfx/event) could/should be possibile or if necessary.
Title: Re: Any chance of a GLFW port?
Post by: DruggedBunny on May 30, 2020, 14:33:43
Hi all,

Just a little update, mainly to let Brucey know I'm still putting his efforts to good use! NB. Very, very WIP indeed.

1) Unzip the attached mod so it sits at: BlitzMaxNG\mod\hitoro.mod
2) Open the hitoro.mod\retro3d.mod\wip folder and run the demos. (Cursors + A/Z.)

I just got a little excited, as my first attempt to use quaternions to rotate my cube worked first time!

This very basic example (demo5.bmx) shows how simple it can be to use quaternions for rotation -- see excerpt below from entity.bmx:



Type Entity

Field position_matrix:SMat4F
Field position:SVec3F

Field rotation_matrix:SMat4F
Field rotation:SVec3F
Field rotation_quat:SQuatF

Method New ()

position_matrix = SMat4F.Identity ()

rotation = New SVec3F (0.0, 0.0, 0.0) ' Euler angles
rotation_quat = New SQuatF (0.0, 0.0, 0.0, 0.0).EulerXYZ (rotation) ' Quaternion creation from angles
rotation_matrix = SQuatF.ToMat4 (rotation_quat) ' Matrix used for rendering

EndMethod

...


No idea if I'm doing it right, but I'm sure I can work from this anyway.