[solved] Can you post your FPS result please ?

General discussion for topics related to the FreeBASIC project or its community.
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: Can you post your FPS result please ?

Post by srvaldez »

Gold Box

Code: Select all

dim as string SCODE

SCODE &= !"float T = iGlobalTime; \n"
SCODE &= !"vec3 LIGHT = vec3(cos(T)-1.0,sin(T),cos(T*0.5))*8.0-vec3(T*16.0,0,0); \n"
SCODE &= !" \n"
SCODE &= !"float MAX = 120.0; \n"
SCODE &= !"float PRE = 0.01; \n"
SCODE &= !"//1D Noise Function \n"
SCODE &= !"float n1(vec3 p) \n"
SCODE &= !"{ \n"
SCODE &= !" 	return fract(cos(dot(floor(p),vec3(17,51,43)))*2736.38);  \n"
SCODE &= !"} \n"
SCODE &= !"//Mapping Function \n"
SCODE &= !"vec3 map(vec3 p, float s) \n"
SCODE &= !"{ \n"
SCODE &= !"    vec3 S = vec3(8); \n"
SCODE &= !"    vec3 A = mod(p+s/2.0,s)-s/2.0; \n"
SCODE &= !"    //vec3 B = max(abs(p)-S,0.0) * sign(p-S); \n"
SCODE &= !"    return A; \n"
SCODE &= !"} \n"
SCODE &= !"//Main Distance Field Function \n"
SCODE &= !"float model(vec3 p) \n"
SCODE &= !"{    \n"
SCODE &= !"    float S = -1.0; \n"
SCODE &= !"    for(int i = 0;i<7;i++) \n"
SCODE &= !"    { \n"
SCODE &= !"        float I = exp2(float(i)); \n"
SCODE &= !"        S = max(S,I/4.0-length(max(abs(map(p,I))-I/8.0,0.0))); \n"
SCODE &= !"    } \n"
SCODE &= !"    return S;//max(S,length(max(abs(p)-8.0,0.0))); \n"
SCODE &= !"} \n"
SCODE &= !"//Normal Function \n"
SCODE &= !"vec3 normal(vec3 p) \n"
SCODE &= !"{ \n"
SCODE &= !" 	vec2 N = vec2(-1, 1) * PRE; \n"
SCODE &= !" \n"
SCODE &= !" 	return normalize(model(p+N.xyy)*N.xyy+model(p+N.yxy)*N.yxy+ \n"
SCODE &= !"                     model(p+N.yyx)*N.yyx+model(p+N.xxx)*N.xxx); \n"
SCODE &= !"} \n"
SCODE &= !"//Simple Raymarcher \n"
SCODE &= !"vec4 raymarch(vec3 p, vec3 d) \n"
SCODE &= !"{ \n"
SCODE &= !"    float S = 0.0; \n"
SCODE &= !"    float T = S; \n"
SCODE &= !"    vec3 D = normalize(d); \n"
SCODE &= !"    vec3 P = p+D*S; \n"
SCODE &= !"    for(int i = 0;i<240;i++) \n"
SCODE &= !"    { \n"
SCODE &= !"        S = model(P); \n"
SCODE &= !"        T += S; \n"
SCODE &= !"        P += D*S; \n"
SCODE &= !"        if ((T>MAX) || (S<PRE)) {break;} \n"
SCODE &= !"    } \n"
SCODE &= !"    return vec4(P,min(T/MAX,1.0)); \n"
SCODE &= !"} \n"
SCODE &= !"//Color/Material Function \n"
SCODE &= !"vec3 color1(vec3 p, vec3 n) \n"
SCODE &= !"{ \n"
SCODE &= !" 	vec3 C = vec3(1,0.8,0.4)*(0.8+0.2*n1(p/2.0)); \n"
SCODE &= !"    vec3 D = normalize(LIGHT-p); \n"
SCODE &= !" 	float L = smoothstep(-3.0,0.0,model(p+D)-model(p-D*0.5)-model(p-D)-model(p-D*2.0)); \n"
SCODE &= !"          L *= max(dot(n,D),-0.5)*0.5+0.5; \n"
SCODE &= !"    	  L *= exp2(1.0-length(LIGHT-p)/16.0); \n"
SCODE &= !"     \n"
SCODE &= !"    return C*L; \n"
SCODE &= !"} \n"
SCODE &= !"vec3 color2(vec3 p, vec3 d) \n"
SCODE &= !"{ \n"
SCODE &= !"    vec3 N = normal(p); \n"
SCODE &= !"    vec3 C = color1(p,N);     \n"
SCODE &= !"     \n"
SCODE &= !"    float A = exp2(1.0-length(LIGHT-p)/16.0); \n"
SCODE &= !"    float R = (1.0-abs(dot(N,d))); \n"
SCODE &= !"    vec3 D = reflect(d,N); \n"
SCODE &= !"    return C * mix(vec3(1),color1(p+D,N),R)+pow(max(dot(D,N),0.0),64.0+64.0*n1(p))*A; \n"
SCODE &= !"} \n"
SCODE &= !"//Camera Variables \n"
SCODE &= !"void camera(out vec3 P,out vec3 D, out vec3 X, out vec3 Y, out vec3 Z) \n"
SCODE &= !"{ \n"
SCODE &= !"	float M = float((iMouse.x+iMouse.y)>0.0); \n"
SCODE &= !"	vec2 A = (0.5-iMouse.xy/iResolution.xy)*vec2(6.2831,3.1416); \n"
SCODE &= !"    vec3 F = mix(vec3(1,0,0),vec3(cos(-A.x)*cos(A.y),sin(-A.x)*cos(A.y),sin(A.y)),M); \n"
SCODE &= !"	P = vec3(-T*16.0,0,0)+24.0*F; \n"
SCODE &= !" \n"
SCODE &= !"	D = -F; \n"
SCODE &= !" \n"
SCODE &= !"	X = normalize(D); \n"
SCODE &= !"	Y = normalize(cross(X,vec3(0.0,0.0,1.0))); \n"
SCODE &= !"	Z = cross(X,Y); \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"void mainImage( out vec4 fragColor, in vec2 fragCoord ) \n"
SCODE &= !"{ \n"
SCODE &= !"    vec3 P,D,X,Y,Z; \n"
SCODE &= !"    camera(P,D,X,Y,Z); \n"
SCODE &= !"	vec2 UV = (fragCoord.xy-iResolution.xy*0.5)/iResolution.y; \n"
SCODE &= !"    D = normalize(mat3(X,Y,Z) * vec3(1.0,UV)); \n"
SCODE &= !"     \n"
SCODE &= !"    vec4 M = raymarch(P,D); \n"
SCODE &= !"    vec3 COL = vec3(0.01,0.01,0.01)+max(color2(M.xyz,D)*sqrt(1.-M.w),0.0); \n"
SCODE &= !"    COL += exp2(-length(cross(D,LIGHT-P))); \n"
SCODE &= !"	fragColor = vec4(COL,0); \n"
SCODE &= !"} \n"


#include once "fbgfx.bi"
#include once "GL/gl.bi"
#include once "GL/glext.bi"

#ifndef NULL
#define NULL 0
#endif


type vec3
  as GLfloat x,y,z
end type

sub ErrorExit(msg as string)
  if screenptr() then screen 0
  dim as integer w,h
  screeninfo w,h : w*=0.75:h*=0.75
  screenres w,h
  print msg
  print "press any key to quit ..."
  beep : sleep : end 1
end sub

' define OpenGL proc's
#define glDefine(n) dim shared as PFN##n##PROC n
' texture
'glDefine(glActiveTexture)
' shader
glDefine(glCreateShader)
glDefine(glDeleteShader)
glDefine(glShaderSource)
glDefine(glCompileShader)
glDefine(glGetShaderiv)
glDefine(glGetShaderInfoLog)
' program
glDefine(glCreateProgram)
glDefine(glDeleteProgram)
glDefine(glAttachShader)
glDefine(glDetachShader)
glDefine(glLinkProgram)
glDefine(glGetProgramiv)
glDefine(glGetProgramInfoLog)
glDefine(glUseProgram)
' uniform
glDefine(glGetUniformLocation)
glDefine(glUniform1f)
glDefine(glUniform2f)
glDefine(glUniform3f)
glDefine(glUniform4f)
glDefine(glUniform1i)
#undef glDefine

sub glScreen(w as integer=640, h as integer=360, b as integer=32, d as integer=24, s as integer=0, f as integer=0)
  if ScreenPtr() then screen 0
  ScreenControl FB.SET_GL_STENCIL_BITS,s
  ScreenControl FB.SET_GL_DEPTH_BITS  ,d
  if ScreenRes(w,h,b,,FB.GFX_OPENGL or iif(f<>0,FB.GFX_FULLSCREEN,0)) then
    ErrorExit("screenres(" & w & "," & h &") failed !")
  end if
  Windowtitle "offline shadertoy.com"

  flip
  ' get OpenGL proc's (abort if something goes wrong)
  #define glProc(n) n = ScreenGLProc(#n) : if n = 0 then ErrorExit(#n)
  ' texture
  'glProc(glActiveTexture)
  ' shader
  glProc(glCreateShader)
  glProc(glDeleteShader)
  glProc(glShaderSource)
  glProc(glCompileShader)
  glProc(glGetShaderiv)
  glProc(glGetShaderInfoLog)
  ' program
  glProc(glCreateProgram)
  glProc(glDeleteProgram)
  glProc(glAttachShader)
  glProc(glDetachShader)
  glProc(glLinkProgram)
  glProc(glGetProgramiv)
  glProc(glGetProgramInfoLog)
  glProc(glUseProgram)
  ' uniform
  glProc(glGetUniformLocation)
  glProc(glUniform1f)
  glProc(glUniform2f)
  glProc(glUniform3f)
  glProc(glUniform4f)
  glProc(glUniform1i)
  #undef glProc
end sub

type ShaderToy
  declare destructor
  declare function CompileFile(Filename as string) as boolean
  declare function CompileCode(Code as string) as boolean
  as GLuint FragmentShader
  as GLuint ProgramObject
  as string Shaderlog
end type
destructor ShaderToy
  if ProgramObject then 
   glUseprogram(0)
   if FragmentShader  then 
     glDetachShader(ProgramObject,FragmentShader)
     glDeleteShader(FragmentShader)
   end if
   glDeleteProgram(ProgramObject)
  end if
end destructor

