Current situation using GLWF/modernGL/shaders

after a couple of years successfully using Julia0.7 to prototype a software to model a painter’s creative process by using my own custom bindings to openGL1.0 using free glut I would like to explore modernGL and shaders…noting that earlier packages were built around GLWindow and GLAbstraction but wanting to switch to julia1.x ( I use julia1.0 for now) I managed use raw GLWF to replace GLWindow to run the first examples in GLAbstraction tutorials…but hit a wall with polygons5 when the code starts using LazyShader and the render. abstraction… I then noted that Louis Ponet’s GLAbstraction does not have the render abstraction and no trace of lazy shader, while Paul m THomson 's GLabstraction. does have them but do not compile in julia1.0x …SImon Danish, the original developper of these packages seems to have switched to Make. and focus on replacement for GLAbstraction…in sum. it’s a bit of a mess right now. I am new to this list and would appreciate if someone could. give me pointers on how to learn more advanced shaders with GLFW. in current Julia…the dream would be to recover a GLAbstraction with render and lazy shaders etc… thanks in advance.

These examples might be of interest to you. There might be some examples that are not working for Julia 1.x, feel free to file an issue if you hit any problems.

1 Like

thanks for the suggestion…I actually did explore the voider tutorials and many of them worked for me…yet , so far they have not allowed me to overcome the problems revealed by the polygons5 and texture examples in Louis poet’s GLABStraction tutorials…I will go back to them and try to reformulate my question in the light of them. I first want to see if there is the equivalent of GLAbstraction/render/shaders. in the VIDERE tutorials.

the voider tutorials … I meant the VIDERE tutorials :slight_smile:

Sorry, I misunderstood the question. I thought you’d like to use raw GLFW and ModernGL. If you just wanna replace GLWindow with GLFW, then combining the simplest example in Videre with GLAbstraction will be enough to do the job.

The LazyShader and the render abstraction stuff are just certain abstractions over the ModernGL’s basic utilities, they have nothing to do with the advanced modern GL shaders. This recalls the old days when I was learning ModernGL with Julia. Back then, GLAbstraction has some fancy dependencies like Mustache for handling GLSL version. As a beginner, I found these abstraction-only stuff are noisy and it’s actually easier and effective to start with raw ModernGL APIs and build a glutils file with helper functions gradually. But it looks like your specific question is how to fix the example in the GLAbstraction repo. I’d say you will get more helpful responses if you file an issue to the GLAbstraction repo. :wink:

Unfortunately, these examples in Videre are intentionally not using any abstraction layers like GLAbstraction. There is only a glutils.jl file that contains some helper functions for compiling shader, linking GLSL program, creating GLFW window, etc.

thanks for the conversation. the examples in voider were wonderful and essential for me. the problem was larger than just replacing GLWindow with GLFW to run the simplest examples in VIDERE or in the GLAbstraction tutorials. indeed I concord with your remark on starting with Raw ModernGL and build a glutils with helper functions…as it is done in VIDERE. actually I am trying to put together an interactive platform where you can type functions in an Xterm and see how they act on things displayed in an openGL windows… develop a toolkit gradually this way. I. actually have a starting point with a modified VIDERE 04mats and vets. …I’ll just paste it here. if you put it into a vectmac2.jl in the 04 folder. then if you include it in julia1x from a terminal ir will open a widow and enter the menu loop. r. key spawns a Julia real inside the running program and you can reenter the menu just typing. mn(). the menu can turn into a tree of multiple menus. here the only commands are c. for clear and u for update screen
forgive th clumsiness of all this but if you can run this inside the voider 04 folder then it will be much easier to focus on questions. I am actually doing this in parallel in gnu-smalltalk and also in J programming…the problem is moving a fairly elaborate painting program from openGL1.0. where it runs really well to shader mechanics so I can use it on the raspberry pi. for workshops on painting and coding with youngsters… anyway here is vecmat2.jl

===========================

using CSyntax

@static if Sys.isapple()
const VERSION_MAJOR = 4
const VERSION_MINOR = 1
end

ENV[“JULIA_DEBUG”] = “all”

using REPL

#include(“classMenu.jl”)

=== class menu

mutable struct Menu
data::Array
cmds::Dict
mnuFlg::Bool
# === declare methods
disp::Function
commands::Function

