Editeur Shader 2D
Publié : mar. 02/avr./2024 18:47
Salut les codeurs,
je reprends le fil de threedslider : Shader pour OpenGL
viewtopic.php?t=19144
j'ai un peu modifié le code repris par manababel en y ajoutant quelques modifs (pris en compte de la souris, copie dans/depuis le presse papier, warning/error)
ça serais bien de l'améliorer
si vous voulez, je peux faire des shaders et vous expliquer les bases si besoin
dites moi ce qui vous intéresserai
vous etes plusieurs à vous etre pencher sur OpenGL
je pense que ça serai bien de refaire la lib sprite pour permettre leur utilisation (ça devrai pas être très compliqué)
l'editeur legerement modifié:
je reprends le fil de threedslider : Shader pour OpenGL
viewtopic.php?t=19144
j'ai un peu modifié le code repris par manababel en y ajoutant quelques modifs (pris en compte de la souris, copie dans/depuis le presse papier, warning/error)
ça serais bien de l'améliorer
si vous voulez, je peux faire des shaders et vous expliquer les bases si besoin
dites moi ce qui vous intéresserai
vous etes plusieurs à vous etre pencher sur OpenGL
je pense que ça serai bien de refaire la lib sprite pour permettre leur utilisation (ça devrai pas être très compliqué)
l'editeur legerement modifié:
Code : Tout sélectionner
;/ GLSL example to test new OpenGLGadget - PJ 06/2014.
;EnableExplicit
ExamineDesktops()
Global screen_lg = DesktopWidth(0)
Global screen_ht = DesktopHeight(0)
Structure shaders
file.s
name.s
EndStructure
Global NewList ShaderList.shaders()
Global shader$
Enumeration ;/ Window
#Window_Main
EndEnumeration
Enumeration ;/ Gadget
#Gad_OpenGL
#Gad_Editor
#Gad_message
#Gad_ShaderSelector_Combo
EndEnumeration
Enumeration ; button
#run = 100
#load
#save
#loadcb
#savecb
#exit
#test
EndEnumeration
Structure System
Width.i
Height.i
Shader_Width.i
Shader_Height.i
Event.i
Exit.i
MouseX.i
MouseY.i
App_CurrentTime.i
App_StartTime.i
Editor_LastText.s
Shader_Vertex_Text.s
Shader_Fragment_Text.s
Shader_Vertex.i
Shader_Fragment.i
Shader_Program.i
Shader_Uniform_Time.i
Shader_Uniform_Resolution.i
Shader_Uniform_Mouse.i
Shader_Uniform_SurfacePosition.i
FPS_Timer.i
Frames.i
FPS.i
EndStructure
Global System.System
Procedure LoadGLTextures(Names.s)
Protected *pointer, TextureID.i, FrameBufferID.i
LoadImage(0, Names) ; Load texture with name
*pointer = EncodeImage(0, #PB_ImagePlugin_BMP,0,24);
FreeImage(0)
; ----- Generate texture
glGenTextures_(1, @TextureID.i)
glBindTexture_(#GL_TEXTURE_2D, TextureID)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR)
glTexImage2D_(#GL_TEXTURE_2D, 0, 3, PeekL(*pointer+18), PeekL(*pointer+22), 0, #GL_BGR_EXT, #GL_UNSIGNED_BYTE, *pointer+54);
FreeMemory(*pointer)
ProcedureReturn TextureID
EndProcedure
Procedure load_shader()
Protected filename$ ="" , t$
filename$ = OpenFileRequester("Open shader","","All|*.*",0)
If filename$ <> ""
If ReadFile(0,filename$)
shader$ = ""
While Eof(0) = 0 ; Boucle tant que la fin du fichier n'est pas atteinte. (Eof = 'End Of File')
shader$ = shader$ + ReadString(0) + Chr(10)
Wend
CloseFile(0) ; Ferme le fichier précédemment ouvert
Else
Debug "???"
EndIf
EndIf
EndProcedure
Procedure save_shader()
Protected filename$ ="" , r$ ,t$
filename$ = SaveFileRequester("Save shader", "", "", 0)
Debug filename$
Debug GetFilePart(filename$)
Debug GetPathPart(filename$)
Debug GetExtensionPart(filename$)
If filename$ <> ""
If OpenFile(0,filename$)
FileSeek(0, Lof(0))
r$ = ""
For i = 1 To Len(shader$)
t$ = Mid(shader$,i,1)
If t$ = Chr(13) Or t$ = Chr(10)
t$ = ""
WriteStringN(0,r$)
r$ = ""
Else
r$ = r$ + t$
EndIf
Next
CloseFile(0)
EndIf
EndIf
EndProcedure
;Procedure Init_Main()
System\Width.i = screen_lg
System\Height = screen_ht
System\Shader_Width = screen_lg / 2
System\Shader_Height = screen_ht
OpenWindow(#Window_Main,0,0,screen_lg,screen_ht,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
OpenGLGadget(#Gad_OpenGL,screen_lg/2,0,System\Shader_Width,System\Shader_Height,#PB_OpenGL_Keyboard)
w=System\Width - (System\Shader_Width+16)
EditorGadget(#Gad_Editor,8,30,w,System\Height-30-200)
EditorGadget(#Gad_message,8,System\Height+8-200,w,150,#PB_Editor_ReadOnly)
LoadFont(0,"consolas",10)
SetGadgetFont(#Gad_Editor,FontID(0))
SetGadgetFont(#Gad_message,FontID(0))
ButtonGadget(#run,5 ,0,90,24,"run [F5]")
ButtonGadget(#save,105 ,0,90,24,"save")
ButtonGadget(#load,205 ,0,90,24,"load")
ButtonGadget(#savecb,305 ,0,90,24,"save clipboard")
ButtonGadget(#loadcb,405 ,0,90,24,"load clipboard")
ButtonGadget(#exit,505 ,0,90,24,"exit [ESC]")
;ButtonGadget(#test,605 ,0,90,24,"test")
AddKeyboardShortcut(#Window_Main, #PB_Shortcut_F5, 1111)
AddKeyboardShortcut(#Window_Main, #PB_Shortcut_Escape, 1112)
System\App_StartTime = ElapsedMilliseconds()
System\Shader_Vertex_Text = "#version 330"+Chr(10)
System\Shader_Vertex_Text + "in vec3 position;"+Chr(10)
System\Shader_Vertex_Text + " void main() {"+Chr(10)
System\Shader_Vertex_Text + " gl_Position = vec4( position, 1.0 );"+Chr(10)
System\Shader_Vertex_Text + " };"+Chr(10)
;EndProcedure
;Init_Main()
;{ Opengl shader setup & routines
#GL_VERTEX_SHADER = $8B31
#GL_FRAGMENT_SHADER = $8B30
;{ OpenGL
; https://www.purebasic.fr/english/viewtopic.php?p=576628#p576628
#GL_VERTEX_SHADER = $8B31
#GL_FRAGMENT_SHADER = $8B30
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
ImportC "-framework OpenGL"
glCreateShader(type.l) As "_glCreateShader"
glCreateProgram() As "_glCreateProgram"
glDeleteShader(shader.l) As "_glDeleteShader"
glCompileShader(shader.l) As "_glCompileShader"
glLinkProgram(shader.l) As "_glLinkProgram"
glUseProgram(shader.l) As "_glUseProgram"
glAttachShader(Program.l, shader.l) As "_glAttachShader"
glShaderSource(shader.l, numOfStrings.l, *strings, *lenOfStrings) As "_glShaderSource"
glGetUniformLocation(Program.i, name.p-ascii) As "_glGetUniformLocation"
glUniform1i(location.i, v0.i) As "_glUniform1i"
glUniform2i(location.i, v0.i, v1.i) As "_glUniform2i"
glUniform1f(location.i, v0.f) As "_glUniform1f"
glUniform1d(location.i, v0.d) As "_glUniform1d"
glUniform2f(location.i, v0.f, v1.f) As "_glUniform2f"
glUniform2d(location.i, v0.d, v1.d) As "_glUniform2d"
glGetShaderInfoLog(shader.i, bufSize.l, *length_l, *infoLog) As "_glGetShaderInfoLog"
EndImport
CompilerElseIf #PB_Compiler_OS = #PB_OS_Linux
ImportC "/usr/lib/x86_64-linux-gnu/libGL.so"
glCreateShader(type.l)
glCreateProgram()
glDeleteShader(shader.l)
glCompileShader(shader.l)
glLinkProgram(shader.l)
glUseProgram(shader.l)
glAttachShader(Program.l, shader.l)
glShaderSource(shader.l, numOfStrings.l, *strings, *lenOfStrings) :
glGetUniformLocation(Program.i, name.p-ascii)
glUniform1i(location.i, v0.i)
glUniform2i(location.i, v0.i, v1.i)
glUniform1f(location.i, v0.f)
glUniform1d(location.i, v0.d)
glUniform2f(location.i, v0.f, v1.f)
glUniform2d(location.i, v0.d, v1.d)
glGetShaderInfoLog(shader.i, bufSize.l, *length_l, *infoLog)
EndImport
CompilerElseIf #PB_Compiler_OS = #PB_OS_Windows
Prototype glCreateShader(type.l)
Prototype glCreateProgram()
Prototype glDeleteShader(shader.l)
Prototype glCompileShader(shader.l)
Prototype glLinkProgram(shader.l)
Prototype glUseProgram(shader.l)
Prototype glAttachShader(Program.l, shader.l)
Prototype glShaderSource(shader.l, numOfStrings.l, *strings, *lenOfStrings) :
Prototype glGetUniformLocation(Program.i, name.p-ascii)
Prototype glUniform1i(location.i, v0.i)
Prototype glUniform2i(location.i, v0.i, v1.i)
Prototype glUniform1f(location.i, v0.f)
Prototype glUniform1d(location.i, v0.d)
Prototype glUniform2f(location.i, v0.f, v1.f)
Prototype glUniform2d(location.i, v0.d, v1.d)
Prototype glGetShaderInfoLog(shader.i, bufSize.l, *length_l, *infoLog)
Global glCreateShader.glCreateShader = wglGetProcAddress_("glCreateShader")
Global glCreateProgram.glCreateProgram = wglGetProcAddress_("glCreateProgram")
Global glDeleteShader.glDeleteShader = wglGetProcAddress_("glDeleteShader")
Global glCompileShader.glCompileShader = wglGetProcAddress_("glCompileShader")
Global glLinkProgram.glLinkProgram = wglGetProcAddress_("glLinkProgram")
Global glUseProgram.glUseProgram = wglGetProcAddress_("glUseProgram")
Global glAttachShader.glAttachShader = wglGetProcAddress_("glAttachShader")
Global glShaderSource.glShaderSource = wglGetProcAddress_("glShaderSource")
Global glGetUniformLocation.glGetUniformLocation = wglGetProcAddress_("glGetUniformLocation")
Global glUniform1i.glUniform1i = wglGetProcAddress_("glUniform1i")
Global glUniform2i.glUniform2i = wglGetProcAddress_("glUniform2i")
Global glUniform1f.glUniform1f = wglGetProcAddress_("glUniform1f")
Global glUniform1d.glUniform1d = wglGetProcAddress_("glUniform1d")
Global glUniform2f.glUniform2f = wglGetProcAddress_("glUniform2f")
Global glUniform2d.glUniform2d = wglGetProcAddress_("glUniform2d")
Global glGetShaderInfoLog.glGetShaderInfoLog = wglGetProcAddress_("glGetShaderInfoLog")
CompilerEndIf
;}
Procedure Shader_Compile_Link_Use(Vertex.s,Fragment.s,Use.i=1)
Protected VertShader.i, FragShader.i, *TxtPointer, Program.i
Protected Textlength.i, Mytext.s = Space(1024)
;/ Compile Vertex shader
VertShader.i = glCreateShader(#GL_VERTEX_SHADER)
*TxtPointer = Ascii(Vertex)
glShaderSource(VertShader, 1, @*TxtPointer, #Null)
glCompileShader(VertShader)
glGetShaderInfoLog(VertShader,1023,@Textlength,@Mytext)
;/ Compile Fragment Shader
FragShader.i = glCreateShader(#GL_FRAGMENT_SHADER)
*TxtPointer = Ascii(Fragment)
glShaderSource(FragShader, 1, @*TxtPointer, #Null)
glCompileShader(FragShader)
glGetShaderInfoLog(FragShader,1023,@Textlength,@Mytext)
SetGadgetText(#Gad_message, PeekS(@Mytext,1023,#PB_Ascii))
;/ Create Shader Program
Program = glCreateProgram()
glAttachShader(Program,VertShader)
glAttachShader(Program,FragShader)
glLinkProgram(Program)
If Use = 1 : glUseProgram(Program) : EndIf
ProcedureReturn Program
EndProcedure
;}
Procedure Shader_Set()
If System\Shader_Program <> 0 :glUseProgram(0) : EndIf ;/ delete the previous shaders
System\Shader_Fragment_Text = shader$
System\Shader_Program = Shader_Compile_Link_Use(System\Shader_Vertex_Text,System\Shader_Fragment_Text)
If System\Shader_Program = 0
MessageRequester("Unsupported Device?","No Shader Support Available",#PB_MessageRequester_Ok)
End
EndIf
;/ store shader uniform locations
System\Shader_Uniform_Time = glGetUniformLocation(System\Shader_Program, "time")
System\Shader_Uniform_Mouse = glGetUniformLocation(System\Shader_Program, "mouse")
System\Shader_Uniform_Resolution = glGetUniformLocation(System\Shader_Program, "resolution")
System\Shader_Uniform_SurfacePosition.i = glGetUniformLocation(System\Shader_Program, "surfacePosition")
SetGadgetText(#Gad_Editor,shader$)
EndProcedure
Procedure Render()
;/ set shader Uniform values
glUniform2f(System\Shader_Uniform_Resolution,System\Shader_Width,System\Shader_Height)
glUniform1f(System\Shader_Uniform_Time,(System\App_CurrentTime-System\App_StartTime) / 1000.0)
glUniform2f(System\Shader_Uniform_Mouse,0.0+System\MouseX / System\Shader_Width,0.0+(System\Shader_Height-System\MouseY) / System\Shader_Height)
glUniform2i(System\Shader_Uniform_SurfacePosition.i,1.0,1.0)
glBegin_(#GL_QUADS)
glVertex2f_(-1,-1)
glVertex2f_( 1,-1)
glVertex2f_( 1, 1)
glVertex2f_(-1, 1)
glEnd_()
System\Frames + 1
If System\App_CurrentTime > System\FPS_Timer
System\FPS = System\Frames
System\Frames = 0
System\FPS_Timer = System\App_CurrentTime + 1000
SetWindowTitle(#Window_Main,"GLSL Testing - PJ 07/06/2014 - FPS: "+Str(System\FPS))
EndIf
SetGadgetAttribute(#Gad_OpenGL,#PB_OpenGL_FlipBuffers,1)
EndProcedure
shader$="#version 130%%uniform float time;%uniform vec2 mouse;%uniform vec2 resolution;%%void main( void ) {% vec2 position = gl_FragCoord.xy;% vec2 center = mouse*resolution;% float r=distance(position,center);% float d=1000/r;% float v = mod(time+d,1);% gl_FragColor = vec4(v, 1-v, d/10, 1.0);%}"
;shader$="#version 130%%uniform float time;%uniform vec2 mouse;%uniform vec2 resolution;%%vec3 palette(float t) {% vec3 a = vec3(0.5,0.5,0.5);% vec3 b = vec3(0.5,0.5,0.5);% vec3 c = vec3(1.0,1.0,1.0);% vec3 d = vec3(0.00, 0.33, 0.67);% % return a + b*cos( 6.28318*(c*t+d));%}%%void main( void ) {% vec3 final = vec3(0.0);% vec2 nres = (gl_FragCoord.xy / resolution-mouse) * 2;% nres.x *= resolution.x / resolution.y;% vec2 nres0 = nres;% for (float i = 0.0; i < 4.0; i++){% nres = fract(nres * 1.5) - 0.5;% float d = length(nres) * exp(-length(nres0));% vec3 col = palette(length(nres0) + i * .4 + time * .4);% d = sin(d * 10.0 + time)/10.0;% d = abs(d);% d = pow(0.01 / d, 1.2);% final += col*d;% }% gl_FragColor = vec4(final,1.0);%}%"
shader$=ReplaceString(shader$,"%",#CRLF$)
SetGadgetText(#Gad_Editor,shader$)
Shader_Set()
Repeat
Repeat
System\Event = WindowEvent()
Select System\Event
Case #PB_Event_CloseWindow
System\Exit = #True
Case #PB_Event_Menu
Select EventMenu()
Case 1111:shader$ = GetGadgetText(#Gad_Editor):Shader_Set()
Case 1112:End
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case #run
shader$ = GetGadgetText(#Gad_Editor)
Shader_Set()
Case #load
load_shader()
Shader_Set()
Case #save
save_shader()
Case #loadcb
SetGadgetText(#Gad_Editor,GetClipboardText())
Case #savecb
shader$=GetGadgetText(#Gad_Editor)
shader$=ReplaceString(shader$,#CRLF$,"%")
SetClipboardText(shader$)
Case #exit
End
Case #test
Case #Gad_OpenGL
Select EventType()
Case #PB_EventType_MouseMove
System\MouseX = GetGadgetAttribute(#Gad_OpenGL,#PB_OpenGL_MouseX)
System\MouseY = GetGadgetAttribute(#Gad_OpenGL,#PB_OpenGL_MouseY)
EndSelect
EndSelect
EndSelect
Until System\Event = 0
System\App_CurrentTime = ElapsedMilliseconds()
Render()
Until System\Exit
End