function ShaderToy.CompileFile(filename as string) as boolean
  dim as string code
  var hFile = FreeFile()
  if open(filename,for input, as #hFile) then 
    ShaderLog = "can't read shader: " & chr(34) & filename  & chr(34) & " !"
    return false
  end if
  while not eof(hFile)
    dim as string aLine
    line input #hFile,aLine
    code &= aLine & !"\n"
  wend
  close #hFile
  return CompileCode(code)
end function

function ShaderToy.CompileCode(UserCode as string) as boolean
  dim as GLint logSize
  dim as GLint status
  dim as string FragmentProlog
  FragmentProlog & =!"uniform float     iGlobalTime;  // shader playback time (in seconds)\n"
  FragmentProlog & =!"uniform vec3      iResolution;  // viewport resolution (in pixels)\n"
  FragmentProlog & =!"uniform vec4      iMouse;       // mouse pixel coords. xy: current (if MLB down), zw: click\n"
  FragmentProlog & =!"uniform vec4      iDate;        // (year, month, day, time in seconds)\n"
  FragmentProlog & =!"uniform sampler2D iChannel0;\n"
  FragmentProlog & =!"uniform sampler2D iChannel1;\n"
  FragmentProlog & =!"uniform sampler2D iChannel2;\n"
  FragmentProlog & =!"uniform sampler2D iChannel3;\n"
  dim as string FragmentEpilog
  FragmentEpilog &= !"void main() {\n"
  FragmentEpilog &= !"  vec4 color;\n"
  FragmentEpilog &= !"  // call user shader\n"
  FragmentEpilog &= !"  mainImage(color, gl_FragCoord.xy);\n"
  FragmentEpilog &= !"  color.w = 1.0;\n"
  FragmentEpilog &= !"  gl_FragColor = color;\n"
  FragmentEpilog &= !"}\n"

  dim as string FragmentCode = FragmentProlog & UserCode & FragmentEpilog

  FragmentShader = glCreateShader(GL_FRAGMENT_SHADER)
  if FragmentShader=0 then 
    ShaderLog = "glCreateShader(GL_FRAGMENT_SHADER) failed !"
    return false
  end if
  dim as GLchar ptr pCode=strptr(FragmentCode)
  glShaderSource (FragmentShader, 1, @pCode, NULL)
  glCompileShader(FragmentShader)
  glGetShaderiv  (FragmentShader, GL_COMPILE_STATUS, @status)
  if status = GL_FALSE then 
    glGetShaderiv(FragmentShader, GL_INFO_LOG_LENGTH, @logSize)
    ShaderLog = space(logSize)
    glGetShaderInfoLog(FragmentShader, logSize, NULL, cptr(GLchar ptr,strptr(ShaderLog)) )
    ShaderLog = !"glCompileShader(FragmentShader) failed !\n" & Shaderlog
    glDeleteShader(FragmentShader) : FragmentShader = 0
    return false
  end if

  ProgramObject = glCreateProgram()
  if ProgramObject=0 then 
    ShaderLog = "glCreateProgram() failed !"
    glDeleteShader(FragmentShader) : FragmentShader = 0
    return false
  end if
  glAttachShader(ProgramObject,FragmentShader)
  glLinkProgram (ProgramObject)
  glGetProgramiv(ProgramObject, GL_LINK_STATUS, @status)
  if (status = GL_FALSE) then
    glGetProgramiv(ProgramObject, GL_INFO_LOG_LENGTH, @logSize)
    ShaderLog = space(logSize)
    glGetProgramInfoLog (ProgramObject, logSize, NULL, cptr(GLchar ptr,strptr(ShaderLog)) )
    ShaderLog = !"glLinkProgram() failed !\n" & Shaderlog
    glDeleteShader(FragmentShader) : FragmentShader = 0
    return false
  end if
  return true
end function

'
' main
'


' init Screenres, create the OpenGL context and load some OpenGL procs.
dim as integer pixels=640
' wide screen 16:9
glScreen pixels,pixels/16*9


' get curent resolution
dim as integer scr_w,scr_h
screeninfo scr_w,scr_h

dim as vec3 v3
v3.x=scr_w     ' width in pixle
v3.y=scr_h     '`height in pixle
v3.z=v3.x/v3.y ' pixel ratio

dim as ShaderToy Shader

if Shader.CompileCode(SCODE)=false then
  ErrorExit Shader.ShaderLog
end if  

' enable shader
glUseProgram(Shader.ProgramObject)

' get uniforms locations in shader program
var iGlobalTime = glGetUniformLocation(Shader.ProgramObject,"iGlobalTime")
var iResolution = glGetUniformLocation(Shader.ProgramObject,"iResolution")
var iMouse      = glGetUniformLocation(Shader.ProgramObject,"iMouse")

' set vec3 iResolution
glUniform3f(iResolution,v3.x,v3.y,v3.z)

dim as integer mx,my,mb,frames,fps
dim as double tStart = Timer()
dim as double tLast=tStart
while inkey=""
  dim as double tNow=Timer()
  ' set uniform float iGlobalTime
  glUniform1f(iGlobalTime,tNow-tStart)
/'
  if frames mod 3=0 then
    ' set vec4 iMouse
    if getMouse(mx,my,,mb)=0 then
      if mb then
        glUniform4f(iResolution,mx,scr_h-my,1,1)
      else
        glUniform4f(iResolution,0,0,0,0)
      end if
    end if
  end if
'/

  'glClear(GL_COLOR_BUFFER_BIT)

  ' draw a rectangle (2 triangles over the whole screen)
  glRectf(-1,-1,1,1)
  flip ' swap the buffers

  frames+=1
  ' update fps
  if frames mod 24=0 then
    fps=24/(tNow-tLast)
    windowtitle "fps: " & fps
    tLast=tNow
  end if

wend

' disable shader
glUseProgram(0)
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: Can you post your FPS result please ?

Post by srvaldez »

iq's school of terrain
I get about 31 to 60 fps on my Mac

Code: Select all

dim as string SCODE
SCODE &= !"/** \n"
SCODE &= !" * Created by revers - 2016 \n"
SCODE &= !" * \n"
SCODE &= !" * Licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. \n"
SCODE &= !" * \n"
SCODE &= !" * This shader is based on iq's brilliant ""Elevated"" (https://www.shadertoy.com/view/MdX3Rr),  \n"
SCODE &= !" * but I've used my own terrain heightmap (without derivatives), added water and own version of clouds. \n"
SCODE &= !" * I've also tried to use own texture patterns.  \n"
SCODE &= !" * The rest of code is created by iq. Notably: hash and noise functions, raymarching, great outdoors lighting \n"
SCODE &= !" * (see also http://iquilezles.org/www/articles/outdoorslighting/outdoorslighting.htm ) \n"
SCODE &= !" *  \n"
SCODE &= !" * It is great pleasure to learn from the best. Thanks for sharing your code, iq! \n"
SCODE &= !" *  \n"
SCODE &= !" * The shader was created and exported from Synthclipse (http://synthclipse.sourceforge.net/) \n"
SCODE &= !" */ \n"
SCODE &= !" \n"
SCODE &= !"const vec3 LightDir = vec3(0.15037532, -0.31434754, -0.93732226); \n"
SCODE &= !"const float MarchDumping = 0.39999998; \n"
SCODE &= !"const float Far = 864.20496; \n"
SCODE &= !"const int MaxSteps = 156; \n"
SCODE &= !"const vec2 PulseSize = vec2(431.0138, 311.53772); \n"
SCODE &= !"const float PulseHeight = 111.24439; \n"
SCODE &= !"const float PulseProbability = 0.6; \n"
SCODE &= !"const float MaxTerrainMul = 60.88; \n"
SCODE &= !"const float MinTerrainMul = 0.0; \n"
SCODE &= !"const float TerrainPower = 0.85950005; \n"
SCODE &= !"const float TerrainHeightMul = 1.838; \n"
SCODE &= !"const float WaterLevel = -9.119999; \n"
SCODE &= !"const float WaterWaveHeight = 0.24681002; \n"
SCODE &= !"const float WaterMaxVisibleDepth = 12.8991; \n"
SCODE &= !"const vec3 WaterColor = vec3(0.007843138, 0.0627451, 0.09019608); \n"
SCODE &= !"const float NormalFactor = 0.399; \n"
SCODE &= !" \n"
SCODE &= !"#define TIME_SHIFT 30.0 \n"
SCODE &= !" \n"
SCODE &= !"#define M_NONE -1.0 \n"
SCODE &= !"#define M_TERRAIN 1.0 \n"
SCODE &= !"#define M_WATER 3.0 \n"
SCODE &= !" \n"
SCODE &= !"vec3 lig = vec3(0.0, -1.0, 0.0); \n"
SCODE &= !"float TerrainParam = 0.0; \n"
SCODE &= !" \n"
SCODE &= !"float hash(vec2 n) { \n"
SCODE &= !"	return fract(sin(dot(n, vec2(1.0, 113.0))) * 43758.5453123); \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"/** \n"
SCODE &= !" * From ""Hash-without-Sine"" by Dave Hoskins \n"
SCODE &= !" * https://www.shadertoy.com/view/4djSRW \n"
SCODE &= !" */ \n"
SCODE &= !"vec2 hash22(vec2 p) { \n"
SCODE &= !"	p = fract(p * vec2(5.3983, 5.4427)); \n"
SCODE &= !"	p += dot(p.yx, p.xy + vec2(21.5351, 14.3137)); \n"
SCODE &= !"	return fract(vec2(p.x * p.y * 95.4337, p.x * p.y * 97.597)); \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"float noise(vec2 p) { \n"
SCODE &= !"	vec2 i = floor(p); \n"
SCODE &= !"	vec2 f = fract(p); \n"
SCODE &= !" \n"
SCODE &= !"	vec2 u = f * f * (3.0 - 2.0 * f); \n"
SCODE &= !" \n"
SCODE &= !"	vec2 a = vec2(0.0, 0.0); \n"
SCODE &= !"	vec2 b = vec2(1.0, 0.0); \n"
SCODE &= !"	vec2 c = vec2(0.0, 1.0); \n"
SCODE &= !"	vec2 d = vec2(1.0, 1.0); \n"
SCODE &= !" \n"
SCODE &= !"	float n0 = hash(i + a); \n"
SCODE &= !"	float n1 = hash(i + b); \n"
SCODE &= !"	float n2 = hash(i + c); \n"
SCODE &= !"	float n3 = hash(i + d); \n"
SCODE &= !" \n"
SCODE &= !"	float ix0 = mix(n0, n1, u.x); \n"
SCODE &= !"	float ix1 = mix(n2, n3, u.x); \n"
SCODE &= !" \n"
SCODE &= !"	return mix(ix0, ix1, u.y); \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"vec2 min2(vec2 a, vec2 b) { \n"
SCODE &= !"	return a.x < b.x ? a : b; \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"/** \n"
SCODE &= !" * http://iquilezles.org/www/articles/functions/functions.htm \n"
SCODE &= !" */ \n"
SCODE &= !"float cubicPulse(float w, float x) { \n"
SCODE &= !"	x = abs(x); \n"
SCODE &= !"	if (x > w) \n"
SCODE &= !"		return 0.0; \n"
SCODE &= !"	x /= w; \n"
SCODE &= !"	return 1.0 - x * x * (3.0 - 2.0 * x); \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"float pulse(vec2 p) { \n"
SCODE &= !"	vec2 q = mod(p, 2.0 * PulseSize) - PulseSize; \n"
SCODE &= !"	vec2 id = floor(p / (2.0 * PulseSize)); \n"
SCODE &= !" \n"
SCODE &= !"	vec2 r2 = hash22(id); \n"
SCODE &= !"	float r = step(PulseProbability, r2.x) * step(PulseProbability, r2.y); \n"
SCODE &= !" \n"
SCODE &= !"	float h = cubicPulse(PulseSize.x, q.x) * cubicPulse(PulseSize.y, q.y) * PulseHeight; \n"
SCODE &= !"	return mix(h, 0.0, r); \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"float fbmL(vec2 p, float baseAmplitude) { \n"
SCODE &= !"	float f = 0.0; \n"
SCODE &= !"	float a = baseAmplitude; \n"
SCODE &= !"	for (int i = 0; i < 2; i++) { \n"
SCODE &= !"		f += a * noise(p); \n"
SCODE &= !"		p *= 2.0; \n"
SCODE &= !"		a *= 0.5; \n"
SCODE &= !"	} \n"
SCODE &= !"	return f; \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"float fbmM(vec2 p, float baseAmplitude) { \n"
SCODE &= !"	float f = 0.0; \n"
SCODE &= !"	float a = baseAmplitude; \n"
SCODE &= !"	for (int i = 0; i < 4; i++) { \n"
SCODE &= !"		f += a * noise(p); \n"
SCODE &= !"		p *= 2.0; \n"
SCODE &= !"		a *= 0.5; \n"
SCODE &= !"	} \n"
SCODE &= !"	return f; \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"float fbmH(vec2 p, float baseAmplitude) { \n"
SCODE &= !"	float f = 0.0; \n"
SCODE &= !"	float a = baseAmplitude; \n"
SCODE &= !"	for (int i = 0; i < 7; i++) { \n"
SCODE &= !"		f += a * noise(p); \n"
SCODE &= !"		p *= 2.0; \n"
SCODE &= !"		a *= 0.5; \n"
SCODE &= !"	} \n"
SCODE &= !"	return f; \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"float hole(vec2 p) { \n"
SCODE &= !"	float f = noise(p); \n"
SCODE &= !"	p *= 2.01; \n"
SCODE &= !"	f += 0.5 * noise(p); \n"
SCODE &= !"	p *= 2.02; \n"
SCODE &= !"	f += 0.25 * noise(p); \n"
SCODE &= !"	p *= 2.00; \n"
SCODE &= !"	f += 0.125 * noise(p); \n"
SCODE &= !" \n"
SCODE &= !"	return f; \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"float terrainL(vec2 p) { \n"
SCODE &= !"	vec2 g = vec2(0.01, 0.012); \n"
SCODE &= !"	vec2 q = p * g; \n"
SCODE &= !" \n"
SCODE &= !"	float a = 0.5; \n"
SCODE &= !"	float f0 = noise(q); \n"
SCODE &= !"	a *= 0.5; \n"
SCODE &= !"	q *= 2.0; \n"
SCODE &= !" \n"
SCODE &= !"	float f = fbmL(q, a); \n"
SCODE &= !"	float t = smoothstep(0.5, 1.0, TerrainParam); \n"
SCODE &= !"	f = pow(f, TerrainPower + t * 2.0); \n"
SCODE &= !" \n"
SCODE &= !"	float k = smoothstep(TerrainParam, 1.0, f0); \n"
SCODE &= !"	float res = mix(f * MinTerrainMul, f * MaxTerrainMul, k) * TerrainHeightMul; \n"
SCODE &= !" \n"
SCODE &= !"	float m = smoothstep(0.0, 0.4, k); \n"
SCODE &= !"	res = mix(res - hole(q) * 12.0, res, m); \n"
SCODE &= !" \n"
SCODE &= !"	res += pulse(p) * fbmM(p * 0.01 + 452.15, 0.5); \n"
SCODE &= !"	return res; \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"float terrainM(vec2 p) { \n"
SCODE &= !"	vec2 g = vec2(0.01, 0.012); \n"
SCODE &= !"	vec2 q = p * g; \n"
SCODE &= !" \n"
SCODE &= !"	float a = 0.5; \n"
SCODE &= !"	float f0 = noise(q); \n"
SCODE &= !"	a *= 0.5; \n"
SCODE &= !"	q *= 2.0; \n"
SCODE &= !" \n"
SCODE &= !"	float f = fbmM(q, a); \n"
SCODE &= !"	float t = smoothstep(0.5, 1.0, TerrainParam); \n"
SCODE &= !"	f = pow(f, TerrainPower + t * 2.0); \n"
SCODE &= !" \n"
SCODE &= !"	float k = smoothstep(TerrainParam, 1.0, f0); \n"
SCODE &= !"	float res = mix(f * MinTerrainMul, f * MaxTerrainMul, k) * TerrainHeightMul; \n"
SCODE &= !" \n"
SCODE &= !"	float m = smoothstep(0.0, 0.4, k); \n"
SCODE &= !"	res = mix(res - hole(q) * 12.0, res, m); \n"
SCODE &= !" \n"
SCODE &= !"	res += pulse(p) * fbmM(p * 0.01 + 452.15, 0.5); \n"
SCODE &= !"	return res; \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"float terrainH(vec2 p) { \n"
SCODE &= !"	vec2 g = vec2(0.01, 0.012); \n"
SCODE &= !"	vec2 q = p * g; \n"
SCODE &= !" \n"
SCODE &= !"	float a = 0.5; \n"
SCODE &= !"	float f0 = noise(q); \n"
SCODE &= !"	a *= 0.5; \n"
SCODE &= !"	q *= 2.0; \n"
SCODE &= !" \n"
SCODE &= !"	float f = fbmH(q, a); \n"
SCODE &= !"	float t = smoothstep(0.5, 1.0, TerrainParam); \n"
SCODE &= !"	f = pow(f, TerrainPower + t * 2.0); \n"
SCODE &= !" \n"
SCODE &= !"	float k = smoothstep(TerrainParam, 1.0, f0); \n"
SCODE &= !"	float res = mix(f * MinTerrainMul, f * MaxTerrainMul, k) * TerrainHeightMul; \n"
SCODE &= !" \n"
SCODE &= !"	float m = smoothstep(0.0, 0.4, k); \n"
SCODE &= !"	res = mix(res - hole(q) * 12.0, res, m); \n"
SCODE &= !" \n"
SCODE &= !"	res += pulse(p) * fbmH(p * 0.01 + 333452.15, 0.5); \n"
SCODE &= !"	return res; \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"vec2 map(vec3 p) { \n"
SCODE &= !"	vec2 res = vec2(p.y - terrainM(p.xz), M_TERRAIN); \n"
SCODE &= !"	return res; \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"vec2 castRay(vec3 ro, vec3 rd) { \n"
SCODE &= !"	float tmin = 0.0; \n"
SCODE &= !"	float tmax = Far; \n"
SCODE &= !" \n"
SCODE &= !"	float precis = 0.002; \n"
SCODE &= !"	float t = tmin; \n"
SCODE &= !"	float m = -1.0; \n"
SCODE &= !" \n"
SCODE &= !"	for (int i = 0; i < MaxSteps; i++) { \n"
SCODE &= !"		vec2 res = map(ro + rd * t); \n"
SCODE &= !"		if (res.x < precis || t > tmax) { \n"
SCODE &= !"			break; \n"
SCODE &= !"		} \n"
SCODE &= !"		t += res.x * MarchDumping; \n"
SCODE &= !"		m = res.y; \n"
SCODE &= !"	} \n"
SCODE &= !"	if (t > tmax) { \n"
SCODE &= !"		m = -1.0; \n"
SCODE &= !"	} \n"
SCODE &= !"	return vec2(t, m); \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"float softshadow(vec3 ro, vec3 rd, float mint, float tmax) { \n"
SCODE &= !"	float res = 1.0; \n"
SCODE &= !"	float t = mint; \n"
SCODE &= !" \n"
SCODE &= !"	for (int i = 0; i < 16; i++) { \n"
SCODE &= !"		float h = map(ro + rd * t).x; \n"
SCODE &= !" \n"
SCODE &= !"		res = min(res, 8.0 * h / t); \n"
SCODE &= !"		t += clamp(h, 0.02, 0.10); \n"
SCODE &= !" \n"
SCODE &= !"		if (h < 0.001 || t > tmax) { \n"
SCODE &= !"			break; \n"
SCODE &= !"		} \n"
SCODE &= !"	} \n"
SCODE &= !"	return clamp(res, 0.0, 1.0); \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"vec3 calcNormal(vec3 pos) { \n"
SCODE &= !"	float t = 0.1; \n"
SCODE &= !"	vec2 eps = vec2(0.02 * t, 0.0); \n"
SCODE &= !" \n"
SCODE &= !"	return normalize( \n"
SCODE &= !"			vec3(terrainH(pos.xz - eps.xy) - terrainH(pos.xz + eps.xy), \n"
SCODE &= !"					2.0 * eps.x, \n"
SCODE &= !"					terrainH(pos.xz - eps.yx) - terrainH(pos.xz + eps.yx))); \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"#define lodbias -100.0 \n"
SCODE &= !" \n"
SCODE &= !"vec4 texcube(sampler2D sam, vec3 p, vec3 n) { \n"
SCODE &= !"	vec4 x = texture2D(sam, p.yz, lodbias); \n"
SCODE &= !"	vec4 y = texture2D(sam, p.zx, lodbias); \n"
SCODE &= !"	vec4 z = texture2D(sam, p.xy, lodbias); \n"
SCODE &= !"	return x * abs(n.x) + y * abs(n.y) + z * abs(n.z); \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"float water(vec2 q) { \n"
SCODE &= !"	float f; \n"
SCODE &= !"	f = 0.5000 * noise(q); \n"
SCODE &= !"	q = q * 2.02; \n"
SCODE &= !"	f += 0.2500 * noise(q); \n"
SCODE &= !"	q -= iGlobalTime * 0.3; \n"
SCODE &= !"	q = q * 2.03; \n"
SCODE &= !"	f += 0.1250 * noise(q); \n"
SCODE &= !"	q -= iGlobalTime * 2.0; \n"
SCODE &= !"	q = q * 2.01; \n"
SCODE &= !"	f += 0.0625 * noise(q); \n"
SCODE &= !" \n"
SCODE &= !"	return f * WaterWaveHeight; \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"vec3 waterBottomColor(vec3 ro, vec3 rd, float t) { \n"
SCODE &= !"	vec3 pos = ro + t * rd; \n"
SCODE &= !"	vec3 nor = calcNormal(pos); \n"
SCODE &= !" \n"
SCODE &= !"	vec3 bn = -1.0 + 2.0 * texcube(iChannel0, pos * 0.3, nor).xyz; \n"
SCODE &= !"	nor = normalize(nor + 0.2 * bn); \n"
SCODE &= !" \n"
SCODE &= !"	vec3 col = vec3(0.009); \n"
SCODE &= !"	float hh = smoothstep(0.0, 10.0, pos.y); \n"
SCODE &= !" \n"
SCODE &= !"	col += 2.0 * vec3(0.722, 0.396, 0.165) \n"
SCODE &= !"			* texcube(iChannel1, pos * vec3(0.1, 0.3, 0.1), nor).rgb; \n"
SCODE &= !" \n"
SCODE &= !"	float dif = max(dot(nor, lig), 0.0); \n"
SCODE &= !"	return dif * col * 0.5; \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"float clouds(vec3 ro, vec3 rd) { \n"
SCODE &= !"	vec2 uv = rd.xz / rd.y; \n"
SCODE &= !"	uv *= 70.0; \n"
SCODE &= !" \n"
SCODE &= !"	uv *= vec2(3.0, 3.0) * 0.005; \n"
SCODE &= !"	vec2 st = uv; \n"
SCODE &= !" \n"
SCODE &= !"	uv.x += iGlobalTime * 0.2; \n"
SCODE &= !" \n"
SCODE &= !"	float f = 0.5 * noise(uv); \n"
SCODE &= !"	uv *= 2.04; \n"
SCODE &= !"	f += 0.25 * noise(uv); \n"
SCODE &= !"	uv *= 2.01; \n"
SCODE &= !"	f += 0.125 * noise(uv); \n"
SCODE &= !"	float res = f; \n"
SCODE &= !"	res = smoothstep(0.4, 1.0, res); \n"
SCODE &= !" \n"
SCODE &= !"	st += vec2(12.0, 34.5); \n"
SCODE &= !"	st.x += iGlobalTime * 0.3; \n"
SCODE &= !"	float g = 0.5 * noise(st); \n"
SCODE &= !"	st *= 2.00; \n"
SCODE &= !"	g += 0.25 * noise(st); \n"
SCODE &= !"	st *= 2.03; \n"
SCODE &= !"	g += 0.125 * noise(st); \n"
SCODE &= !"	st *= 2.04; \n"
SCODE &= !"	g += 0.0625 * noise(st); \n"
SCODE &= !" \n"
SCODE &= !"	res += 0.5 * smoothstep(0.5, 0.9, g); \n"
SCODE &= !" \n"
SCODE &= !"	return res * 0.8; \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"vec3 skyColor(vec3 ro, vec3 rd) { \n"
SCODE &= !"	float sundot = max(0.0, dot(rd, lig)); \n"
SCODE &= !"	vec3 col = vec3(0.396, 0.678, 0.878) * (0.9 - 0.9 * rd.y) * 1.5; \n"
SCODE &= !"	col += pow(sundot, 120.0) * vec3(1.0, 0.937, 0.71) * 0.75; \n"
SCODE &= !" \n"
SCODE &= !"	col = mix(col, vec3(2.0), clouds(ro, rd) * rd.y); \n"
SCODE &= !"	return col; \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"#define OFFSET 10.0 \n"
SCODE &= !"#define GROUND_LEVEL_MIN (-20.0 + OFFSET) \n"
SCODE &= !"#define GROUND_LEVEL_MAX (-5.0 + OFFSET) \n"
SCODE &= !" \n"
SCODE &= !"#define GRASS_LEVEL_MIN (-5.0 + OFFSET) \n"
SCODE &= !"#define GRASS_LEVEL_MAX (25.0 + OFFSET) \n"
SCODE &= !" \n"
SCODE &= !"#define SNOW_LEVEL_MIN (20.0 + OFFSET) \n"
SCODE &= !"#define SNOW_LEVEL_MAX (60.0 + OFFSET) \n"
SCODE &= !" \n"
SCODE &= !"vec3 terrainColor(vec3 ro, vec3 rd, vec3 pos, vec3 nor) { \n"
SCODE &= !"	vec3 col = vec3(0.009); \n"
SCODE &= !" \n"
SCODE &= !"	vec3 rock = 1.0 * vec3(0.5) \n"
SCODE &= !"			* texcube(iChannel1, pos * vec3(0.1, 0.4, 0.1) * 0.2, nor).rgb; \n"
SCODE &= !"	float rockFactor = (1.0 - nor.y); \n"
SCODE &= !"	col += mix(rock, vec3(0.01), rockFactor); \n"
SCODE &= !" \n"
SCODE &= !"	float r = texture2D(iChannel0, pos.xz * 0.1).r; \n"
SCODE &= !" \n"
SCODE &= !"	vec3 ground = 0.1 * vec3(0.7, 0.4, 0.2); \n"
SCODE &= !"	float k = texture2D(iChannel0, pos.xz * 0.0005).r * 10.0; \n"
SCODE &= !"	float groundFactor = (1.0 - smoothstep(GROUND_LEVEL_MIN, GROUND_LEVEL_MAX, pos.y - k)); \n"
SCODE &= !"	col = mix(col, ground, groundFactor); \n"
SCODE &= !" \n"
SCODE &= !"	vec3 grass = 0.4 * mix(vec3(0.04, 0.3, 0.0), vec3(0.0, 0.1, 0.0), \n"
SCODE &= !"			smoothstep(0.0, 0.5, texcube(iChannel2, pos * 0.04 + r, nor).r)); \n"
SCODE &= !"	float grassFactor = (0.6 + 0.4 * r) * groundFactor; \n"
SCODE &= !"	col = mix(col, grass, grassFactor); \n"
SCODE &= !" \n"
SCODE &= !"	grass = vec3(0.02, 0.06, 0.0); \n"
SCODE &= !"	grassFactor = smoothstep(NormalFactor, 1.0, nor.y) \n"
SCODE &= !"			* (1.0 - smoothstep(GRASS_LEVEL_MIN, GRASS_LEVEL_MAX, pos.y)) \n"
SCODE &= !"			* (1.0 - groundFactor); \n"
SCODE &= !"	col = mix(col, grass, grassFactor); \n"
SCODE &= !" \n"
SCODE &= !"	vec3 snow = vec3(1.0); \n"
SCODE &= !"	float snowFactor = smoothstep(SNOW_LEVEL_MIN, SNOW_LEVEL_MAX, pos.y) \n"
SCODE &= !"			* smoothstep(0.1, 1.0, nor.y); \n"
SCODE &= !"	col = mix(col, snow, snowFactor); \n"
SCODE &= !" \n"
SCODE &= !"	return col; \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"vec3 doLighting(vec3 rd, vec3 pos, vec3 nor) { \n"
SCODE &= !"	vec3 ref = reflect(rd, nor); \n"
SCODE &= !" \n"
SCODE &= !"	float amb = clamp(0.5 + 0.5 * nor.y, 0.0, 1.0); \n"
SCODE &= !"	float dif = clamp(dot(nor, lig), 0.0, 1.0); \n"
SCODE &= !"	float bac = clamp(dot(nor, normalize(vec3(-lig.x, 0.0, -lig.z))), 0.0, \n"
SCODE &= !"			1.0) * clamp(1.0 - pos.y, 0.0, 1.0); \n"
SCODE &= !"	float dom = smoothstep(-0.1, 0.1, ref.y); \n"
SCODE &= !"	float fre = pow(clamp(1.0 + dot(nor, rd), 0.0, 1.0), 2.0); \n"
SCODE &= !"	float spe = pow(clamp(dot(ref, lig), 0.0, 1.0), 16.0); \n"
SCODE &= !" \n"
SCODE &= !"	dif *= softshadow(pos, lig, 0.02, 2.5); \n"
SCODE &= !"	dom *= softshadow(pos, ref, 0.02, 2.5); \n"
SCODE &= !" \n"
SCODE &= !"	vec3 brdf = vec3(0.0); \n"
SCODE &= !"	brdf += 1.20 * dif * vec3(1.00, 0.90, 0.60); \n"
SCODE &= !"	brdf += 1.20 * spe * vec3(1.00, 0.90, 0.60) * dif; \n"
SCODE &= !"	brdf += 0.30 * amb * vec3(0.50, 0.70, 1.00); \n"
SCODE &= !"	brdf += 0.40 * dom * vec3(0.50, 0.70, 1.00); \n"
SCODE &= !"	brdf += 0.30 * bac * vec3(0.25, 0.25, 0.25); \n"
SCODE &= !"	brdf += 0.20 * fre * vec3(1.00, 1.00, 1.00); \n"
SCODE &= !"	brdf += 0.02; \n"
SCODE &= !" \n"
SCODE &= !"	return brdf; \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"vec3 render(vec3 ro, vec3 rd) { \n"
SCODE &= !"	vec3 col = vec3(0.0); \n"
SCODE &= !" \n"
SCODE &= !"	vec2 res = castRay(ro, rd); \n"
SCODE &= !"	float t = res.x; \n"
SCODE &= !"	float m = res.y; \n"
SCODE &= !" \n"
SCODE &= !"	float wt = (WaterLevel - ro.y) / rd.y; \n"
SCODE &= !" \n"
SCODE &= !"	bool isWater = false; \n"
SCODE &= !"	float waterBlendFactor = 1.0; \n"
SCODE &= !"	vec3 bottomColor = vec3(0.0); \n"
SCODE &= !" \n"
SCODE &= !"	if (wt > 0.0 && wt < t) { \n"
SCODE &= !"		// water \n"
SCODE &= !"		float k = (t - wt) / WaterMaxVisibleDepth; \n"
SCODE &= !"		waterBlendFactor = min(k * k, 1.0); \n"
SCODE &= !"		vec3 pos = ro + wt * rd; \n"
SCODE &= !" \n"
SCODE &= !"		vec2 e = vec2(wt * 0.05, 0.0); \n"
SCODE &= !"		vec2 p = pos.xz * 2.0; \n"
SCODE &= !"		float x0 = water(p); \n"
SCODE &= !"		vec2 grad = vec2(water(p + e.xy) - x0, \n"
SCODE &= !"						 water(p + e.yx) - x0) / e.x; \n"
SCODE &= !" \n"
SCODE &= !"		vec3 nor = normalize(vec3(grad.x, 1.0, grad.y)); \n"
SCODE &= !"		bottomColor = waterBottomColor(ro, rd, t); \n"
SCODE &= !" \n"
SCODE &= !"		rd = reflect(rd, nor); \n"
SCODE &= !"		ro = pos + rd * 0.2; \n"
SCODE &= !" \n"
SCODE &= !"		res = castRay(ro, rd); \n"
SCODE &= !"		t = res.x; \n"
SCODE &= !"		m = res.y; \n"
SCODE &= !" \n"
SCODE &= !"		isWater = true; \n"
SCODE &= !"	} \n"
SCODE &= !" \n"
SCODE &= !"	if (m > M_NONE) { \n"
SCODE &= !"		vec3 pos = ro + t * rd; \n"
SCODE &= !"		vec3 nor = calcNormal(pos); \n"
SCODE &= !" \n"
SCODE &= !"		col = terrainColor(ro, rd, pos, nor); \n"
SCODE &= !"		vec3 brdf = doLighting(rd, pos, nor); \n"
SCODE &= !" \n"
SCODE &= !"		col = col * brdf; \n"
SCODE &= !" \n"
SCODE &= !"		if (isWater) { \n"
SCODE &= !"			col += bottomColor * (1.0 - waterBlendFactor); \n"
SCODE &= !"			col += WaterColor * 0.5; \n"
SCODE &= !"		} \n"
SCODE &= !"		// fog \n"
SCODE &= !"		col = mix(col, vec3(0.5), 1.0 - exp(-0.000001 * t * t)); \n"
SCODE &= !"	} else { \n"
SCODE &= !"		col = skyColor(ro, rd); \n"
SCODE &= !"		if (isWater) { \n"
SCODE &= !"			col += bottomColor * (1.0 - waterBlendFactor); \n"
SCODE &= !"			col += WaterColor * 0.1; \n"
SCODE &= !" \n"
SCODE &= !"		} \n"
SCODE &= !"	} \n"
SCODE &= !"	return vec3(clamp(col, 0.0, 1.0)); \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"vec3 camPath(float time) { \n"
SCODE &= !"	time *= 2.0; \n"
SCODE &= !"	return 1100.0 * vec3(cos(0.0 + 0.23 * time), 0.0, cos(1.5 + 0.21 * time)); \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"mat3 setCamera(vec3 ro, vec3 ta, float cr) { \n"
SCODE &= !"	vec3 cw = normalize(ta - ro); \n"
SCODE &= !"	vec3 cp = vec3(sin(cr), cos(cr), 0.0); \n"
SCODE &= !"	vec3 cu = normalize(cross(cw, cp)); \n"
SCODE &= !"	vec3 cv = normalize(cross(cu, cw)); \n"
SCODE &= !"	return mat3(cu, cv, cw); \n"
SCODE &= !"} \n"
SCODE &= !" \n"
SCODE &= !"void mainImage(out vec4 fragColor, in vec2 fragCoord) { \n"
SCODE &= !"    lig = normalize(-LightDir); \n"
SCODE &= !"    TerrainParam = (sin(iGlobalTime * 0.2 + TIME_SHIFT) * 0.5 + 0.5); \n"
SCODE &= !"     \n"
SCODE &= !"    vec2 q = fragCoord / iResolution.xy; \n"
SCODE &= !"	vec2 xy = -1.0 + 2.0 * q; \n"
SCODE &= !"	vec2 s = xy * vec2(iResolution.x / iResolution.y, 1.0); \n"
SCODE &= !" \n"
SCODE &= !"	float time = iGlobalTime * 0.15 + 0.3 + TIME_SHIFT + 4.0 * iMouse.x / iResolution.x; \n"
SCODE &= !" \n"
SCODE &= !"	vec3 ro = camPath(time); \n"
SCODE &= !"	vec3 ta = camPath(time + 3.0); \n"
SCODE &= !"	ro.y = terrainL(ro.xz) + 11.0; \n"
SCODE &= !"	ta.y = ro.y - 20.0; \n"
SCODE &= !"	float cameraRoll = 0.2 * cos(0.1 * time); \n"
SCODE &= !" \n"
SCODE &= !"	// camera2world transform \n"
SCODE &= !"	mat3 cam = setCamera(ro, ta, cameraRoll); \n"
SCODE &= !" \n"
SCODE &= !"	// camera ray \n"
SCODE &= !"	vec3 rd = cam * normalize(vec3(s.xy, 1.5)); \n"
SCODE &= !"	vec3 col = render(ro, rd); \n"
SCODE &= !" \n"
SCODE &= !"    col = pow(col, vec3(0.4545)); \n"
SCODE &= !"    col += 0.07; \n"
SCODE &= !"    // vignette \n"
SCODE &= !"	//col *= 0.25 + 0.75 * pow(16.0 * q.x * q.y * (1.0 - q.x) * (1.0 - q.y), 0.07); \n"
SCODE &= !" \n"
SCODE &= !"	fragColor = vec4(col, 1.0); \n"
SCODE &= !"} \n"


#include once "fbgfx.bi"
#include once "GL/gl.bi"
#include once "GL/glext.bi"

#ifndef NULL
#define NULL 0
#endif


type vec3
  as GLfloat x,y,z
end type

sub ErrorExit(msg as string)
  if screenptr() then screen 0
  dim as integer w,h
  screeninfo w,h : w*=0.75:h*=0.75
  screenres w,h
  print msg
  print "press any key to quit ..."
  beep : sleep : end 1
end sub

' define OpenGL proc's
#define glDefine(n) dim shared as PFN##n##PROC n
' texture
'glDefine(glActiveTexture)
' shader
glDefine(glCreateShader)
glDefine(glDeleteShader)
glDefine(glShaderSource)
glDefine(glCompileShader)
glDefine(glGetShaderiv)
glDefine(glGetShaderInfoLog)
' program
glDefine(glCreateProgram)
glDefine(glDeleteProgram)
glDefine(glAttachShader)
glDefine(glDetachShader)
glDefine(glLinkProgram)
glDefine(glGetProgramiv)
glDefine(glGetProgramInfoLog)
glDefine(glUseProgram)
' uniform
glDefine(glGetUniformLocation)
glDefine(glUniform1f)
glDefine(glUniform2f)
glDefine(glUniform3f)
glDefine(glUniform4f)
glDefine(glUniform1i)
#undef glDefine

sub glScreen(w as integer=640, h as integer=360, b as integer=32, d as integer=24, s as integer=0, f as integer=0)
  if ScreenPtr() then screen 0
  ScreenControl FB.SET_GL_STENCIL_BITS,s
  ScreenControl FB.SET_GL_DEPTH_BITS  ,d
  if ScreenRes(w,h,b,,FB.GFX_OPENGL or iif(f<>0,FB.GFX_FULLSCREEN,0)) then
    ErrorExit("screenres(" & w & "," & h &") failed !")
  end if
  Windowtitle "offline shadertoy.com"

  flip
  ' get OpenGL proc's (abort if something goes wrong)
  #define glProc(n) n = ScreenGLProc(#n) : if n = 0 then ErrorExit(#n)
  ' texture
  'glProc(glActiveTexture)
  ' shader
  glProc(glCreateShader)
  glProc(glDeleteShader)
  glProc(glShaderSource)
  glProc(glCompileShader)
  glProc(glGetShaderiv)
  glProc(glGetShaderInfoLog)
  ' program
  glProc(glCreateProgram)
  glProc(glDeleteProgram)
  glProc(glAttachShader)
  glProc(glDetachShader)
  glProc(glLinkProgram)
  glProc(glGetProgramiv)
  glProc(glGetProgramInfoLog)
  glProc(glUseProgram)
  ' uniform
  glProc(glGetUniformLocation)
  glProc(glUniform1f)
  glProc(glUniform2f)
  glProc(glUniform3f)
  glProc(glUniform4f)
  glProc(glUniform1i)
  #undef glProc
end sub

type ShaderToy
  declare destructor
  declare function CompileFile(Filename as string) as boolean
  declare function CompileCode(Code as string) as boolean
  as GLuint FragmentShader
  as GLuint ProgramObject
  as string Shaderlog
end type
destructor ShaderToy
  if ProgramObject then 
   glUseprogram(0)
   if FragmentShader  then 
     glDetachShader(ProgramObject,FragmentShader)
     glDeleteShader(FragmentShader)
   end if
   glDeleteProgram(ProgramObject)
  end if
end destructor

function ShaderToy.CompileFile(filename as string) as boolean
  dim as string code
  var hFile = FreeFile()
  if open(filename,for input, as #hFile) then 
    ShaderLog = "can't read shader: " & chr(34) & filename  & chr(34) & " !"
    return false
  end if
  while not eof(hFile)
    dim as string aLine
    line input #hFile,aLine
    code &= aLine & !"\n"
  wend
  close #hFile
  return CompileCode(code)
end function

function ShaderToy.CompileCode(UserCode as string) as boolean
  dim as GLint logSize
  dim as GLint status
  dim as string FragmentProlog
  FragmentProlog & =!"uniform float     iGlobalTime;  // shader playback time (in seconds)\n"
  FragmentProlog & =!"uniform vec3      iResolution;  // viewport resolution (in pixels)\n"
  FragmentProlog & =!"uniform vec4      iMouse;       // mouse pixel coords. xy: current (if MLB down), zw: click\n"
  FragmentProlog & =!"uniform vec4      iDate;        // (year, month, day, time in seconds)\n"
  FragmentProlog & =!"uniform sampler2D iChannel0;\n"
  FragmentProlog & =!"uniform sampler2D iChannel1;\n"
  FragmentProlog & =!"uniform sampler2D iChannel2;\n"
  FragmentProlog & =!"uniform sampler2D iChannel3;\n"
  dim as string FragmentEpilog
  FragmentEpilog &= !"void main() {\n"
  FragmentEpilog &= !"  vec4 color;\n"
  FragmentEpilog &= !"  // call user shader\n"
  FragmentEpilog &= !"  mainImage(color, gl_FragCoord.xy);\n"
  FragmentEpilog &= !"  color.w = 1.0;\n"
  FragmentEpilog &= !"  gl_FragColor = color;\n"
  FragmentEpilog &= !"}\n"

  dim as string FragmentCode = FragmentProlog & UserCode & FragmentEpilog

  FragmentShader = glCreateShader(GL_FRAGMENT_SHADER)
  if FragmentShader=0 then 
    ShaderLog = "glCreateShader(GL_FRAGMENT_SHADER) failed !"
    return false
  end if
  dim as GLchar ptr pCode=strptr(FragmentCode)
  glShaderSource (FragmentShader, 1, @pCode, NULL)
  glCompileShader(FragmentShader)
  glGetShaderiv  (FragmentShader, GL_COMPILE_STATUS, @status)
  if status = GL_FALSE then 
    glGetShaderiv(FragmentShader, GL_INFO_LOG_LENGTH, @logSize)
    ShaderLog = space(logSize)
    glGetShaderInfoLog(FragmentShader, logSize, NULL, cptr(GLchar ptr,strptr(ShaderLog)) )
    ShaderLog = !"glCompileShader(FragmentShader) failed !\n" & Shaderlog
    glDeleteShader(FragmentShader) : FragmentShader = 0
    return false
  end if

  ProgramObject = glCreateProgram()
  if ProgramObject=0 then 
    ShaderLog = "glCreateProgram() failed !"
    glDeleteShader(FragmentShader) : FragmentShader = 0
    return false
  end if
  glAttachShader(ProgramObject,FragmentShader)
  glLinkProgram (ProgramObject)
  glGetProgramiv(ProgramObject, GL_LINK_STATUS, @status)
  if (status = GL_FALSE) then
    glGetProgramiv(ProgramObject, GL_INFO_LOG_LENGTH, @logSize)
    ShaderLog = space(logSize)
    glGetProgramInfoLog (ProgramObject, logSize, NULL, cptr(GLchar ptr,strptr(ShaderLog)) )
    ShaderLog = !"glLinkProgram() failed !\n" & Shaderlog
    glDeleteShader(FragmentShader) : FragmentShader = 0
    return false
  end if
  return true
end function

'
' main
'


' init Screenres, create the OpenGL context and load some OpenGL procs.
dim as integer pixels=640
' wide screen 16:9
glScreen pixels,pixels/16*9


' get curent resolution
dim as integer scr_w,scr_h
screeninfo scr_w,scr_h

dim as vec3 v3
v3.x=scr_w     ' width in pixle
v3.y=scr_h     '`height in pixle
v3.z=v3.x/v3.y ' pixel ratio

dim as ShaderToy Shader

if Shader.CompileCode(SCODE)=false then
  ErrorExit Shader.ShaderLog
end if  

' enable shader
glUseProgram(Shader.ProgramObject)

' get uniforms locations in shader program
var iGlobalTime = glGetUniformLocation(Shader.ProgramObject,"iGlobalTime")
var iResolution = glGetUniformLocation(Shader.ProgramObject,"iResolution")
var iMouse      = glGetUniformLocation(Shader.ProgramObject,"iMouse")

' set vec3 iResolution
glUniform3f(iResolution,v3.x,v3.y,v3.z)

dim as integer mx,my,mb,frames,fps
dim as double tStart = Timer()
dim as double tLast=tStart
while inkey=""
  dim as double tNow=Timer()
  ' set uniform float iGlobalTime
  glUniform1f(iGlobalTime,tNow-tStart)
/'
  if frames mod 3=0 then
    ' set vec4 iMouse
    if getMouse(mx,my,,mb)=0 then
      if mb then
        glUniform4f(iResolution,mx,scr_h-my,1,1)
      else
        glUniform4f(iResolution,0,0,0,0)
      end if
    end if
  end if
'/

  'glClear(GL_COLOR_BUFFER_BIT)

  ' draw a rectangle (2 triangles over the whole screen)
  glRectf(-1,-1,1,1)
  flip ' swap the buffers

  frames+=1
  ' update fps
  if frames mod 24=0 then
    fps=24/(tNow-tLast)
    windowtitle "fps: " & fps
    tLast=tNow
  end if

wend

' disable shader
glUseProgram(0)
St_W
Posts: 1619
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: Can you post your FPS result please ?

Post by St_W »

srvaldez wrote:[...] on my Mac
FreeBasic isn't available for Mac, is it?
(or are you running Windows / Linux on it?)
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: Can you post your FPS result please ?

Post by srvaldez »

venom built FreeBASIC for Mac http://www.freebasic.net/forum/viewtopi ... 17&t=24027
but I have Windows and Linux VM's
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Can you post your FPS result please ?

Post by badidea »

Had to disable glDefine(glActiveTexture) and glProc(glActiveTexture)
And do this sudo ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1.2.0 /usr/lib/i386-linux-gnu/libGL.so to make ld find -lGL

Joshy's code:

Between 25-50 fps
But lags now and then for a few tens of a second. heavy on cpu, graphics card fan going nuts.

Web version runs smoother, less heavy on CPU, 20-35 fps

srvaldez's - Winding Menger Tunnel:

Between 120-140 fps, less laggy behavior.

srvaldez's - iq's school of terrain:

Between 10-15 fps, very laggy

srvaldez's - Gold Box:

~80 fps

--- system info ---

Ubuntu 14.04 64-bit
FreeBASIC Compiler - Version 1.05.0 (01-31-2016), built for linux-x86 (32bit)
Intel(R) Core(TM)2 Duo CPU E8400 @ 3.00GHz
NVIDIA Corporation G92 [GeForce GTS 250]
OpenGL Vendor: NVIDIA Corporation
OpenGL Renderer: GeForce GTS 250/PCIe/SSE2
OpenGL Version: 3.3.0 NVIDIA 340.96
GLX version: 1.4
Kernel driver in use: nvidia
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Can you post your FPS result please ?

Post by D.J.Peters »

Thank you all for reporting your FPS.

Now it's clear for me isn't a driver problem here.
ST_W's GeForce 8600 GT or my GT240 are simple out of date.

I wonder me only why I get 20 FPS with OpenGL shader
and only 5 FPS with OpenGL ES shader and WebGL.

But to early to put it in the trash. (96 cores 1.5GHz with 1 GB RAM)

Joshy
noop
Posts: 130
Joined: Sep 18, 2006 10:29

Re: [solved] Can you post your FPS result please ?

Post by noop »

Really cool what can be done with just a few hundred lines of code!

Joshy's code:
I get a solid 60 fps (minimum 58 fps) on a (mobile) Nvidia GTX860M.
On the Intel processor integrated HD Graphics 4600 I get a minimum of 10 fps, a maximum of 25 fps and an estimated median of 12 fps (other stuff, e.g. web browser, was running as well).
Using 2560x1440 I get an estimated median of 6 fps on the GTX860M. It shows full load as does one CPU core.
Dr_D
Posts: 2451
Joined: May 27, 2005 4:59
Contact:

Re: [solved] Can you post your FPS result please ?

Post by Dr_D »

I'm going to test, but it looks like I need to update my compiler. I have no "boolean" yet. lol

45-60 fps here man. That is freakin' awesome too! :)
Mihail_B
Posts: 273
Joined: Jan 29, 2008 11:20
Location: Romania
Contact:

Re: [solved] Can you post your FPS result please ?

Post by Mihail_B »

CPU: INTEL i5-4210M dual core 3.2ghz (laptop)
RAM: 8GB (1600 dual channel)
OS: WIN10 64bit
GPU(1): NVIDIA GT840m :
50-60fps (ave ~56.5, steady all the time)
GPU(2): INTEL HD4600 :
30-70fps (ave ~35, graphics glitches)


CPU: INTEL i5-3350P quad core 3.3ghz (dektop)
RAM: 16GB (1600XMP dual channel)
OS: WIN7 64bit
GPU: AMD Radeon R7-250 overclocked :
37-100fps (ave ~40..50, with portions running at low fps ~40 and portions running at high fps >60fps)
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: [solved] Can you post your FPS result please ?

Post by srvaldez »

Seascape https://www.shadertoy.com/view/Ms2SD1
Image

Code: Select all

dim as string SCODE
SCODE &= !"/*\n"
SCODE &= !" * ""Seascape"" by Alexander Alekseev aka TDM - 2014\n"
SCODE &= !" * License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.\n"
SCODE &= !" * Contact: tdmaav@gmail.com\n"
SCODE &= !" */\n"

SCODE &= !"const int NUM_STEPS = 8;\n"
SCODE &= !"const float PI	 	= 3.141592;\n"
SCODE &= !"const float EPSILON	= 1e-3;\n"
SCODE &= !"#define EPSILON_NRM (0.1 / iResolution.x)\n"

SCODE &= !"// sea\n"
SCODE &= !"const int ITER_GEOMETRY = 3;\n"
SCODE &= !"const int ITER_FRAGMENT = 5;\n"
SCODE &= !"const float SEA_HEIGHT = 0.6;\n"
SCODE &= !"const float SEA_CHOPPY = 4.0;\n"
SCODE &= !"const float SEA_SPEED = 0.8;\n"
SCODE &= !"const float SEA_FREQ = 0.16;\n"
SCODE &= !"const vec3 SEA_BASE = vec3(0.1,0.19,0.22);\n"
SCODE &= !"const vec3 SEA_WATER_COLOR = vec3(0.8,0.9,0.6);\n"
SCODE &= !"#define SEA_TIME (1.0 + iGlobalTime * SEA_SPEED)\n"
SCODE &= !"const mat2 octave_m = mat2(1.6,1.2,-1.2,1.6);\n"

SCODE &= !"// math\n"
SCODE &= !"mat3 fromEuler(vec3 ang) {\n"
SCODE &= !"	vec2 a1 = vec2(sin(ang.x),cos(ang.x));\n"
SCODE &= !"    vec2 a2 = vec2(sin(ang.y),cos(ang.y));\n"
SCODE &= !"    vec2 a3 = vec2(sin(ang.z),cos(ang.z));\n"
SCODE &= !"    mat3 m;\n"
SCODE &= !"    m[0] = vec3(a1.y*a3.y+a1.x*a2.x*a3.x,a1.y*a2.x*a3.x+a3.y*a1.x,-a2.y*a3.x);\n"
SCODE &= !"	m[1] = vec3(-a2.y*a1.x,a1.y*a2.y,a2.x);\n"
SCODE &= !"	m[2] = vec3(a3.y*a1.x*a2.x+a1.y*a3.x,a1.x*a3.x-a1.y*a3.y*a2.x,a2.y*a3.y);\n"
SCODE &= !"	return m;\n"
SCODE &= !"}\n"
SCODE &= !"float hash( vec2 p ) {\n"
SCODE &= !"	float h = dot(p,vec2(127.1,311.7));	\n"
SCODE &= !"    return fract(sin(h)*43758.5453123);\n"
SCODE &= !"}\n"
SCODE &= !"float noise( in vec2 p ) {\n"
SCODE &= !"    vec2 i = floor( p );\n"
SCODE &= !"    vec2 f = fract( p );	\n"
SCODE &= !"	vec2 u = f*f*(3.0-2.0*f);\n"
SCODE &= !"    return -1.0+2.0*mix( mix( hash( i + vec2(0.0,0.0) ), \n"
SCODE &= !"                     hash( i + vec2(1.0,0.0) ), u.x),\n"
SCODE &= !"                mix( hash( i + vec2(0.0,1.0) ), \n"
SCODE &= !"                     hash( i + vec2(1.0,1.0) ), u.x), u.y);\n"
SCODE &= !"}\n"

SCODE &= !"// lighting\n"
SCODE &= !"float diffuse(vec3 n,vec3 l,float p) {\n"
SCODE &= !"    return pow(dot(n,l) * 0.4 + 0.6,p);\n"
SCODE &= !"}\n"
SCODE &= !"float specular(vec3 n,vec3 l,vec3 e,float s) {    \n"
SCODE &= !"    float nrm = (s + 8.0) / (PI * 8.0);\n"
SCODE &= !"    return pow(max(dot(reflect(e,n),l),0.0),s) * nrm;\n"
SCODE &= !"}\n"

SCODE &= !"// sky\n"
SCODE &= !"vec3 getSkyColor(vec3 e) {\n"
SCODE &= !"    e.y = max(e.y,0.0);\n"
SCODE &= !"    return vec3(pow(1.0-e.y,2.0), 1.0-e.y, 0.6+(1.0-e.y)*0.4);\n"
SCODE &= !"}\n"

SCODE &= !"// sea\n"
SCODE &= !"float sea_octave(vec2 uv, float choppy) {\n"
SCODE &= !"    uv += noise(uv);        \n"
SCODE &= !"    vec2 wv = 1.0-abs(sin(uv));\n"
SCODE &= !"    vec2 swv = abs(cos(uv));    \n"
SCODE &= !"    wv = mix(wv,swv,wv);\n"
SCODE &= !"    return pow(1.0-pow(wv.x * wv.y,0.65),choppy);\n"
SCODE &= !"}\n"

SCODE &= !"float map(vec3 p) {\n"
SCODE &= !"    float freq = SEA_FREQ;\n"
SCODE &= !"    float amp = SEA_HEIGHT;\n"
SCODE &= !"    float choppy = SEA_CHOPPY;\n"
SCODE &= !"    vec2 uv = p.xz; uv.x *= 0.75;\n"
SCODE &= !"    \n"
SCODE &= !"    float d, h = 0.0;    \n"
SCODE &= !"    for(int i = 0; i < ITER_GEOMETRY; i++) {        \n"
SCODE &= !"    	d = sea_octave((uv+SEA_TIME)*freq,choppy);\n"
SCODE &= !"    	d += sea_octave((uv-SEA_TIME)*freq,choppy);\n"
SCODE &= !"        h += d * amp;        \n"
SCODE &= !"    	uv *= octave_m; freq *= 1.9; amp *= 0.22;\n"
SCODE &= !"        choppy = mix(choppy,1.0,0.2);\n"
SCODE &= !"    }\n"
SCODE &= !"    return p.y - h;\n"
SCODE &= !"}\n"

SCODE &= !"float map_detailed(vec3 p) {\n"
SCODE &= !"    float freq = SEA_FREQ;\n"
SCODE &= !"    float amp = SEA_HEIGHT;\n"
SCODE &= !"    float choppy = SEA_CHOPPY;\n"
SCODE &= !"    vec2 uv = p.xz; uv.x *= 0.75;\n"
SCODE &= !"    \n"
SCODE &= !"    float d, h = 0.0;    \n"
SCODE &= !"    for(int i = 0; i < ITER_FRAGMENT; i++) {        \n"
SCODE &= !"    	d = sea_octave((uv+SEA_TIME)*freq,choppy);\n"
SCODE &= !"    	d += sea_octave((uv-SEA_TIME)*freq,choppy);\n"
SCODE &= !"        h += d * amp;        \n"
SCODE &= !"    	uv *= octave_m; freq *= 1.9; amp *= 0.22;\n"
SCODE &= !"        choppy = mix(choppy,1.0,0.2);\n"
SCODE &= !"    }\n"
SCODE &= !"    return p.y - h;\n"
SCODE &= !"}\n"

SCODE &= !"vec3 getSeaColor(vec3 p, vec3 n, vec3 l, vec3 eye, vec3 dist) {  \n"
SCODE &= !"    float fresnel = clamp(1.0 - dot(n,-eye), 0.0, 1.0);\n"
SCODE &= !"    fresnel = pow(fresnel,3.0) * 0.65;\n"
SCODE &= !"        \n"
SCODE &= !"    vec3 reflected = getSkyColor(reflect(eye,n));    \n"
SCODE &= !"    vec3 refracted = SEA_BASE + diffuse(n,l,80.0) * SEA_WATER_COLOR * 0.12; \n"
SCODE &= !"    \n"
SCODE &= !"    vec3 color = mix(refracted,reflected,fresnel);\n"
SCODE &= !"    \n"
SCODE &= !"    float atten = max(1.0 - dot(dist,dist) * 0.001, 0.0);\n"
SCODE &= !"    color += SEA_WATER_COLOR * (p.y - SEA_HEIGHT) * 0.18 * atten;\n"
SCODE &= !"    \n"
SCODE &= !"    color += vec3(specular(n,l,eye,60.0));\n"
SCODE &= !"    \n"
SCODE &= !"    return color;\n"
SCODE &= !"}\n"

SCODE &= !"// tracing\n"
SCODE &= !"vec3 getNormal(vec3 p, float eps) {\n"
SCODE &= !"    vec3 n;\n"
SCODE &= !"    n.y = map_detailed(p);    \n"
SCODE &= !"    n.x = map_detailed(vec3(p.x+eps,p.y,p.z)) - n.y;\n"
SCODE &= !"    n.z = map_detailed(vec3(p.x,p.y,p.z+eps)) - n.y;\n"
SCODE &= !"    n.y = eps;\n"
SCODE &= !"    return normalize(n);\n"
SCODE &= !"}\n"

SCODE &= !"float heightMapTracing(vec3 ori, vec3 dir, out vec3 p) {  \n"
SCODE &= !"    float tm = 0.0;\n"
SCODE &= !"    float tx = 1000.0;    \n"
SCODE &= !"    float hx = map(ori + dir * tx);\n"
SCODE &= !"    if(hx > 0.0) return tx;   \n"
SCODE &= !"    float hm = map(ori + dir * tm);    \n"
SCODE &= !"    float tmid = 0.0;\n"
SCODE &= !"    for(int i = 0; i < NUM_STEPS; i++) {\n"
SCODE &= !"        tmid = mix(tm,tx, hm/(hm-hx));                   \n"
SCODE &= !"        p = ori + dir * tmid;                   \n"
SCODE &= !"    	float hmid = map(p);\n"
SCODE &= !"		if(hmid < 0.0) {\n"
SCODE &= !"        	tx = tmid;\n"
SCODE &= !"            hx = hmid;\n"
SCODE &= !"        } else {\n"
SCODE &= !"            tm = tmid;\n"
SCODE &= !"            hm = hmid;\n"
SCODE &= !"        }\n"
SCODE &= !"    }\n"
SCODE &= !"    return tmid;\n"
SCODE &= !"}\n"

SCODE &= !"// main\n"
SCODE &= !"void mainImage( out vec4 fragColor, in vec2 fragCoord ) {\n"
SCODE &= !"	vec2 uv = fragCoord.xy / iResolution.xy;\n"
SCODE &= !"    uv = uv * 2.0 - 1.0;\n"
SCODE &= !"    uv.x *= iResolution.x / iResolution.y;    \n"
SCODE &= !"    float time = iGlobalTime * 0.3 + iMouse.x*0.01;\n"
SCODE &= !"        \n"
SCODE &= !"    // ray\n"
SCODE &= !"    vec3 ang = vec3(sin(time*3.0)*0.1,sin(time)*0.2+0.3,time);    \n"
SCODE &= !"    vec3 ori = vec3(0.0,3.5,time*5.0);\n"
SCODE &= !"    vec3 dir = normalize(vec3(uv.xy,-2.0)); dir.z += length(uv) * 0.15;\n"
SCODE &= !"    dir = normalize(dir) * fromEuler(ang);\n"
SCODE &= !"    \n"
SCODE &= !"    // tracing\n"
SCODE &= !"    vec3 p;\n"
SCODE &= !"    heightMapTracing(ori,dir,p);\n"
SCODE &= !"    vec3 dist = p - ori;\n"
SCODE &= !"    vec3 n = getNormal(p, dot(dist,dist) * EPSILON_NRM);\n"
SCODE &= !"    vec3 light = normalize(vec3(0.0,1.0,0.8)); \n"
SCODE &= !"             \n"
SCODE &= !"    // color\n"
SCODE &= !"    vec3 color = mix(\n"
SCODE &= !"        getSkyColor(dir),\n"
SCODE &= !"        getSeaColor(p,n,light,dir,dist),\n"
SCODE &= !"    	pow(smoothstep(0.0,-0.05,dir.y),0.3));\n"
SCODE &= !"        \n"
SCODE &= !"    // post\n"
SCODE &= !"	fragColor = vec4(pow(color,vec3(0.75)), 1.0);\n"
SCODE &= !"}\n"
SCODE &= !"//-------------------------------------------------------------------------- \n"


#include once "fbgfx.bi"
#include once "GL/gl.bi"
#include once "GL/glext.bi"

#ifndef NULL
#define NULL 0
#endif


type vec3
  as GLfloat x,y,z
end type

sub ErrorExit(msg as string)
  if screenptr() then screen 0
  dim as integer w,h
  screeninfo w,h : w*=0.75:h*=0.75
  screenres w,h
  print msg
  print "press any key to quit ..."
  beep : sleep : end 1
end sub

' define OpenGL proc's
#define glDefine(n) dim shared as PFN##n##PROC n
' texture
'glDefine(glActiveTexture)
' shader
glDefine(glCreateShader)
glDefine(glDeleteShader)
glDefine(glShaderSource)
glDefine(glCompileShader)
glDefine(glGetShaderiv)
glDefine(glGetShaderInfoLog)
' program
glDefine(glCreateProgram)
glDefine(glDeleteProgram)
glDefine(glAttachShader)
glDefine(glDetachShader)
glDefine(glLinkProgram)
glDefine(glGetProgramiv)
glDefine(glGetProgramInfoLog)
glDefine(glUseProgram)
' uniform
glDefine(glGetUniformLocation)
glDefine(glUniform1f)
glDefine(glUniform2f)
glDefine(glUniform3f)
glDefine(glUniform4f)
glDefine(glUniform1i)
#undef glDefine

sub glScreen(w as integer=640, h as integer=360, b as integer=32, d as integer=24, s as integer=0, f as integer=0)
  if ScreenPtr() then screen 0
  ScreenControl FB.SET_GL_STENCIL_BITS,s
  ScreenControl FB.SET_GL_DEPTH_BITS  ,d
  if ScreenRes(w,h,b,,FB.GFX_OPENGL or iif(f<>0,FB.GFX_FULLSCREEN,0)) then
    ErrorExit("screenres(" & w & "," & h &") failed !")
  end if
  Windowtitle "offline shadertoy.com"

  flip
  ' get OpenGL proc's (abort if something goes wrong)
  #define glProc(n) n = ScreenGLProc(#n) : if n = 0 then ErrorExit(#n)
  ' texture
  'glProc(glActiveTexture)
  ' shader
  glProc(glCreateShader)
  glProc(glDeleteShader)
  glProc(glShaderSource)
  glProc(glCompileShader)
  glProc(glGetShaderiv)
  glProc(glGetShaderInfoLog)
  ' program
  glProc(glCreateProgram)
  glProc(glDeleteProgram)
  glProc(glAttachShader)
  glProc(glDetachShader)
  glProc(glLinkProgram)
  glProc(glGetProgramiv)
  glProc(glGetProgramInfoLog)
  glProc(glUseProgram)
  ' uniform
  glProc(glGetUniformLocation)
  glProc(glUniform1f)
  glProc(glUniform2f)
  glProc(glUniform3f)
  glProc(glUniform4f)
  glProc(glUniform1i)
  #undef glProc
end sub

type ShaderToy
  declare destructor
  declare function CompileFile(Filename as string) as boolean
  declare function CompileCode(Code as string) as boolean
  as GLuint FragmentShader
  as GLuint ProgramObject
  as string Shaderlog
end type
destructor ShaderToy
  if ProgramObject then 
   glUseprogram(0)
   if FragmentShader  then 
     glDetachShader(ProgramObject,FragmentShader)
     glDeleteShader(FragmentShader)
   end if
   glDeleteProgram(ProgramObject)
  end if
end destructor

function ShaderToy.CompileFile(filename as string) as boolean
  dim as string code
  var hFile = FreeFile()
  if open(filename,for input, as #hFile) then 
    ShaderLog = "can't read shader: " & chr(34) & filename  & chr(34) & " !"
    return false
  end if
  while not eof(hFile)
    dim as string aLine
    line input #hFile,aLine
    code &= aLine & !"\n"
  wend
  close #hFile
  return CompileCode(code)
end function

function ShaderToy.CompileCode(UserCode as string) as boolean
  dim as GLint logSize
  dim as GLint status
  dim as string FragmentProlog
  FragmentProlog & =!"uniform float     iGlobalTime;  // shader playback time (in seconds)\n"
  FragmentProlog & =!"uniform vec3      iResolution;  // viewport resolution (in pixels)\n"
  FragmentProlog & =!"uniform vec4      iMouse;       // mouse pixel coords. xy: current (if MLB down), zw: click\n"
  FragmentProlog & =!"uniform vec4      iDate;        // (year, month, day, time in seconds)\n"
  FragmentProlog & =!"uniform sampler2D iChannel0;\n"
  FragmentProlog & =!"uniform sampler2D iChannel1;\n"
  FragmentProlog & =!"uniform sampler2D iChannel2;\n"
  FragmentProlog & =!"uniform sampler2D iChannel3;\n"
  dim as string FragmentEpilog
  FragmentEpilog &= !"void main() {\n"
  FragmentEpilog &= !"  vec4 color;\n"
  FragmentEpilog &= !"  // call user shader\n"
  FragmentEpilog &= !"  mainImage(color, gl_FragCoord.xy);\n"
  FragmentEpilog &= !"  color.w = 1.0;\n"
  FragmentEpilog &= !"  gl_FragColor = color;\n"
  FragmentEpilog &= !"}\n"

  dim as string FragmentCode = FragmentProlog & UserCode & FragmentEpilog

  FragmentShader = glCreateShader(GL_FRAGMENT_SHADER)
  if FragmentShader=0 then 
    ShaderLog = "glCreateShader(GL_FRAGMENT_SHADER) failed !"
    return false
  end if
  dim as GLchar ptr pCode=strptr(FragmentCode)
  glShaderSource (FragmentShader, 1, @pCode, NULL)
  glCompileShader(FragmentShader)
  glGetShaderiv  (FragmentShader, GL_COMPILE_STATUS, @status)
  if status = GL_FALSE then 
    glGetShaderiv(FragmentShader, GL_INFO_LOG_LENGTH, @logSize)
    ShaderLog = space(logSize)
    glGetShaderInfoLog(FragmentShader, logSize, NULL, cptr(GLchar ptr,strptr(ShaderLog)) )
    ShaderLog = !"glCompileShader(FragmentShader) failed !\n" & Shaderlog
    glDeleteShader(FragmentShader) : FragmentShader = 0
    return false
  end if

  ProgramObject = glCreateProgram()
  if ProgramObject=0 then 
    ShaderLog = "glCreateProgram() failed !"
    glDeleteShader(FragmentShader) : FragmentShader = 0
    return false
  end if
  glAttachShader(ProgramObject,FragmentShader)
  glLinkProgram (ProgramObject)
  glGetProgramiv(ProgramObject, GL_LINK_STATUS, @status)
  if (status = GL_FALSE) then
    glGetProgramiv(ProgramObject, GL_INFO_LOG_LENGTH, @logSize)
    ShaderLog = space(logSize)
    glGetProgramInfoLog (ProgramObject, logSize, NULL, cptr(GLchar ptr,strptr(ShaderLog)) )
    ShaderLog = !"glLinkProgram() failed !\n" & Shaderlog
    glDeleteShader(FragmentShader) : FragmentShader = 0
    return false
  end if
  return true
end function

'
' main
'


' init Screenres, create the OpenGL context and load some OpenGL procs.
dim as integer pixels=640
' wide screen 16:9
glScreen pixels,pixels/16*9


' get curent resolution
dim as integer scr_w,scr_h
screeninfo scr_w,scr_h

dim as vec3 v3
v3.x=scr_w     ' width in pixle
v3.y=scr_h     '`height in pixle
v3.z=v3.x/v3.y ' pixel ratio

dim as ShaderToy Shader

if Shader.CompileCode(SCODE)=false then
  ErrorExit Shader.ShaderLog
end if  

' enable shader
glUseProgram(Shader.ProgramObject)

' get uniforms locations in shader program
var iGlobalTime = glGetUniformLocation(Shader.ProgramObject,"iGlobalTime")
var iResolution = glGetUniformLocation(Shader.ProgramObject,"iResolution")
var iMouse      = glGetUniformLocation(Shader.ProgramObject,"iMouse")

' set vec3 iResolution
glUniform3f(iResolution,v3.x,v3.y,v3.z)

dim as integer mx,my,mb,frames,fps
dim as double tStart = Timer()
dim as double tLast=tStart
while inkey=""
  dim as double tNow=Timer()
  ' set uniform float iGlobalTime
  glUniform1f(iGlobalTime,tNow-tStart)
/'
  if frames mod 3=0 then
    ' set vec4 iMouse
    if getMouse(mx,my,,mb)=0 then
      if mb then
        glUniform4f(iResolution,mx,scr_h-my,1,1)
      else
        glUniform4f(iResolution,0,0,0,0)
      end if
    end if
  end if
'/

  'glClear(GL_COLOR_BUFFER_BIT)

  ' draw a rectangle (2 triangles over the whole screen)
  glRectf(-1,-1,1,1)
  flip ' swap the buffers

  frames+=1
  ' update fps
  if frames mod 24=0 then
    fps=24/(tNow-tLast)
    windowtitle "fps: " & fps
    tLast=tNow
  end if

wend

' disable shader
glUseProgram(0)
Last edited by srvaldez on Apr 04, 2018 15:12, edited 3 times in total.
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: [solved] Can you post your FPS result please ?

Post by srvaldez »

Kirby Jump
Created by fizzer https://www.shadertoy.com/view/lt2fD3
Image

Code: Select all

dim as string SCODE
SCODE &= !"// polynomial smooth min (from IQ)\n"
SCODE &= !"float smin( float a, float b, float k )\n"
SCODE &= !"{\n"
SCODE &= !"    float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 );\n"
SCODE &= !"    return mix( b, a, h ) - k*h*(1.0-h);\n"
SCODE &= !"}\n"


SCODE &= !"float smax(float a,float b, float k)\n"
SCODE &= !"{\n"
SCODE &= !"    return -smin(-a,-b,k);\n"
SCODE &= !"}\n"

SCODE &= !"mat2 rotmat(float a)\n"
SCODE &= !"{\n"
SCODE &= !"    return mat2(cos(a),sin(a),-sin(a),cos(a));\n"
SCODE &= !"}\n"

SCODE &= !"float shoesDist(vec3 p)\n"
SCODE &= !"{\n"
SCODE &= !"    vec3 op=p;\n"
SCODE &= !"    float d=1e4;\n"

SCODE &= !"    p.y-=1.5;\n"

SCODE &= !"    // right shoe\n"
SCODE &= !"    op=p;\n"
SCODE &= !"    p-=vec3(-.5,-.6,-.9);\n"
SCODE &= !"    p.yz=rotmat(-.7)*p.yz;\n"
SCODE &= !"    p.xz=rotmat(0.1)*p.xz;\n"
SCODE &= !"    d=min(d,-smin(p.y,-(length(p*vec3(1.6,1,1))-.64),.2));\n"
SCODE &= !"    p=op;\n"

SCODE &= !"    // left shoe\n"
SCODE &= !"    op=p;\n"
SCODE &= !"    p-=vec3(.55,-.8,0.4);\n"
SCODE &= !"    p.x=-p.x;\n"
SCODE &= !"    p.yz=rotmat(1.4)*p.yz;\n"
SCODE &= !"    d=min(d,-smin(p.y,-(length(p*vec3(1.6,1,1))-.73),.2));\n"
SCODE &= !"    p=op;\n"
SCODE &= !"    return d;\n"
SCODE &= !"}\n"

SCODE &= !"float sceneDist(vec3 p)\n"
SCODE &= !"{\n"
SCODE &= !"    vec3 op=p;\n"
SCODE &= !"    float d=shoesDist(p);\n"

SCODE &= !"    d=min(d,p.y);\n"
SCODE &= !"    p.y-=1.5;\n"

SCODE &= !"    // torso\n"
SCODE &= !"    d=min(d,length(p)-1.);\n"


SCODE &= !"    // left arm\n"
SCODE &= !"    op=p;\n"
SCODE &= !"    p-=vec3(.66,.7,0);\n"
SCODE &= !"    p.xz=rotmat(-0.1)*p.xz;\n"
SCODE &= !"    d=smin(d,(length(p*vec3(1.8,1,1))-.58),.07);\n"
SCODE &= !"    p=op;\n"

SCODE &= !"    // right arm\n"
SCODE &= !"    op=p;\n"
SCODE &= !"    p-=vec3(-.75,0.2,0);\n"
SCODE &= !"    d=smin(d,(length(p*vec3(1,1.5,1))-.54),.03);\n"
SCODE &= !"    p=op;\n"

SCODE &= !"    // mouth\n"
SCODE &= !"    p.y-=.11;\n"
SCODE &= !"    float md=smax(p.z+.84,smax(smax(p.x-.2,p.y-.075,.2),dot(p,vec3(.7071,-.7071,0))-.1,.08),.04);\n"
SCODE &= !"    p.x=-p.x;\n"
SCODE &= !"    md=smax(md,smax(p.z+.84,smax(smax(p.x-.2,p.y-.075,.2),dot(p,vec3(.7071,-.7071,0))-.1,.08),.01),.13);\n"
SCODE &= !"    d=smax(d,-md,.012);\n"

SCODE &= !"    // tongue\n"
SCODE &= !"    p=op;\n"
SCODE &= !"    d=smin(d,length((p-vec3(0,.03,-.75))*vec3(1,1,1))-.16,.01);\n"

SCODE &= !"    return min(d,10.);\n"
SCODE &= !"}\n"



SCODE &= !"vec3 sceneNorm(vec3 p)\n"
SCODE &= !"{\n"
SCODE &= !"    vec3 e=vec3(1e-3,0,0);\n"
SCODE &= !"    float d = sceneDist(p);\n"
SCODE &= !"    return normalize(vec3(sceneDist(p + e.xyy) - sceneDist(p - e.xyy), sceneDist(p + e.yxy) - sceneDist(p - e.yxy),\n"
SCODE &= !"                          sceneDist(p + e.yyx) - sceneDist(p - e.yyx)));\n"
SCODE &= !"}\n"


SCODE &= !"// from simon green and others\n"
SCODE &= !"float ambientOcclusion(vec3 p, vec3 n)\n"
SCODE &= !"{\n"
SCODE &= !"    const int steps = 4;\n"
SCODE &= !"    const float delta = 0.15;\n"

SCODE &= !"    float a = 0.0;\n"
SCODE &= !"    float weight = 4.;\n"
SCODE &= !"    for(int i=1; i<=steps; i++) {\n"
SCODE &= !"        float d = (float(i) / float(steps)) * delta; \n"
SCODE &= !"        a += weight*(d - sceneDist(p + n*d));\n"
SCODE &= !"        weight *= 0.5;\n"
SCODE &= !"    }\n"
SCODE &= !"    return clamp(1.0 - a, 0.0, 1.0);\n"
SCODE &= !"}\n"

SCODE &= !"// a re-shaped cosine, to make the peaks more pointy\n"
SCODE &= !"float cos2(float x){return cos(x-sin(x)/3.);}\n"

SCODE &= !"float starShape(vec2 p)\n"
SCODE &= !"{\n"
SCODE &= !"    float a=atan(p.y,p.x)+iGlobalTime/3.;\n"
SCODE &= !"    float l=pow(length(p),.8);\n"
SCODE &= !"    float star=1.-smoothstep(0.,(3.-cos2(a*5.*2.))*.02,l-.5+cos2(a*5.)*.1);\n"
SCODE &= !"    return star;\n"
SCODE &= !"}\n"


SCODE &= !"void mainImage( out vec4 fragColor, in vec2 fragCoord )\n"
SCODE &= !"{\n"
SCODE &= !"    // Normalized pixel coordinates (from 0 to 1)\n"
SCODE &= !"    vec2 uv = fragCoord/iResolution.xy;\n"

SCODE &= !"    float an=cos(iGlobalTime)*.1;\n"

SCODE &= !"    vec2 ot=uv*2.-1.;\n"
SCODE &= !"    ot.y*=iResolution.y/iResolution.x;\n"
SCODE &= !"    vec3 ro=vec3(0.,1.4,4.);\n"
SCODE &= !"    vec3 rd=normalize(vec3(ot.xy,-1.3));\n"

SCODE &= !"    rd.xz=mat2(cos(an),sin(an),sin(an),-cos(an))*rd.xz;\n"
SCODE &= !"    ro.xz=mat2(cos(an),sin(an),sin(an),-cos(an))*ro.xz;\n"

SCODE &= !"    float s=20.;\n"

SCODE &= !"    // primary ray\n"
SCODE &= !"    float t=0.,d=0.;\n"
SCODE &= !"    for(int i=0;i<80;++i)\n"
SCODE &= !"    {\n"
SCODE &= !"        d=sceneDist(ro+rd*t);\n"
SCODE &= !"        if(d<1e-4)\n"
SCODE &= !"            break;\n"
SCODE &= !"        if(t>10.)\n"
SCODE &= !"            break;\n"
SCODE &= !"        t+=d*.9;\n"
SCODE &= !"    }\n"

SCODE &= !"    t=min(t,10.0);\n"

SCODE &= !"    // shadow ray\n"
SCODE &= !"    vec3 rp=ro+rd*t;\n"
SCODE &= !"    vec3 n=sceneNorm(rp);\n"
SCODE &= !"    float st=5e-3;\n"
SCODE &= !"    vec3 ld=normalize(vec3(2,4,-4));\n"
SCODE &= !"    for(int i=0;i<20;++i)\n"
SCODE &= !"    {\n"
SCODE &= !"        d=sceneDist(rp+ld*st);\n"
SCODE &= !"        if(d<1e-5)\n"
SCODE &= !"            break;\n"
SCODE &= !"        if(st>5.)\n"
SCODE &= !"            break;\n"
SCODE &= !"        st+=d*2.;\n"
SCODE &= !"    }\n"

SCODE &= !"    // ambient occlusion and shadowing\n"
SCODE &= !"    vec3 ao=vec3(ambientOcclusion(rp, n));\n"
SCODE &= !"    float shad=mix(.85,1.,step(5.,st));\n"

SCODE &= !"    ao*=mix(.3,1.,.5+.5*n.y);\n"

SCODE &= !"    // soft floor shadow\n"
SCODE &= !"    if(rp.y<1e-3)\n"
SCODE &= !"        ao*=mix(mix(vec3(1,.5,.7),vec3(1),.4)*.6,vec3(1),smoothstep(0.,1.6,length(rp.xz)));\n"



SCODE &= !"    vec3 diff=vec3(1);\n"
SCODE &= !"    vec3 emit=vec3(0);\n"

SCODE &= !"    // skin\n"
SCODE &= !"    diff*=vec3(1.15,.3,.41)*1.4;\n"
SCODE &= !"    diff+=.4*mix(1.,0.,smoothstep(0.,1.,length(rp.xy-vec2(0.,1.9))));\n"
SCODE &= !"    diff+=.5*mix(1.,0.,smoothstep(0.,.5,length(rp.xy-vec2(.7,2.5))));\n"
SCODE &= !"    diff+=.36*mix(1.,0.,smoothstep(0.,.5,length(rp.xy-vec2(-1.1,1.8))));\n"

SCODE &= !"    if(rp.y<1e-3)\n"
SCODE &= !"        diff=vec3(.6,1,.6);\n"

SCODE &= !"    // mouth\n"
SCODE &= !"    diff*=mix(vec3(1,.3,.2),vec3(1),smoothstep(.97,.99,length(rp-vec3(0,1.5,0))));\n"

SCODE &= !"    // shoes\n"
SCODE &= !"    diff=mix(vec3(1.,.05,.1),diff,smoothstep(0.,0.01,shoesDist(rp)));\n"
SCODE &= !"    diff+=.2*mix(1.,0.,smoothstep(0.,.2,length(rp.xy-vec2(-0.5,1.4))));\n"
SCODE &= !"    diff+=.12*mix(1.,0.,smoothstep(0.,.25,length(rp.xy-vec2(0.57,.3))));\n"

SCODE &= !"    // bounce light from the floor\n"
SCODE &= !"    diff+=vec3(.25,1.,.25)*smoothstep(-.3,1.7,-rp.y+1.)*max(0.,-n.y)*.7;\n"

SCODE &= !"    vec3 orp=rp;\n"
SCODE &= !"    rp.y-=1.5;\n"
SCODE &= !"    rp.x=abs(rp.x);\n"

SCODE &= !"    // blushes\n"
SCODE &= !"    diff*=mix(vec3(1,.5,.5),vec3(1),smoothstep(.1,.15,length((rp.xy-vec2(.4,.2))*vec2(1,1.65))));\n"

SCODE &= !"    rp.xy-=vec2(.16,.45);\n"
SCODE &= !"    rp.xy*=.9;\n"
SCODE &= !"    orp=rp;\n"
SCODE &= !"    rp.y=pow(abs(rp.y),1.4)*sign(rp.y);\n"

SCODE &= !"    // eye outline\n"
SCODE &= !"    diff*=smoothstep(.058,.067,length((rp.xy)*vec2(.9,.52)));\n"

SCODE &= !"    rp=orp;\n"
SCODE &= !"    rp.y+=.08;\n"
SCODE &= !"    rp.y-=pow(abs(rp.x),2.)*16.;\n"

SCODE &= !"    // eye reflections\n"
SCODE &= !"    emit+=vec3(.1,.5,1.)*(1.-smoothstep(.03,.036,length((rp.xy)*vec2(.7,.3))))*max(0.,-rp.y)*10.;\n"

SCODE &= !"    rp=orp;\n"
SCODE &= !"    rp.y-=.12;\n"

SCODE &= !"    // eye highlights\n"
SCODE &= !"    emit+=vec3(1)*(1.-smoothstep(.03,.04,length((rp.xy)*vec2(1.,.48))));\n"

SCODE &= !"    // fresnel\n"
SCODE &= !"    diff+=pow(clamp(1.-dot(-rd,n),0.,.9),4.)*.5;\n"

SCODE &= !"    // background and floor fade\n"
SCODE &= !"    vec3 backg=vec3(1.15,.3,.41)*.9;\n"
SCODE &= !"    ot.x+=.6+iGlobalTime/50.;\n"
SCODE &= !"    ot.y+=cos(floor(ot.x*2.)*3.)*.1+.2;\n"
SCODE &= !"    ot.x=mod(ot.x,.5)-.25;\n"
SCODE &= !"    backg=mix(backg,vec3(1.,1.,.5),.1*starShape((ot-vec2(0.,.6))*8.)*smoothstep(9.,10.,t));\n"
SCODE &= !"    diff=mix(diff,backg,smoothstep(.9,10.,t));\n"

SCODE &= !"    fragColor.rgb=mix(vec3(.15,0,0),vec3(1),ao)*shad*diff*1.1;\n"
SCODE &= !"    fragColor.rgb+=emit;\n"

SCODE &= !"    fragColor.rgb=pow(fragColor.rgb,vec3(1./2.4));\n"
SCODE &= !"}\n"

SCODE &= !"//-------------------------------------------------------------------------- \n"


#include once "fbgfx.bi"
#include once "GL/gl.bi"
#include once "GL/glext.bi"

#ifndef NULL
#define NULL 0
#endif


type vec3
  as GLfloat x,y,z
end type

sub ErrorExit(msg as string)
  if screenptr() then screen 0
  dim as integer w,h
  screeninfo w,h : w*=0.75:h*=0.75
  screenres w,h
  print msg
  print "press any key to quit ..."
  beep : sleep : end 1
end sub

' define OpenGL proc's
#define glDefine(n) dim shared as PFN##n##PROC n
' texture
'glDefine(glActiveTexture)
' shader
glDefine(glCreateShader)
glDefine(glDeleteShader)
glDefine(glShaderSource)
glDefine(glCompileShader)
glDefine(glGetShaderiv)
glDefine(glGetShaderInfoLog)
' program
glDefine(glCreateProgram)
glDefine(glDeleteProgram)
glDefine(glAttachShader)
glDefine(glDetachShader)
glDefine(glLinkProgram)
glDefine(glGetProgramiv)
glDefine(glGetProgramInfoLog)
glDefine(glUseProgram)
' uniform
glDefine(glGetUniformLocation)
glDefine(glUniform1f)
glDefine(glUniform2f)
glDefine(glUniform3f)
glDefine(glUniform4f)
glDefine(glUniform1i)
#undef glDefine

sub glScreen(w as integer=640, h as integer=360, b as integer=32, d as integer=24, s as integer=0, f as integer=0)
  if ScreenPtr() then screen 0
  ScreenControl FB.SET_GL_STENCIL_BITS,s
  ScreenControl FB.SET_GL_DEPTH_BITS  ,d
  if ScreenRes(w,h,b,,FB.GFX_OPENGL or iif(f<>0,FB.GFX_FULLSCREEN,0)) then
    ErrorExit("screenres(" & w & "," & h &") failed !")
  end if
  Windowtitle "offline shadertoy.com"

  flip
  ' get OpenGL proc's (abort if something goes wrong)
  #define glProc(n) n = ScreenGLProc(#n) : if n = 0 then ErrorExit(#n)
  ' texture
  'glProc(glActiveTexture)
  ' shader
  glProc(glCreateShader)
  glProc(glDeleteShader)
  glProc(glShaderSource)
  glProc(glCompileShader)
  glProc(glGetShaderiv)
  glProc(glGetShaderInfoLog)
  ' program
  glProc(glCreateProgram)
  glProc(glDeleteProgram)
  glProc(glAttachShader)
  glProc(glDetachShader)
  glProc(glLinkProgram)
  glProc(glGetProgramiv)
  glProc(glGetProgramInfoLog)
  glProc(glUseProgram)
  ' uniform
  glProc(glGetUniformLocation)
  glProc(glUniform1f)
  glProc(glUniform2f)
  glProc(glUniform3f)
  glProc(glUniform4f)
  glProc(glUniform1i)
  #undef glProc
end sub

type ShaderToy
  declare destructor
  declare function CompileFile(Filename as string) as boolean
  declare function CompileCode(Code as string) as boolean
  as GLuint FragmentShader
  as GLuint ProgramObject
  as string Shaderlog
end type
destructor ShaderToy
  if ProgramObject then 
   glUseprogram(0)
   if FragmentShader  then 
     glDetachShader(ProgramObject,FragmentShader)
     glDeleteShader(FragmentShader)
   end if
   glDeleteProgram(ProgramObject)
  end if
end destructor

function ShaderToy.CompileFile(filename as string) as boolean
  dim as string code
  var hFile = FreeFile()
  if open(filename,for input, as #hFile) then 
    ShaderLog = "can't read shader: " & chr(34) & filename  & chr(34) & " !"
    return false
  end if
  while not eof(hFile)
    dim as string aLine
    line input #hFile,aLine
    code &= aLine & !"\n"
  wend
  close #hFile
  return CompileCode(code)
end function

function ShaderToy.CompileCode(UserCode as string) as boolean
  dim as GLint logSize
  dim as GLint status
  dim as string FragmentProlog
  FragmentProlog & =!"uniform float     iGlobalTime;  // shader playback time (in seconds)\n"
  FragmentProlog & =!"uniform vec3      iResolution;  // viewport resolution (in pixels)\n"
  FragmentProlog & =!"uniform vec4      iMouse;       // mouse pixel coords. xy: current (if MLB down), zw: click\n"
  FragmentProlog & =!"uniform vec4      iDate;        // (year, month, day, time in seconds)\n"
  FragmentProlog & =!"uniform sampler2D iChannel0;\n"
  FragmentProlog & =!"uniform sampler2D iChannel1;\n"
  FragmentProlog & =!"uniform sampler2D iChannel2;\n"
  FragmentProlog & =!"uniform sampler2D iChannel3;\n"
  dim as string FragmentEpilog
  FragmentEpilog &= !"void main() {\n"
  FragmentEpilog &= !"  vec4 color;\n"
  FragmentEpilog &= !"  // call user shader\n"
  FragmentEpilog &= !"  mainImage(color, gl_FragCoord.xy);\n"
  FragmentEpilog &= !"  color.w = 1.0;\n"
  FragmentEpilog &= !"  gl_FragColor = color;\n"
  FragmentEpilog &= !"}\n"

  dim as string FragmentCode = FragmentProlog & UserCode & FragmentEpilog

  FragmentShader = glCreateShader(GL_FRAGMENT_SHADER)
  if FragmentShader=0 then 
    ShaderLog = "glCreateShader(GL_FRAGMENT_SHADER) failed !"
    return false
  end if
  dim as GLchar ptr pCode=strptr(FragmentCode)
  glShaderSource (FragmentShader, 1, @pCode, NULL)
  glCompileShader(FragmentShader)
  glGetShaderiv  (FragmentShader, GL_COMPILE_STATUS, @status)
  if status = GL_FALSE then 
    glGetShaderiv(FragmentShader, GL_INFO_LOG_LENGTH, @logSize)
    ShaderLog = space(logSize)
    glGetShaderInfoLog(FragmentShader, logSize, NULL, cptr(GLchar ptr,strptr(ShaderLog)) )
    ShaderLog = !"glCompileShader(FragmentShader) failed !\n" & Shaderlog
    glDeleteShader(FragmentShader) : FragmentShader = 0
    return false
  end if

  ProgramObject = glCreateProgram()
  if ProgramObject=0 then 
    ShaderLog = "glCreateProgram() failed !"
    glDeleteShader(FragmentShader) : FragmentShader = 0
    return false
  end if
  glAttachShader(ProgramObject,FragmentShader)
  glLinkProgram (ProgramObject)
  glGetProgramiv(ProgramObject, GL_LINK_STATUS, @status)
  if (status = GL_FALSE) then
    glGetProgramiv(ProgramObject, GL_INFO_LOG_LENGTH, @logSize)
    ShaderLog = space(logSize)
    glGetProgramInfoLog (ProgramObject, logSize, NULL, cptr(GLchar ptr,strptr(ShaderLog)) )
    ShaderLog = !"glLinkProgram() failed !\n" & Shaderlog
    glDeleteShader(FragmentShader) : FragmentShader = 0
    return false
  end if
  return true
end function

'
' main
'


' init Screenres, create the OpenGL context and load some OpenGL procs.
dim as integer pixels=640
' wide screen 16:9
glScreen pixels,pixels/16*9


' get curent resolution
dim as integer scr_w,scr_h
screeninfo scr_w,scr_h

dim as vec3 v3
v3.x=scr_w     ' width in pixle
v3.y=scr_h     '`height in pixle
v3.z=v3.x/v3.y ' pixel ratio

dim as ShaderToy Shader

if Shader.CompileCode(SCODE)=false then
  ErrorExit Shader.ShaderLog
end if  

' enable shader
glUseProgram(Shader.ProgramObject)

' get uniforms locations in shader program
var iGlobalTime = glGetUniformLocation(Shader.ProgramObject,"iGlobalTime")
var iResolution = glGetUniformLocation(Shader.ProgramObject,"iResolution")
var iMouse      = glGetUniformLocation(Shader.ProgramObject,"iMouse")

' set vec3 iResolution
glUniform3f(iResolution,v3.x,v3.y,v3.z)

dim as integer mx,my,mb,frames,fps
dim as double tStart = Timer()
dim as double tLast=tStart
while inkey=""
  dim as double tNow=Timer()
  ' set uniform float iGlobalTime
  glUniform1f(iGlobalTime,tNow-tStart)
/'
  if frames mod 3=0 then
    ' set vec4 iMouse
    if getMouse(mx,my,,mb)=0 then
      if mb then
        glUniform4f(iResolution,mx,scr_h-my,1,1)
      else
        glUniform4f(iResolution,0,0,0,0)
      end if
    end if
  end if
'/

  'glClear(GL_COLOR_BUFFER_BIT)

  ' draw a rectangle (2 triangles over the whole screen)
  glRectf(-1,-1,1,1)
  flip ' swap the buffers

  frames+=1
  ' update fps
  if frames mod 24=0 then
    fps=24/(tNow-tLast)
    windowtitle "fps: " & fps
    tLast=tNow
  end if

wend

' disable shader
glUseProgram(0)
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: [solved] Can you post your FPS result please ?

Post by paul doe »

srvaldez wrote:Kirby Jump
Created by fizzer https://www.shadertoy.com/view/lt2fD3
Nice! My daughter loves Kirby (I do too, so what!) but there seems to be a problem:
Image
I tested it in my shadertoy implementation and the result is the same. Is it just me, or do you get these results as well? Translated the code by hand or by program?
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: [solved] Can you post your FPS result please ?

Post by srvaldez »

no problems here, I simply wrote a small program to add the string quotes.
tested on my Mac.
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: [solved] Can you post your FPS result please ?

Post by paul doe »

Funny thing is, this same code on the browser doesn't give me any troubles. I'll have to take a look to see what the problem is. Thanks.
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: Can you post your FPS result please ?

Post by srvaldez »

@Paul doe
srvaldez wrote:on my Mac I get a steady 60 fps but I had to comment-out lines 279 and 318 --duplicate definition of glDefine(glActiveTexture) and lines 486 thru 495 as fb on mac has no mouse lib yet.
perhaps if you uncomment those lines?
Post Reply