# ===  constructor
function Menu()

	# ===  initialize
	
	this = new()  
	this.data=Array{String}(undef, 1)
	this.cmds=Dict()
	
	# == define methods
	
	this.disp=function() 
		println(this.data)
	end
	
	this.commands=function(s)
		this.data=s
	end
	
	return this
end # ==end constructor

end

=== the menu system executive loop

function input(prompt::String="")::String
print(prompt)
return chomp(readline())
end

function mn()
curmnu.mnuFlg=true
while curmnu.mnuFlg
curmnu.disp()
cmd= input(“enter command:”)
#println(cmd)
curmnu.cmdscmd
end
# == try exiting to repl here

end

==== create menus

mainmnu = Menu()
drawmnu = Menu()
curmnu=mainmnu

==== utils

function exit2repl()
term =REPL.Terminals.TTYTerminal(get(ENV, “TERM”,“dumb”),stdin,stdout,stderr)
active_repl = REPL.LineEditREPL(term, true)
active_repl.history_file=true
REPL.run_repl(active_repl, backend->(global active_repl_backend = backend))
end

==== mainmnu

function main_exit()
println(“exit main”)
curmnu.mnuFlg=false
GLFW.DestroyWindow(window)
end

function main_repl()

curmnu.mnuFlg=false
run(`clear`)	
exit2repl()
end

function main_clear()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
GLFW.SwapBuffers(window)
end

function main_update()
update()
end

mainmnu.commands([“eXitmain”,“Repl”,“Clear”,“Update”])

mainmnu.cmds[“x”]=main_exit
mainmnu.cmds[“r”]=main_repl
mainmnu.cmds[“c”]=main_clear
mainmnu.cmds[“u”]=main_update

==== include glutils.jl ===

include(joinpath(@DIR, “glutils.jl”))
#include( “classMenu.jl”)

init window

#global width, height = fb_width, fb_height = 1300, 700
global width, height = 1300, 700
global cursx, cursy = 0,0
global normx=0.0

=== start openGL window

window = startgl(width, height)

glEnable(GL_DEPTH_TEST)
glDepthFunc(GL_LESS)

vertex data

points = GLfloat[ 0.0, 0.5, 0.0,
0.5, -0.5, 0.0,
-0.5, -0.5, 0.0]

colors = GLfloat[ 1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0]

create buffers located in the memory of graphic card

points_vbo = GLuint(0)
@c glGenBuffers(1, &points_vbo)
glBindBuffer(GL_ARRAY_BUFFER, points_vbo)
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW)

colors_vbo = GLuint(0)
@c glGenBuffers(1, &colors_vbo)
glBindBuffer(GL_ARRAY_BUFFER, colors_vbo)
glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW)

create VAO

vao = GLuint(0)
@c glGenVertexArrays(1, &vao)
glBindVertexArray(vao)
glBindBuffer(GL_ARRAY_BUFFER, points_vbo)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, C_NULL)
glBindBuffer(GL_ARRAY_BUFFER, colors_vbo)
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, C_NULL)
glEnableVertexAttribArray(0)
glEnableVertexAttribArray(1)

load and compile shaders from file

vert_shader = createshader(joinpath(@DIR, “vecmat.vert”), GL_VERTEX_SHADER)
frag_shader = createshader(joinpath(@DIR, “vecmat.frag”),GL_FRAGMENT_SHADER)

link program

shader_prog = createprogram(vert_shader, frag_shader)

enable cull face

glEnable(GL_CULL_FACE)
glCullFace(GL_BACK)
glFrontFace(GL_CW)

set background color to gray

glClearColor(0.0, 0.0, 0.0, 1.0)

transform matrix

matrix = GLfloat[1.0 0.0 0.0 0.5;
0.0 1.0 0.0 0.5;
0.0 0.0 1.0 0.0;
0.0 0.0 0.0 1.0]

matrix_location = glGetUniformLocation(shader_prog, “matrix”)
println(matrix_location)

glUseProgram(shader_prog)
glUniformMatrix4fv(matrix_location, 1, GL_FALSE, matrix)

==== setup some event callbacks

#=
GLFW.SetMouseButtonCallback(window,
(_, button, action, mods) ->begin
#println("$button $action")
normx=cursx/width
# == why this???
#matrix_location=normx
normy= (1.0 -(cursy/width))
println([matrix_location,normx,normy])
matrix[1,4] = normx
matrix[2,4] = normy
end
)

