How to make a GLSL fragment shader follow a vertex shader

Just starting out? Need help? Post your questions and find answers here.
User avatar
seangriffin
New User
New User
Posts: 8
Joined: Wed Jun 28, 2017 3:53 pm

How to make a GLSL fragment shader follow a vertex shader

Post by seangriffin »

Gudday PureBasic community!

This is my first post after joining the forums and purchasing PureBasic. So exciting :D

Let me quickly ask my question to not waste your time. My code below displays a OpenGL GLSL shader inside a box. If you use the arrow keys on the keyboard the box moves but the shader remains fixed at the center of the window.

I'm wanting to make this shader pattern move with the box and arrow keys.

This is a modified version of applePi's code over here -> http://www.purebasic.fr/english/viewtop ... 3&start=30. Look at the bottom of that page for his work. He is nicely able to move both his triangle shape and shader together with the arrow keys.

I am aware that my fragment shader code below has a static reference inside it of 800 x 600 pixels. Most likely this is what's causing the shader pattern to remain fixed at one point. But my knowledge of shaders is poor and I can't work out how to modify the shader code to make this move with the arrow keys.

By the way, I've taken this shader code from here -> http://glslsandbox.com/e#41187.0

The fragment shader doesn't look too complex to me so I'm hoping this isn't a hard question for someone with shader knowledge.

Thanks community!

Code: Select all

#GL_ARRAY_BUFFER = $8892
#GL_STATIC_DRAW = $88E4
#GL_VERTEX_SHADER = $8B31
#GL_FRAGMENT_SHADER = $8B30

Declare.s LoadFile(FileName.s)

Structure TVertex
  x.f
  y.f
  z.f
EndStructure


Structure Colors
  r.f
  g.f
  b.f
EndStructure


Dim matrix.f(3,3)
matrix(0,0)=1:   matrix(0,1)=0:matrix(0,2)=0:matrix(0,3)=0 ;// first column
matrix(1,0)=0:   matrix(1,1)=1:matrix(1,2)=0:matrix(1,3)=0 ;// second column
matrix(2,0)=0:   matrix(2,1)=0:matrix(2,2)=1:matrix(2,3)=0 ; // third column
matrix(3,0)=0: matrix(3,1)=0:matrix(3,2)=0:matrix(3,3)=2 ;// fourth column

;the above is the simulation of this:
;GLfloat matrix[] = {
;      1.0f, 0.0f, 0.0f, 0.0f, // first column
;      0.0f, 1.0f, 0.0f, 0.0f, // second column
;      0.0f, 0.0f, 1.0f, 0.0f, // third column
;      -0.5f, 0.0f, 0.0f, 2.0f // fourth column
;   };

