{$apptype console}
program julia_fractal; uses GL, GLU, GLEXT, Glut;
var
ShaderProgram,TextureID: GLuint;
// Julia C const
Cx: Single = -0.7;
Cy: Single = 0.27015;
Zoom: Single = 3.0;
VertSrc:PChar =
'varying vec2 vTexCoord;'#10+
'void main() {'#10+
'vTexCoord = gl_MultiTexCoord0.xy;'#10+
'gl_Position = ftransform();'#10+
'}'#10;
FragSrc:PChar=
'varying vec2 vTexCoord;'#10+
'uniform vec2 u_center;'#10+
'uniform float u_zoom,u_cx,u_cy;'#10+
'uniform sampler2D u_pal;'#10+
'void main() {'#10+
'float x = (vTexCoord.x - 0.5) * u_zoom;'#10+
'float y = (vTexCoord.y - 0.5) * u_zoom;'#10+
'for (int i = 0; i < 20; i++) {'#10+
//PLAZMA CUB: (x * x) + (y * y)
'float t = (x * x) - (y * y) + u_cx;'#10+
'y = (x + x) * y + u_cy;'#10+
'x = t;'#10+
'}'#10+
'gl_FragColor = texture2D(u_pal, vec2(x, y) * 0.5 + vec2(0.5, 0.5));'#10+
'}';
procedure GenTexture;
var
TextureData: array[0..255, 0..2] of Byte;
i: Integer;
begin
randomize;
for i := 0 to 255 do
begin
TextureData[i, 0] := random(255);
TextureData[i, 1] := random(255);
TextureData[i, 2] := random(255);
end;
glGenTextures(1, @TextureID);
glBindTexture(GL_TEXTURE_2D, TextureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, @TextureData);
glBindTexture(GL_TEXTURE_2D, 0);
end;
procedure InitShaders;
var
VertShader, FragShader: GLuint;
Compiled, Linked: GLint;
begin
VertShader := glCreateShader(GL_VERTEX_SHADER);
glShaderSource(VertShader, 1, @VertSrc, nil);
glCompileShader(VertShader);
glGetShaderiv(VertShader, GL_COMPILE_STATUS, @Compiled);
if Compiled = GL_FALSE then Halt(1);
FragShader := glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(FragShader, 1, @FragSrc, nil);
glCompileShader(FragShader);
glGetShaderiv(FragShader, GL_COMPILE_STATUS, @Compiled);
if Compiled = GL_FALSE then Halt(1);
ShaderProgram := glCreateProgram();
glAttachShader(ShaderProgram, VertShader);
glAttachShader(ShaderProgram, FragShader);
glLinkProgram(ShaderProgram);
glGetProgramiv(ShaderProgram, GL_LINK_STATUS, @Linked);
if Linked = GL_FALSE then Halt(1);
glDeleteShader(VertShader);
glDeleteShader(FragShader);
glUseProgram(ShaderProgram);
end;
procedure DisplayProc; cdecl;
var
LocZoom,LocCx,LocCy,LocPalette: GLint;
begin
LocCx := glGetUniformLocation(ShaderProgram, 'u_cx');
LocCy := glGetUniformLocation(ShaderProgram, 'u_cy');
LocZoom := glGetUniformLocation(ShaderProgram, 'u_zoom');
glUniform1f(LocZoom, Zoom);
glUniform1f(LocCx, Cx);
glUniform1f(LocCy, Cy);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, TextureID);
LocPalette := glGetUniformLocation(ShaderProgram, 'u_pal');
glUniform1i(LocPalette, 0);
glBegin(GL_QUADS);
glMultiTexCoord2f(GL_TEXTURE0, 0.0, 0.0); glVertex2f(-1.0, -1.0);
glMultiTexCoord2f(GL_TEXTURE0, 1.0, 0.0); glVertex2f( 1.0, -1.0);
glMultiTexCoord2f(GL_TEXTURE0, 1.0, 1.0); glVertex2f( 1.0, 1.0);
glMultiTexCoord2f(GL_TEXTURE0, 0.0, 1.0); glVertex2f(-1.0, 1.0);
glEnd();
glutSwapBuffers();
end;
procedure ReshapeProc(w, h: Integer); cdecl;
begin
glViewport(0, 0, w, h);
end;
procedure PassiveMotionProc(x, y: Integer); cdecl;
begin
Cx := (x / glutGet(GLUT_WINDOW_WIDTH)) * 2.0 - 1.0;
Cy := (y / glutGet(GLUT_WINDOW_HEIGHT)) * 2.0 - 1.0;
glutPostRedisplay();
end;
procedure KeyboardProc(key: Byte; x, y: Integer); cdecl;
begin
case Chr(key) of
'+', '=': Zoom := Zoom * 0.85;
'-': Zoom := Zoom * 1.15;
'r','R': GenTexture;
#27: Halt(0);
end;
glutPostRedisplay();
end;
begin
glutInit(@argc, argv);
glutInitDisplayMode(GLUT_DOUBLE or GLUT_RGB or GLUT_DEPTH);
glutInitWindowSize(512, 512);
glutCreateWindow('Julia Set OpenGL 2.0');
glext_LoadExtension('GL_version_2_0');
glutDisplayFunc(@DisplayProc);
glutReshapeFunc(@ReshapeProc);
glutKeyboardFunc(@KeyboardProc);
glutPassiveMotionFunc(@PassiveMotionProc);
InitShaders; GenTexture;
glClearColor(0.0, 0.0, 0.0, 1.0);
glutMainLoop();
end.