Any chance of a GLFW port?

Started by DruggedBunny, March 10, 2020, 02:04:32

Previous topic - Next topic

medi71

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



medi71

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.

medi71


DruggedBunny

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

medi71

I am working on your program. It may take long because I will reduce your program then add your other code gradually.

medi71

#66
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.

DruggedBunny

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!

medi71

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.   ^-^

medi71

Good luck on your game engine. Don't rush it.

medi71

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!

DruggedBunny

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

medi71

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.

medi71

Another however, I will limit myself to OpenGL 3.3.

DruggedBunny

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