OpenWindow(0, 10, 10, 800, 600, "OpenGL demo ... color and translation with shader... use arrow keys and A/Z to translate in 3D space")
SetWindowColor(0, RGB(200,220,200))
OpenGLGadget(0, 20, 10, WindowWidth(0)-40 , WindowHeight(0)-20, #PB_OpenGL_Keyboard)

IncludeFile "newFunctions.pbi"


Global points_vbo.i, colors_vbo.i, vao.i
Dim Vertex.TVertex(3)
Vertex(0)\x = -0.5
Vertex(0)\y = 0.5
Vertex(0)\z = 0

Vertex(1)\x = 0.5
Vertex(1)\y = 0.5
Vertex(1)\z = 0

Vertex(2)\x = 0.5
Vertex(2)\y = -0.5
Vertex(2)\z = 0

Vertex(3)\x = -0.5
Vertex(3)\y = -0.5
Vertex(3)\z = 0

Define vertex_shader.s
Define fragment_shader.s
Define *vbuff


vertex_shader = "#version 420"+#CRLF$
vertex_shader + "layout(location = 0) in vec3 vertex_position;"+#CRLF$
vertex_shader + "uniform mat4 matrix; // our matrix"+#CRLF$
vertex_shader + "void main() {"+#CRLF$
vertex_shader + "gl_Position = matrix * vec4(vertex_position, 1.0);"+#CRLF$
vertex_shader + "}"

fragment_shader = "precision highp float;"+#CRLF$
fragment_shader + "uniform mat4 matrix;"+#CRLF$
fragment_shader + ""+#CRLF$
fragment_shader + "float ball(vec2 p) {"+#CRLF$
fragment_shader + "    vec2 r = vec2(p.x , p.y);"+#CRLF$	
fragment_shader + "    return 0.05 / length(r);"+#CRLF$
fragment_shader + "}"+#CRLF$
fragment_shader + "void main(void) {"+#CRLF$
fragment_shader + "    vec2 resolution = vec2(800 , 600);	"+#CRLF$
fragment_shader + "    vec2 q = vec2(gl_FragCoord.x,gl_FragCoord.y) / vec2(resolution.x,resolution.y);"+#CRLF$
fragment_shader + "    vec2 p = -0.5 + q;	"+#CRLF$
fragment_shader + "    p.x	*= resolution.x / resolution.y;"+#CRLF$
fragment_shader + "    float col = 0.0;"+#CRLF$
fragment_shader + "    col += ball(p);"+#CRLF$
fragment_shader + "    col = max(mod(col, 0.4), min(col, 2.0));"+#CRLF$
fragment_shader + "    gl_FragColor = vec4(col * 0.8, col * 0.3, col * 0.3, 1.0);"+#CRLF$
fragment_shader + "}"+#CRLF$
    
;*vbuff = @vertex_shader
;*fbuff = @fragment_shader

*vbuff = Ascii(vertex_shader)
*fbuff = Ascii(fragment_shader)
   
glEnable_(#GL_DEPTH_TEST); // enable depth-testing
;glDepthFunc_(#GL_LESS); // depth-testing interprets a smaller value as "closer"

Global points_vbo.i, colors_vbo.i, vao.i

;=================================================================================
glGenBuffers( 1, @points_vbo ) ; Vertex Buffer Object
glBindBuffer(#GL_ARRAY_BUFFER, points_vbo )
glBufferData(#GL_ARRAY_BUFFER,12 * SizeOf(float),@Vertex(0), #GL_STATIC_DRAW)


glGenVertexArrays (1, @vao);
glBindVertexArray (vao);
glBindBuffer (#GL_ARRAY_BUFFER, points_vbo);
glVertexAttribPointer (0, 3, #GL_FLOAT, #GL_FALSE, 0, #Null);
;ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
glEnableVertexAttribArray(0);
;=================================================================================

Global vs = glCreateShader(#GL_VERTEX_SHADER);
glShaderSource(vs, 1, @*vbuff, #Null) ;
glCompileShader(vs);
Global fs = glCreateShader(#GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, @*fbuff, #Null);
glCompileShader(fs)                          ;

Global shader_programme = glCreateProgram();
glAttachShader(shader_programme, fs);
glAttachShader(shader_programme, vs);
glLinkProgram(shader_programme)     ;


glEnable_(#GL_CULL_FACE); // cull face
   glCullFace_(#GL_BACK); // cull back face
   glFrontFace_(#GL_CW); // GL_CCW for counter clock-wise
   
   rot.f = 1   
   SetActiveGadget(0)
   Repeat
    
     Event = WaitWindowEvent()
     If Event = #PB_Event_Gadget And EventGadget() = 0
   If EventType() = #PB_EventType_KeyDown
     
            key = GetGadgetAttribute(0,#PB_OpenGL_Key )
            ;If key = 38 ; Up arrow key
            If key = #PB_Shortcut_Up
               matrix(3,1) + 0.1
               
               ElseIf key = #PB_Shortcut_Down ; Down arrow key 
                 matrix(3,1) - 0.1
               ElseIf key = #PB_Shortcut_Left ; Left arrow key
                 matrix(3,0) - 0.1
               ElseIf key = #PB_Shortcut_Right ; Left arrow key
                 matrix(3,0) + 0.1
               ElseIf key = #PB_Shortcut_A ; Left arrow key
                 matrix(3,3) - 0.1
               ElseIf key = #PB_Shortcut_Z ; Left arrow key
                 matrix(3,3) + 0.1     
            ElseIf key = #PB_Shortcut_Escape ;  Esc key to exit

             quit = 1
            EndIf 
     EndIf
   EndIf 
   
    
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT);
  glRotatef_(rot, 0, 1, 0)                             ;
  matrix_location.l = glGetUniformLocation(shader_programme, "matrix");
   glUseProgram (shader_programme);
   glUniformMatrix4fv (matrix_location, 1, #GL_FALSE, @matrix(0,0));
   
   glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT);
   glViewport_(0, 0, 800, 600)                          ;
   
   glUseProgram(shader_programme) 
   
  glBindVertexArray(vao);
   
  ;draw points 0-3 from the currently bound VAO With current in-use shader
  ;glDrawArrays(#GL_TRIANGLES, 0, 3);
  glDrawArrays(#GL_QUADS, 0, 4);
   
  SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
  Delay(16)
 
Until Event = #PB_Event_CloseWindow Or quit = 1

Procedure.s LoadFile(FileName.s)
  Protected FF, Format, length, *mem, Text.s
  FF = ReadFile(#PB_Any, FileName)
  If FF
    Format = ReadStringFormat(FF)
    length = Lof(FF)
    If length
      *mem = AllocateMemory(length)
      If *mem
        ReadData(FF, *mem, length)
        Text = PeekS(*mem, length, Format)
        FreeMemory(*mem)
        CloseFile(FF)
        ProcedureReturn Text
      EndIf
    EndIf
    CloseFile(FF)
  EndIf
EndProcedure
newFunctions.pbi ...

Code: Select all

Prototype PFNGLGENBUFFERSPROC ( n.i, *buffers)
Global glGenBuffers.PFNGLGENBUFFERSPROC
glGenBuffers = wglGetProcAddress_( "glGenBuffers" )
Prototype PFNGLBINDBUFFERPROC ( target.l, buffer.i)
Global glBindBuffer.PFNGLBINDBUFFERPROC
glBindBuffer = wglGetProcAddress_( "glBindBuffer" )
Prototype PFNGLBUFFERDATAPROC ( target.l, size.i, *Data_, usage.l)
Global glBufferData.PFNGLBUFFERDATAPROC
glBufferData = wglGetProcAddress_( "glBufferData" )

Prototype PFNGLGENVERTEXARRAYSPROC (n.i, *arrays)
Global glGenVertexArrays.PFNGLGENVERTEXARRAYSPROC
glGenVertexArrays = wglGetProcAddress_( "glGenVertexArrays" )

Prototype PFNGLBINDVERTEXARRAYPROC(n.i)
Global glBindVertexArray.PFNGLBINDVERTEXARRAYPROC
glBindVertexArray = wglGetProcAddress_( "glBindVertexArray" )

Prototype PFNGLENABLEVERTEXATTRIBARRAYPROC ( index.i )
Global glEnableVertexAttribArray.PFNGLENABLEVERTEXATTRIBARRAYPROC
glEnableVertexAttribArray = wglGetProcAddress_( "glEnableVertexAttribArray" )

Prototype PFNGLVERTEXATTRIBPOINTERPROC ( index.i, size.i, type.l, normalized.b, stride.i, *pointer )
Global glVertexAttribPointer.PFNGLVERTEXATTRIBPOINTERPROC
glVertexAttribPointer = wglGetProcAddress_( "glVertexAttribPointer" )

Prototype.i PFNGLCREATESHADERPROC ( type.l )
Global glCreateShader.PFNGLCREATESHADERPROC
glCreateShader = wglGetProcAddress_( "glCreateShader" )


Prototype PFNGLSHADERSOURCEPROC ( shader.i, count.i, *stringBuffer, *length )
Global glShaderSource.PFNGLSHADERSOURCEPROC
glShaderSource = wglGetProcAddress_( "glShaderSource" )


Prototype PFNGLCOMPILESHADERPROC ( shader.i )
Global glCompileShader.PFNGLCOMPILESHADERPROC
glCompileShader = wglGetProcAddress_( "glCompileShader" )


Prototype PFNGLATTACHSHADERPROC ( program.i, shader.i )
Global glAttachShader.PFNGLATTACHSHADERPROC
glAttachShader = wglGetProcAddress_( "glAttachShader" )


Prototype PFNGLLINKPROGRAMPROC ( program.i )
Global glLinkProgram.PFNGLLINKPROGRAMPROC
glLinkProgram = wglGetProcAddress_( "glLinkProgram" )

Prototype.i PFNGLCREATEPROGRAMPROC ( )
Global glCreateProgram.PFNGLCREATEPROGRAMPROC
glCreateProgram = wglGetProcAddress_( "glCreateProgram" )

Prototype PFNGLUSEPROGRAMPROC ( program.i )
Global glUseProgram.PFNGLUSEPROGRAMPROC
glUseProgram = wglGetProcAddress_( "glUseProgram" )

Prototype PFNGLDRAWARRAYSPROC ( mode.l, first.i, count.i )
Global glDrawArrays.PFNGLDRAWARRAYSPROC
glDrawArrays = wglGetProcAddress_( "glDrawArrays" )

Prototype PFNGLGETUNIFORMLOCATIONPROC ( program.i, name.p-ascii )
Global glGetUniformLocation.PFNGLGETUNIFORMLOCATIONPROC
glGetUniformLocation = wglGetProcAddress_( "glGetUniformLocation" )

Prototype PFNGLUNIFORMMATRIX4FVPROC ( location.i, count.i, transpose.b, *value )
Global glUniformMatrix4fv.PFNGLUNIFORMMATRIX4FVPROC
glUniformMatrix4fv = wglGetProcAddress_( "glUniformMatrix4fv" )
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: How to make a GLSL fragment shader follow a vertex shade

Post by djes »

Welcome seangriffin ! :D
User avatar
seangriffin
New User
New User
Posts: 8
Joined: Wed Jun 28, 2017 3:53 pm

Re: How to make a GLSL fragment shader follow a vertex shade

Post by seangriffin »

djes wrote:Welcome seangriffin ! :D
Thanks djes! I'm looking to develop some physics related code. I began my journey several weeks ago in AutoIT, which is my all time favourite language, but sadly being an interpreted language it's just not suitable for a real-time physics engine. I needed another language that was as close to the performance of C for graphics, yet easy to script in, because I don't enjoy writing low-level code. So I transitioned next to FreeBasic, but found I couldn't make my static and dynamic libraries work there no matter how hard I tried. I brought my code to PureBasic and it worked perfectly. I tried the embedded graphics in PureBasic but again it wasn't up to speed. I've resorted to working directly against OpenGL now. Performance is fantastic, but I'm really getting my hands dirtier than I expected.

I'm on a steep learning curve with OpenGL. I actually learned a lot more about the design of shaders today. I think I may have solved my question above. I'm looking to render many primitive shapes in OpenGL. These are particles in the physics engine. I'm currently doing so through standard OpenGL primitives but now I'm considering shaders as a more visually appealing format. Today I've discovered that rather than shading hundreds of primitives individually in OpenGL I'll get a far better effect (with blending / blurring / etc) if I shade all my particles in the one single shader / primitive that's the size of the entire window. Possibly this is going to kill the performance of my app, but I need to investigate. I'll publish my findings once I get there.
User avatar
blueb
Addict
Addict
Posts: 1116
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

Re: How to make a GLSL fragment shader follow a vertex shade

Post by blueb »

Check out some good work done by Luis.. :)

A little dated, but might give you some help.

http://www.purebasic.fr/english/viewtop ... 34#p211034
- It was too lonely at the top.

System : PB 6.21(x64) and Win 11 Pro (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
User avatar
seangriffin
New User
New User
Posts: 8
Joined: Wed Jun 28, 2017 3:53 pm

Re: How to make a GLSL fragment shader follow a vertex shade

Post by seangriffin »

Great blueb! I haven't yet seen that topic and I'll definitely look into it.

The most interesting topic I've found so far for OpenGL shaders is this one -> http://www.purebasic.fr/english/viewtop ... 36&t=62179. pjay presents his demo of shaders and everyone falls in love with it. And I see pjay's code replicated in most shader topics in the forums and well as in other discussion groups. It must be very good, yet I am unable to get it to work :( I have performed all the mentioned adjustments to his code in pages 2 and 3 of the topic, and yet I end up with just a black screen. I tried playing around with his script without really understanding much about how it works and couldn't for the life of me get it to work. Tried it in PB v5.60 and 5.44. The last post is applePi stating that he got it working in PB 5.5, as recent as October 2016. Maybe I should post a question to that topic? I'm keen to know exactly how people are managing to run pjay's code.
User avatar
blueb
Addict
Addict
Posts: 1116
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

Re: How to make a GLSL fragment shader follow a vertex shade

Post by blueb »

Since you are new here, I sent you a PM (Private Message)

To check your messages... see the top right of your screen.

Blueb
- It was too lonely at the top.

System : PB 6.21(x64) and Win 11 Pro (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: How to make a GLSL fragment shader follow a vertex shade

Post by Samuel »

seangriffin wrote: I am aware that my fragment shader code below has a static reference inside it of 800 x 600 pixels. Most likely this is what's causing the shader pattern to remain fixed at one point. But my knowledge of shaders is poor and I can't work out how to modify the shader code to make this move with the arrow keys.

Code: Select all

vertex_shader = "#version 420"+#CRLF$
vertex_shader + "layout(location = 0) in vec3 vertex_position;"+#CRLF$
vertex_shader + "uniform mat4 matrix; // our matrix"+#CRLF$
vertex_shader + "void main() {"+#CRLF$
vertex_shader + "gl_Position = matrix * vec4(vertex_position, 1.0);"+#CRLF$
vertex_shader + "}"

fragment_shader = "precision highp float;"+#CRLF$
fragment_shader + "uniform mat4 matrix;"+#CRLF$
fragment_shader + ""+#CRLF$
fragment_shader + "float ball(vec2 p) {"+#CRLF$
fragment_shader + "    vec2 r = vec2(p.x , p.y);"+#CRLF$	
fragment_shader + "    return 0.05 / length(r);"+#CRLF$
fragment_shader + "}"+#CRLF$
fragment_shader + "void main(void) {"+#CRLF$
fragment_shader + "    vec2 resolution = vec2(800 , 600);	"+#CRLF$
fragment_shader + "    vec2 q = vec2(gl_FragCoord.x,gl_FragCoord.y) / vec2(resolution.x,resolution.y);"+#CRLF$
fragment_shader + "    vec2 p = -0.5 + q;	"+#CRLF$
fragment_shader + "    p.x	*= resolution.x / resolution.y;"+#CRLF$
fragment_shader + "    float col = 0.0;"+#CRLF$
fragment_shader + "    col += ball(p);"+#CRLF$
fragment_shader + "    col = max(mod(col, 0.4), min(col, 2.0));"+#CRLF$
fragment_shader + "    gl_FragColor = vec4(col * 0.8, col * 0.3, col * 0.3, 1.0);"+#CRLF$
fragment_shader + "}"+#CRLF$
Welcome to the forums!

I haven't gotten around to trying your code, but at first glance I've noticed a few things.

I believe the precision qualifier at the top of the fragment shader is for GLSL ES only. In PB you're using plain GLSL.
Also, I notice you're loading a mat4 matrix into the fragment shader, but then you are not using it anywhere within the fragment shader. This matrix seems to be a model (also known as world) matrix which is mainly used to move object vertices. Which is usually done in the vertex shader portion of the pipeline. In this case, I don't see a use for it in the fragment shader.

In order to move the shader effect, I believe you'll want to move the UV coordinates which are stored in gl_FragCoord. Editing the coordinates would be the slower way though. In my opinion, It would be better to send a vec2 value to the shader containing the offsets of the X and Y axis which then can be applied to the UV coordinates.
User avatar
seangriffin
New User
New User
Posts: 8
Joined: Wed Jun 28, 2017 3:53 pm

Re: How to make a GLSL fragment shader follow a vertex shade

Post by seangriffin »

So happy to get a reply from you Samuel! I've been studying your work in the forums and I'm amazed. It's an honour actually to hear from you. Thank you so much for your time. I've spent many hours surfing and absorbing your knowledge of OpenGL in the forums and it's been fantastic.

Your reply is spot on. I realised not long after posting this that my question was dumb :-( Due to my lack of knowledge of OpenGL. In the past few days I've learned a lot more about OpenGL. What I was doing here was not my goal. I'll explain a bit more. I was looking to render hundreds of OpenGL elements / primitives with a metaball type effect for particles. I'd already solved the code for particles as primitives in OpenGL and PureBasic. I was lacking the metaball effect. I wasn't trying to achieve anything too fancy. I just wanted the cheapest computational solution possible that gave the appearance of the particles blobbing together. I found most OpenGL metaball discussions on the internet were providing shaders solutions. With my poor understanding of OpenGL I assumed this was the best and fastest approach for a cheap metaball effect. Then I discovered the GLSL Sandbox and some metaball style shaders there. This is how my code above came about.

My goal became to somehow get hundred of particles rendering in the fragment shaders. I've actually achieved this now. I borrowed that code above from another post from ApplePi that worked for me, and it had the matrix inside it for a different purpose. i was actually looking for a full screen shader (such as in a fullscreen quad), and as in the GLSL Sandbox, and then render my particles in that and somehow control them. I actually got this working by using uniform arrays to pass my array of particle vectors into the fragment shader, then in a for loop in the shader I render every particle. Simple stuff, and small and efficient code, but it certainly was too computationally expensive on the entire window I discovered (and that was my fear all along).

My current understanding of fragment shaders is they iterate over every pixel within the primitive the shader as attached to. Because I was running my shader on a full windowed quad I believe the shader code is running against every pixel in my window (800 x 600 pixels), plus there the for loop of hundreds of particles / vectors looping in the shader code. While this actually worked for me, it was too slow of course. In the GLSL Sandbox I replicated that same shader code and for loop and found the same performance bottleneck there, confirming this behaviour. It's all a learning experience for me, and the lesson I learned is that shaders are expensive. I recall several people mentioning this in discussion groups, perhaps yourself included, but now I understand first hand.

I'm happy to post my solution here, but the performance is quite embarrasingly bad. Maybe it will serve as a good use case for others who thinks that implementing a particle engine in shaders is a good idea. If anyone is interested let me know and I'll post it. For now I'm abandoning this approach.

Good news is I've learned a lot more about "blending" now in OpenGL. And through OpenGL primitives, vertex arrays and blending I now have my metaball effect running thousands of particles at 60 frames per second, all in PureBasic code. Extremely happy and exactly what I was looking for. I'm going to publish my code soon in another topic. To my knowledge there isn't any good demonstration of a particle system in the PB forums yet.

Samuel in one of your posts you commented that there seems to be a lack of knowledge of OpenGL implementation in PureBasic at the moment. I agree with you, and it's quite a hit-and-miss affair with the code I've seen. I can appreciate PureBasic has probably been evolving continuously too over many, many years and everyone might be trying to keep up with that. I wish I'd arrived on this scene years ago.

PureBasic is satisfying two of my needs right now. A fast runtime (compiled) language for real-time graphics that's also as close to a scripting language as possible. I'm getting a lot of success now with OpenGL in PB so you should see more demos from me very soon.
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: How to make a GLSL fragment shader follow a vertex shade

Post by Samuel »

Your particle example sounds interesting. I look forward to seeing it.
seangriffin wrote: To my knowledge there isn't any good demonstration of a particle system in the PB forums yet.
I don't recall ever seeing any examples excluding the few that use PB's internal particle system.
seangriffin wrote: I'm getting a lot of success now with OpenGL in PB so you should see more demos from me very soon.
Glad to hear this. If you ever have any questions just holler.
User avatar
seangriffin
New User
New User
Posts: 8
Joined: Wed Jun 28, 2017 3:53 pm

Re: How to make a GLSL fragment shader follow a vertex shade

Post by seangriffin »

Well my particle physics library for PureBasic is now available, for those who might be interested.

Check out this topic -> http://www.purebasic.fr/english/viewtop ... 27&t=68874

My knowledge of PureBasic and OpenGL has come a long way since posting the above. :P Thanks again for everyone's warm support. Loving the PB community already!

Cheers,

Sean.
Post Reply