#GLFW.SetCursorPosCallback(window, (_, x, y) -> println(“cursor: $x, $y”))

GLFW.SetCursorPosCallback(window,
(_, x, y) -> begin
global cursx=x
global cursy=y
global normx=cursx/width
#println(“cursor: $x, $y, $normx”)
#println("$normx $matrix")
#matrix[1,4] = normx
end
)

=#

#  === first rendering	
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glViewport(0, 0, width, height)
# drawing
glUseProgram(shader_prog)
# update matrix
#matrix[1,4] = sin(time())
#matrix[1,4] = normx


glUniformMatrix4fv(matrix_location, 1, GL_FALSE, matrix)
# drawcall
glBindVertexArray(vao)
glDrawArrays(GL_TRIANGLES, 0, 3)

# check and call events
GLFW.PollEvents()
# swap the buffers
GLFW.SwapBuffers(window)

#end
#end # let

function update()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
#glViewport(0, 0, width, height)

glUseProgram(shader_prog)
glUniformMatrix4fv(matrix_location, 1, GL_FALSE, matrix)

glBindVertexArray(vao)
glDrawArrays(GL_TRIANGLES, 0, 3)
GLFW.PollEvents()
GLFW.SwapBuffers(window)
end

mn()

GLFW.DestroyWindow(window)

==============

I will add that making a strictly identical program in J, smalltalk and Julia all running identically from the terminal. is quite interesting…

regards and thanks for the focus and also for voider…

voider @&!&@!! I mean VIDERE…

louis pont replied to my ping about this problem on research gate…so there is hope to put together a GLFW environment that should me more effective than it is now…

pont. …I mean Ponet !!! damn the automatic spelling corrector!

I’ve recently pushed quite some work to the master branch of GLAbstraction, all tutorials work again, and all examples except for the compute shaders one, for which I may need some help to understand what is going on.

Hope it helps!

1 Like

thanks for doing that…it’s kind of opening a pandora box of errors and questions…but the drawing_polygons5.jl is working…and that’s a first step for me to expand on…all other examples had errors due to packages like ImageIO NOT loading in my JUlia1.0

i also note that in some examples you are still using GLFWindow which is a package that is not working neither in julia 0.7 nor in julia1.0 does this mean there is a version of GLFWindow that works julia1.0 ???

it’s intersting to compare the two versions of
drawing_polygones5 the older version i got from your earlier git site for GLAbstraction

the earlier version creates the glbuffers via

bufferdict = Dict(:position=>Buffer(vertex_positions),
:color=>Buffer(vertex_colors),
:indexes=>indexbuffer(elements)) # special for element buffers

