Julia Set (shader)

Discussions related to graphics (2D and 3D), animation and games programming
Richard Russell
Posts: 591
Joined: Tue 18 Jun 2024, 09:32

Re: Julia Set (shader)

Post by Richard Russell »

Richard Russell wrote: Tue 27 Jan 2026, 11:13 I think the only place it could sensibly go would be in the documentation of the SYS statement.
I have added a note there.
DDRM
Posts: 33
Joined: Mon 17 Jun 2024, 08:02

Re: Julia Set (shader)

Post by DDRM »

Thanks, Richard. I'll try to remember!

Best wishes,

D
Richard Russell
Posts: 591
Joined: Tue 18 Jun 2024, 09:32

Re: Julia Set (shader)

Post by Richard Russell »

Richard Russell wrote: Tue 27 Jan 2026, 11:13 Given that you used the Float{} structure, which holds two numbers, I'm surprised that you didn't send both cr and ci together to the shader (as a two-component vector)
Just to demonstrate that it works, here's a version which does that. I've also added a test for BB4W so that setting the window title works on that platform as well, since you seem to think that's important (perhaps I should have provided a *TITLE command to do it in a universal way).

Code: Select all

      MODE 9
      REM MODE 9 is 640 x 512 pixels, or 1280 x 1024 graphics units
      xres%=1280
      yres%=1024
      INSTALL @lib$ + "shaderlib"
      DIM Vertex$(10), Fragment$(20),Float{0%,1%}
      PROC_readshader(Vertex$())
      PROC_readshader(Fragment$())

      PROC_shaderinit(oVertex%, oFragment%)
      PROC_compileshader(oVertex%, Vertex$(), "Vertex")
      PROC_compileshader(oFragment%, Fragment$(), "Fragment")
      oProgram% = FN_useshaders(oVertex%, oFragment%)

      REM Here we store the locations of our shader variables ("uniforms")
      SYS `glGetUniformLocation`, oProgram%, "pt", @memhdc% TO pPoint%%

      REPEAT
        REM We get the mouse coordinates, and check it's in the window area
        REM (That way we know the calculated start point will lie within (-2 to 2,-1.25 to 1.25) )
        REM Though I think the shader actually only shows the area (-1.5 to 1.5, -1 to 1)?
        MOUSE px%,py%,pz%
        IF px%>0 AND px%<xres% AND py%>0 AND py%<yres% THEN
          REM Scale the mouse X coordinate into the required space. Not sure why it needs to go into a structure...
          Float.0% = FN_f4(4*px%/xres% - 3)
          Float.1% = FN_f4(2.5*py%/yres% - 1.25)
          SYS `glUniform2fv`, pPoint%%, 1, Float{}, @memhdc%
          title$ = STR$(4*px%/1280 - 2) + CHR$9 + CHR$9 + STR$(4*py%/1024 - 1.25)
          IF INKEY$(-256) = "W" THEN
            SYS "SetWindowText", @hwnd%, title$
          ELSE
            SYS "SDL_SetWindowTitle", @hwnd%, title$, @memhdc%
          ENDIF
        ENDIF

        PROC_render
        WAIT 2
      UNTIL FALSE
      END

      REM Vertex shader:
      DATA "attribute vec4 vPosition;"
      DATA "void main()"
      DATA "{"
      DATA "gl_Position = vPosition;"
      DATA "}"
      DATA ""

      REM Fragment shader:
      REM We'll define two parameters pt.x and pt.y, being
      REM the real and imaginary parts of the start location
      DATA "uniform vec2 pt;"

      DATA "void main()"
      DATA "{"
      DATA "float v;"
      DATA "float zr = gl_FragCoord.x  * 3.0 / 639.0 - 1.5;"
      DATA "float zi = gl_FragCoord.y * 2.0 / 511.0  - 1.0;"
      DATA "for( int i = 0; i <= 510; i++ )"
      DATA " {"
      DATA " v = float(i) / 512.0;"
      DATA " float zn = (zr + zi) * (zr - zi) + pt.x;"
      DATA " zi = 2.0 * zr * zi + pt.y; zr = zn;"
      DATA " if ((zr * zr + zi * zi) > 3.0) break;"
      DATA " }"
      DATA "gl_FragColor = vec4(sqrt(v), v, v*v, 1.0 );"
      DATA "}"
      DATA ""