ro = std_renderobject(bufferdict,
LazyShader(vertex_shader, fragment_shader)

and renders them inside the GLFW eventloop as

GLAbstraction.render(ro)

this older version never compiled because of nowhere any trace of LazyShader!!
that is when i discovered various versions of GLAbstraction, one of them by Paul THompson…still no trace of LAzySHader…

in fact my post to you was in the hope of finding a way to use that
bufferdict = Dict( … approach which seemed appropriate to study all sorts of shaders…

the newer version to my great surprise does away with the std_renderobject
and does instead

buffers = GLA.generate_buffers(prog, GLA.GEOMETRY_DIVISOR,
position = vertex_positions,
color = vertex_colors)

vao = GLA.VertexArray(buffers, elements)

and the rendering inside of the event loop is now replaced by three lines

GLA.bind(prog)
GLA.bind(vao)
GLA.draw(vao)

obviously these are different approaches of the rendering process
it’s intriguing for me why you chose that path over the previous one…

there is a lot more to say. some points i can better discuss in my coming reply on researchgate;…

this first step definitely helps…thank you …i will have to post some more questions later on.

I finally overcame some of the problems in louis poet’s tutorial examples from his recently updated GLAbstraction package on git…early difficulties cam from error such as:

Package ImageIO not found in current path

interestingly this error disappears if I add.

using FIleIO. in the “using” list of packages, then if one replaces using GLWindow. by explicit creation of the window and of the glcontext as louis point has done in his updated
drawing_polygons5.jl
that examples also shows how to replace the obscure LazyShader abstraction in:

bufferdict = Dict(:position=>GLBuffer(vertex_positions))
ro = std_renderobject(bufferdict,
LazyShader(vertex_shader, fragment_shader))

by explicit prog binding:

prog = GLA.Program(vertex_shader, fragment_shader)
buffers = GLA.generate_buffers(prog,
GLA.GEOMETRY_DIVISOR,
position = vertex_positions)
vao = GLA.VertexArray(buffers, GL_TRIANGLES)
and replaced the use of the render object in the rendering loop:
GLAbstraction.render(ro)

by. explicit. binding and drawing
GLA.bind(prog)
GLA.bind(vao)
GLA.draw(vao)

Louis Ponet has also updated. the
depth_stencils1.jl
and textures1,2.jl

it was a bit delicate how to clarify the mapping go the render object abstractions. to explicit prog and VAO binding. when time varying functions were used…

only and miraculously
texture_exercise1.jl
provided a doable case:
bufferdict = Dict(
:position=>Buffer(vertex_positions),
:texcoord=>Buffer(vertex_texcoords),
:texKitten=>Texture(data(kitten)),
:texPuppy=>Texture(data(puppy)),
:indexes=>indexbuffer(elements),
:blend_f=>1f0
) # special for element buffers

ro = std_renderobject(
bufferdict,
LazyShader(
vertex_shader, fragment_shader,
fragdatalocation=[(0, “outColor”)]
))

had to be replaced by:
prog = GLA.Program(vertex_shader, fragment_shader)
buffers = GLA.generate_buffers(prog,
GLA.GEOMETRY_DIVISOR,
position = vertex_positions,
texcoord=vertex_texcoords,
blend_f =1f0
)

vao = GLA.VertexArray(buffers, elements)
tex_kitten = GLA.Texture(collect(kitten’))
tex_puppy = GLA.Texture(collect(puppy’))

then. inside the render loop. the two lines:
ro[:blend_f] = Float32(mod(time(), period)/period)
GLAbstraction.render(ro)

had to be replaced by:

 push!(blend_f, Float32(mod(time(), period)/period))
GLA.bind(prog)
GLA.gluniform(prog, :texKitten, 0, tex_kitten)
GLA.gluniform(prog, :texPuppy, 1, tex_puppy)
GLA.gluniform(prog, :blend_f, value(blend_f))
GLA.bind(vao)
GLA.draw(vao) 	

thus explicating the delicate mechanism of how to interact with shaders with time varying functions inside the rendering loop…
quite a challenging formalism for the laymen and beginners…

I do get this message when running this modified texture_excercise1.jl

┌ Warning: Message queue is full. Ordering may be incorrect. Channel size can be increased by setting ENV["REACTIVE_CHANNEL_SIZE"] = ... before using Reactive.

at least this is giving me a foothold into reactive…

applying these mods to other examples and exercises made them all. work…with the exception of the last two ones.

transformation_exercise1. and 2.jl

who are using a
rotate
function that is not defined anywhere…

I saw traces of a rotation function in Paul Thompson’s git version of GLAbstraction. inside the. GLMatrixMath.jl. file

rotate{T}(angle::T, axis::Vec{3, T}) = rotationmatrix4(Quaternions.qrotation(convert(Array, axis), angle))

this rotate function seems to take the same parameters as the rotate. function in
transformation_exercise1,2

but simply pasting it into these files did not work…

thus most of the examples and exercises now can work
( with the annoyance of a recurrent compilation error. in the package QuartzImageIO. complaining that:

[ Info: Precompiling QuartzImageIO [dca85d43-d64c-5e67-8c65-017450d5d020]
ERROR: LoadError: UndefVarError: RGBX not defined

which makes testing the examples annoyingly slow :))

thanks to Louis Ponet for this update as it gives me a crack in the wall towards making an interactive platform to explore shaders and modernGL…the next step is to integrate these examples with the menu system. posted higher up in this thread.
a longer term goal is to be able to exit the shackle of the rendering loop and use custom events loop from inside the menus. like it is possible to do if using FreeGlut instead of GLFW… because free glut has the.
glutMainLoopEvent. and glutLeaveMainLoop. functions for which GLFW seems to have no equivalent…(unless someone can point me to a way to do this in GLFW. :)). )

I did manage to put together one example of controlling shaders under freeGlut interactively from menus using J programming but it was difficult to learn how to use the GL. perpective matrix…the examples in louis ponet’s update are a significant step to learn that.

this effort aims at having a platform to explore the modernGL. statemachine interactively from the REPL …

Louis POnet’s generous update of GL abstraction has allowed me to move one step forward. I now have a flat white texture on which I can interactively change some areas…the problem is now to bring it to a 2D geometry on which I can change pixels and draw lines…I have tried to stall the Glimpse package. but it refuses to install on my Julia1.0. complaining that. GeometryBasics. is not installable …I also note that. Glimpse use the CImGui. package…when I try to install that package it complains that:Warning: julia version requirement for package CImGui not satisfied
â @ Pkg.Operations /Users/osx/buildbot/slave/package_osx64/build/usr/share/julia/stdlib/v1.0/Pkg/src/Operations.jl:143
ERROR: Unsatisfiable requirements detected for package GLFW [f7f18e0c]:
GLFW [f7f18e0c] log:
ââpossible versions are: [2.1.0, 2.2.0, 2.3.0, 3.0.0, 3.1.0, 3.2.0-3.2.2, 3.3.0, 3.4.0] or uninstalled

and yet my currently installed GLFW package functions well with the Gnimuc/videre tutorials …

impressive how difficult it is to arrive at a consistent world in the Julia ModernGL front… any suggestions?

Lots of stuff to comment on :slight_smile:

This was kind of the main reason why I started to work on GLAbstraction. Over the development period of GLVisualize turned later into Makie/GLMakie, it morphed from being purely an abstraction layer to half of a fully fledged rendering library. The idea was thus to remove things like the std_renderobject which can then be rendered using render because it does not allow for too much flexibility and obfuscates some mechanisms making it harder to adapt to more general usecases.
So I tried to turn GLAbstraction into more of a toolbox that provides some obvious abstractions around the normal OpenGL standard, but no defaults so to say.
It does not, for example, make too much sense to tie a shader to one particular geometry that has to be rendered, neither does the openGL setup inside the renderloop.
So the philosophy is that GLAbstraction provides you with some nice to have utilities over OpenGL but won’t handle the specific rendering for you.

As far as I can tell from looking at the examples again, this was all replaced by specific function definitions for the transformation matrices, i.e. rotmat_z lookat and prespectiveprojection

Yea I did not change the exercises, because honestly I’m not sure that we should have OpenGL tutorials and exercises in a package like GLAbstraction, rather in a separate notebook type package, so I didn’t get around to that.

So Glimpse is really not ready to be published, and thus not registered. I didn’t know it was an issue to get it installed.

I think this is mainly because the one package that satisfies most people’s uses is Makie which is more developed and mature, and I think should not have issues working. The other packages that you’re trying to use are pretty much usable but not quite robust to be used generally, which is why they are not registered yet (you cannot do add GLAbstraction). That being said, I think I should make work of registering GLAbstraction again…

Also, on a more general note, It’s probably best to just open issues on the github repos of the packages that are not working as desired, that allows the makers to track what is going wrong and improve the experience for every subsequent user

for now no problem as the updates you did on the glAbsstraction tutorials went a long way to overcome the basics…i now have a cube ( the one of trenasformatons2 ) that i can control(i can rotate on the three axis, and pan the scene) from my little menus by altering some parameters of the transform matrix…spawning a Julia repl from the menus allows to inspect objects and tamper with the GL state machine… there are enough details on transforms to work my way to control zooming which is what i need to get as close as i can to a plat 2D space on which i can alter one pixel ( even if thicker crude pixels…) all i need is a way to display 2D polylines with shaders… no internet at home (for absurd admiistrative reasons) the ortho function of old openGL1.1 seems no longer there… I am hoping to find my way by tampering with PerspectiveProjection. and lookout function and arrive at the equivalent of what I had with glortho… I agree with your methodological remarks on posting…for now with no internet at home and a ore and more tense situation in the cafes where I have managed to work with internet these last months…doing things right is a bit difficult. hopefully things will get better after my eye cataract operations en of oct… getting in touch with you via researgate was kind of a miracle that at least got me with that cube controlled from my menus… the software I have written works fine without shaders to work on paintings in the studio…but it’s crucial to move it. to shaders if I want to share it and do workshops with it… for now thanks a lot. I will come back to this in a little while