Fix the Julia set shader example (#3467)
* Simplify POI selection * Improve mouse logic * Add colour cycles to the shader to show finer details. Works well with high iteration numbers * Testing things... * Actually fix zoom. Also allow user to reset camera with 'R' * Reset max iterations * Tidying & comments * Revert to original if statement * Make mouse logic more readable * Style conventions * Coding conventions - f postifx on floating points * Missed a few f postfixes
This commit is contained in:
parent
b4865588f8
commit
975d4154e6
3 changed files with 89 additions and 79 deletions
|
@ -6,30 +6,30 @@ precision mediump float;
|
||||||
varying vec2 fragTexCoord;
|
varying vec2 fragTexCoord;
|
||||||
varying vec4 fragColor;
|
varying vec4 fragColor;
|
||||||
|
|
||||||
uniform vec2 screenDims; // Dimensions of the screen
|
|
||||||
uniform vec2 c; // c.x = real, c.y = imaginary component. Equation done is z^2 + c
|
uniform vec2 c; // c.x = real, c.y = imaginary component. Equation done is z^2 + c
|
||||||
uniform vec2 offset; // Offset of the scale.
|
uniform vec2 offset; // Offset of the scale.
|
||||||
uniform float zoom; // Zoom of the scale.
|
uniform float zoom; // Zoom of the scale.
|
||||||
|
|
||||||
// NOTE: Maximum number of shader for-loop iterations depend on GPU,
|
// NOTE: Maximum number of shader for-loop iterations depend on GPU,
|
||||||
// for example, on RasperryPi for this examply only supports up to 60
|
// for example, on RasperryPi for this examply only supports up to 60
|
||||||
const int MAX_ITERATIONS = 48; // Max iterations to do
|
const int maxIterations = 48; // Max iterations to do.
|
||||||
|
const float colorCycles = 1.0f; // Number of times the color palette repeats.
|
||||||
|
|
||||||
// Square a complex number
|
// Square a complex number
|
||||||
vec2 ComplexSquare(vec2 z)
|
vec2 ComplexSquare(vec2 z)
|
||||||
{
|
{
|
||||||
return vec2(
|
return vec2(
|
||||||
z.x * z.x - z.y * z.y,
|
z.x*z.x - z.y*z.y,
|
||||||
z.x * z.y * 2.0
|
z.x*z.y*2.0f
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert Hue Saturation Value (HSV) color into RGB
|
// Convert Hue Saturation Value (HSV) color into RGB
|
||||||
vec3 Hsv2rgb(vec3 c)
|
vec3 Hsv2rgb(vec3 c)
|
||||||
{
|
{
|
||||||
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
vec4 K = vec4(1.0f, 2.0f/3.0f, 1.0f/3.0f, 3.0f);
|
||||||
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
vec3 p = abs(fract(c.xxx + K.xyz)*6.0f - K.www);
|
||||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
return c.z*mix(K.xxx, clamp(p - K.xxx, 0.0f, 1.0f), c.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
|
@ -45,8 +45,8 @@ void main()
|
||||||
|
|
||||||
If the number is below 2, we keep iterating.
|
If the number is below 2, we keep iterating.
|
||||||
But when do we stop iterating if the number is always below 2 (it converges)?
|
But when do we stop iterating if the number is always below 2 (it converges)?
|
||||||
That is what MAX_ITERATIONS is for.
|
That is what maxIterations is for.
|
||||||
Then we can divide the iterations by the MAX_ITERATIONS value to get a normalized value that we can
|
Then we can divide the iterations by the maxIterations value to get a normalized value that we can
|
||||||
then map to a color.
|
then map to a color.
|
||||||
|
|
||||||
We use dot product (z.x * z.x + z.y * z.y) to determine the magnitude (length) squared.
|
We use dot product (z.x * z.x + z.y * z.y) to determine the magnitude (length) squared.
|
||||||
|
@ -55,13 +55,15 @@ void main()
|
||||||
|
|
||||||
// The pixel coordinates are scaled so they are on the mandelbrot scale
|
// The pixel coordinates are scaled so they are on the mandelbrot scale
|
||||||
// NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom
|
// NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom
|
||||||
vec2 z = vec2((fragTexCoord.x + offset.x/screenDims.x)*2.5/zoom, (fragTexCoord.y + offset.y/screenDims.y)*1.5/zoom);
|
vec2 z = vec2((fragTexCoord.x - 0.5f)*2.5f, (fragTexCoord.y - 0.5f)*1.5f)/zoom;
|
||||||
|
z.x += offset.x;
|
||||||
|
z.y += offset.y;
|
||||||
|
|
||||||
int iter = 0;
|
int iter = 0;
|
||||||
for (int iterations = 0; iterations < 60; iterations++)
|
for (int iterations = 0; iterations < 60; iterations++)
|
||||||
{
|
{
|
||||||
z = ComplexSquare(z) + c; // Iterate function
|
z = ComplexSquare(z) + c; // Iterate function
|
||||||
if (dot(z, z) > 4.0) break;
|
if (dot(z, z) > 4.0f) break;
|
||||||
|
|
||||||
iter = iterations;
|
iter = iterations;
|
||||||
}
|
}
|
||||||
|
@ -72,12 +74,12 @@ void main()
|
||||||
z = ComplexSquare(z) + c;
|
z = ComplexSquare(z) + c;
|
||||||
|
|
||||||
// This last part smooths the color (again see link above).
|
// This last part smooths the color (again see link above).
|
||||||
float smoothVal = float(iter) + 1.0 - (log(log(length(z)))/log(2.0));
|
float smoothVal = float(iter) + 1.0f - (log(log(length(z)))/log(2.0f));
|
||||||
|
|
||||||
// Normalize the value so it is between 0 and 1.
|
// Normalize the value so it is between 0 and 1.
|
||||||
float norm = smoothVal/float(MAX_ITERATIONS);
|
float norm = smoothVal/float(maxIterations);
|
||||||
|
|
||||||
// If in set, color black. 0.999 allows for some float accuracy error.
|
// If in set, color black. 0.999 allows for some float accuracy error.
|
||||||
if (norm > 0.999) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
if (norm > 0.999f) gl_FragColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
else gl_FragColor = vec4(Hsv2rgb(vec3(norm, 1.0, 1.0)), 1.0);
|
else gl_FragColor = vec4(Hsv2rgb(vec3(norm*colorCycles, 1.0f, 1.0f)), 1.0f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,28 +7,28 @@ in vec4 fragColor;
|
||||||
// Output fragment color
|
// Output fragment color
|
||||||
out vec4 finalColor;
|
out vec4 finalColor;
|
||||||
|
|
||||||
uniform vec2 screenDims; // Dimensions of the screen
|
|
||||||
uniform vec2 c; // c.x = real, c.y = imaginary component. Equation done is z^2 + c
|
uniform vec2 c; // c.x = real, c.y = imaginary component. Equation done is z^2 + c
|
||||||
uniform vec2 offset; // Offset of the scale.
|
uniform vec2 offset; // Offset of the scale.
|
||||||
uniform float zoom; // Zoom of the scale.
|
uniform float zoom; // Zoom of the scale.
|
||||||
|
|
||||||
const int MAX_ITERATIONS = 255; // Max iterations to do.
|
const int maxIterations = 255; // Max iterations to do.
|
||||||
|
const float colorCycles = 2.0f; // Number of times the color palette repeats. Can show higher detail for higher iteration numbers.
|
||||||
|
|
||||||
// Square a complex number
|
// Square a complex number
|
||||||
vec2 ComplexSquare(vec2 z)
|
vec2 ComplexSquare(vec2 z)
|
||||||
{
|
{
|
||||||
return vec2(
|
return vec2(
|
||||||
z.x * z.x - z.y * z.y,
|
z.x*z.x - z.y*z.y,
|
||||||
z.x * z.y * 2.0
|
z.x*z.y*2.0f
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert Hue Saturation Value (HSV) color into RGB
|
// Convert Hue Saturation Value (HSV) color into RGB
|
||||||
vec3 Hsv2rgb(vec3 c)
|
vec3 Hsv2rgb(vec3 c)
|
||||||
{
|
{
|
||||||
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
vec4 K = vec4(1.0f, 2.0f/3.0f, 1.0f/3.0f, 3.0f);
|
||||||
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
vec3 p = abs(fract(c.xxx + K.xyz)*6.0f - K.www);
|
||||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
return c.z*mix(K.xxx, clamp(p - K.xxx, 0.0f, 1.0f), c.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
|
@ -44,8 +44,8 @@ void main()
|
||||||
|
|
||||||
If the number is below 2, we keep iterating.
|
If the number is below 2, we keep iterating.
|
||||||
But when do we stop iterating if the number is always below 2 (it converges)?
|
But when do we stop iterating if the number is always below 2 (it converges)?
|
||||||
That is what MAX_ITERATIONS is for.
|
That is what maxIterations is for.
|
||||||
Then we can divide the iterations by the MAX_ITERATIONS value to get a normalized value that we can
|
Then we can divide the iterations by the maxIterations value to get a normalized value that we can
|
||||||
then map to a color.
|
then map to a color.
|
||||||
|
|
||||||
We use dot product (z.x * z.x + z.y * z.y) to determine the magnitude (length) squared.
|
We use dot product (z.x * z.x + z.y * z.y) to determine the magnitude (length) squared.
|
||||||
|
@ -54,14 +54,16 @@ void main()
|
||||||
|
|
||||||
// The pixel coordinates are scaled so they are on the mandelbrot scale
|
// The pixel coordinates are scaled so they are on the mandelbrot scale
|
||||||
// NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom
|
// NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom
|
||||||
vec2 z = vec2((fragTexCoord.x + offset.x/screenDims.x)*2.5/zoom, (fragTexCoord.y + offset.y/screenDims.y)*1.5/zoom);
|
vec2 z = vec2((fragTexCoord.x - 0.5f)*2.5f, (fragTexCoord.y - 0.5f)*1.5f)/zoom;
|
||||||
|
z.x += offset.x;
|
||||||
|
z.y += offset.y;
|
||||||
|
|
||||||
int iterations = 0;
|
int iterations = 0;
|
||||||
for (iterations = 0; iterations < MAX_ITERATIONS; iterations++)
|
for (iterations = 0; iterations < maxIterations; iterations++)
|
||||||
{
|
{
|
||||||
z = ComplexSquare(z) + c; // Iterate function
|
z = ComplexSquare(z) + c; // Iterate function
|
||||||
|
|
||||||
if (dot(z, z) > 4.0) break;
|
if (dot(z, z) > 4.0f) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Another few iterations decreases errors in the smoothing calculation.
|
// Another few iterations decreases errors in the smoothing calculation.
|
||||||
|
@ -70,12 +72,12 @@ void main()
|
||||||
z = ComplexSquare(z) + c;
|
z = ComplexSquare(z) + c;
|
||||||
|
|
||||||
// This last part smooths the color (again see link above).
|
// This last part smooths the color (again see link above).
|
||||||
float smoothVal = float(iterations) + 1.0 - (log(log(length(z)))/log(2.0));
|
float smoothVal = float(iterations) + 1.0f - (log(log(length(z)))/log(2.0f));
|
||||||
|
|
||||||
// Normalize the value so it is between 0 and 1.
|
// Normalize the value so it is between 0 and 1.
|
||||||
float norm = smoothVal/float(MAX_ITERATIONS);
|
float norm = smoothVal/float(maxIterations);
|
||||||
|
|
||||||
// If in set, color black. 0.999 allows for some float accuracy error.
|
// If in set, color black. 0.999 allows for some float accuracy error.
|
||||||
if (norm > 0.999) finalColor = vec4(0.0, 0.0, 0.0, 1.0);
|
if (norm > 0.999f) finalColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
else finalColor = vec4(Hsv2rgb(vec3(norm, 1.0, 1.0)), 1.0);
|
else finalColor = vec4(Hsv2rgb(vec3(norm*colorCycles, 1.0f, 1.0f)), 1.0f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,12 @@
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 2.5, last time updated with raylib 4.0
|
* Example originally created with raylib 2.5, last time updated with raylib 4.0
|
||||||
*
|
*
|
||||||
* Example contributed by eggmund (@eggmund) and reviewed by Ramon Santamaria (@raysan5)
|
* Example contributed by Josh Colclough (@joshcol9232) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
* BSD-like license that allows static linking with closed source software
|
* BSD-like license that allows static linking with closed source software
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019-2023 eggmund (@eggmund) and Ramon Santamaria (@raysan5)
|
* Copyright (c) 2019-2023 Josh Colclough (@joshcol9232) and Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
********************************************************************************************/
|
********************************************************************************************/
|
||||||
|
|
||||||
|
@ -37,6 +37,13 @@ const float pointsOfInterest[6][2] =
|
||||||
{ -0.70176f, -0.3842f },
|
{ -0.70176f, -0.3842f },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
const float zoomSpeed = 1.01f;
|
||||||
|
const float offsetSpeedMul = 2.0f;
|
||||||
|
|
||||||
|
const float startingZoom = 0.75f;
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Program main entry point
|
// Program main entry point
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
|
@ -44,10 +51,6 @@ int main(void)
|
||||||
{
|
{
|
||||||
// Initialization
|
// Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
const int screenWidth = 800;
|
|
||||||
const int screenHeight = 450;
|
|
||||||
|
|
||||||
//SetConfigFlags(FLAG_WINDOW_HIGHDPI);
|
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - julia sets");
|
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - julia sets");
|
||||||
|
|
||||||
// Load julia set shader
|
// Load julia set shader
|
||||||
|
@ -61,10 +64,8 @@ int main(void)
|
||||||
float c[2] = { pointsOfInterest[0][0], pointsOfInterest[0][1] };
|
float c[2] = { pointsOfInterest[0][0], pointsOfInterest[0][1] };
|
||||||
|
|
||||||
// Offset and zoom to draw the julia set at. (centered on screen and default size)
|
// Offset and zoom to draw the julia set at. (centered on screen and default size)
|
||||||
float offset[2] = { -(float)GetScreenWidth()/2, -(float)GetScreenHeight()/2 };
|
float offset[2] = { 0.0f, 0.0f };
|
||||||
float zoom = 1.0f;
|
float zoom = startingZoom;
|
||||||
|
|
||||||
Vector2 offsetSpeed = { 0.0f, 0.0f };
|
|
||||||
|
|
||||||
// Get variable (uniform) locations on the shader to connect with the program
|
// Get variable (uniform) locations on the shader to connect with the program
|
||||||
// NOTE: If uniform variable could not be found in the shader, function returns -1
|
// NOTE: If uniform variable could not be found in the shader, function returns -1
|
||||||
|
@ -72,17 +73,13 @@ int main(void)
|
||||||
int zoomLoc = GetShaderLocation(shader, "zoom");
|
int zoomLoc = GetShaderLocation(shader, "zoom");
|
||||||
int offsetLoc = GetShaderLocation(shader, "offset");
|
int offsetLoc = GetShaderLocation(shader, "offset");
|
||||||
|
|
||||||
// Tell the shader what the screen dimensions, zoom, offset and c are
|
// Upload the shader uniform values!
|
||||||
float screenDims[2] = { (float)GetScreenWidth(), (float)GetScreenHeight() };
|
|
||||||
SetShaderValue(shader, GetShaderLocation(shader, "screenDims"), screenDims, SHADER_UNIFORM_VEC2);
|
|
||||||
|
|
||||||
SetShaderValue(shader, cLoc, c, SHADER_UNIFORM_VEC2);
|
SetShaderValue(shader, cLoc, c, SHADER_UNIFORM_VEC2);
|
||||||
SetShaderValue(shader, zoomLoc, &zoom, SHADER_UNIFORM_FLOAT);
|
SetShaderValue(shader, zoomLoc, &zoom, SHADER_UNIFORM_FLOAT);
|
||||||
SetShaderValue(shader, offsetLoc, offset, SHADER_UNIFORM_VEC2);
|
SetShaderValue(shader, offsetLoc, offset, SHADER_UNIFORM_VEC2);
|
||||||
|
|
||||||
int incrementSpeed = 0; // Multiplier of speed to change c value
|
int incrementSpeed = 0; // Multiplier of speed to change c value
|
||||||
bool showControls = true; // Show controls
|
bool showControls = true; // Show controls
|
||||||
bool pause = false; // Pause animation
|
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
@ -110,42 +107,50 @@ int main(void)
|
||||||
SetShaderValue(shader, cLoc, c, SHADER_UNIFORM_VEC2);
|
SetShaderValue(shader, cLoc, c, SHADER_UNIFORM_VEC2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsKeyPressed(KEY_SPACE)) pause = !pause; // Pause animation (c change)
|
// If "R" is pressed, reset zoom and offset.
|
||||||
if (IsKeyPressed(KEY_F1)) showControls = !showControls; // Toggle whether or not to show controls
|
if (IsKeyPressed(KEY_R))
|
||||||
|
|
||||||
if (!pause)
|
|
||||||
{
|
{
|
||||||
if (IsKeyPressed(KEY_RIGHT)) incrementSpeed++;
|
zoom = startingZoom;
|
||||||
else if (IsKeyPressed(KEY_LEFT)) incrementSpeed--;
|
offset[0] = 0.0f;
|
||||||
|
offset[1] = 0.0f;
|
||||||
// TODO: The idea is to zoom and move around with mouse
|
|
||||||
// Probably offset movement should be proportional to zoom level
|
|
||||||
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT) || IsMouseButtonDown(MOUSE_BUTTON_RIGHT))
|
|
||||||
{
|
|
||||||
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) zoom += zoom*0.003f;
|
|
||||||
if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) zoom -= zoom*0.003f;
|
|
||||||
|
|
||||||
Vector2 mousePos = GetMousePosition();
|
|
||||||
|
|
||||||
offsetSpeed.x = mousePos.x -(float)screenWidth/2;
|
|
||||||
offsetSpeed.y = mousePos.y -(float)screenHeight/2;
|
|
||||||
|
|
||||||
// Slowly move camera to targetOffset
|
|
||||||
offset[0] += GetFrameTime()*offsetSpeed.x*0.8f;
|
|
||||||
offset[1] += GetFrameTime()*offsetSpeed.y*0.8f;
|
|
||||||
}
|
|
||||||
else offsetSpeed = (Vector2){ 0.0f, 0.0f };
|
|
||||||
|
|
||||||
SetShaderValue(shader, zoomLoc, &zoom, SHADER_UNIFORM_FLOAT);
|
SetShaderValue(shader, zoomLoc, &zoom, SHADER_UNIFORM_FLOAT);
|
||||||
SetShaderValue(shader, offsetLoc, offset, SHADER_UNIFORM_VEC2);
|
SetShaderValue(shader, offsetLoc, offset, SHADER_UNIFORM_VEC2);
|
||||||
|
|
||||||
// Increment c value with time
|
|
||||||
float amount = GetFrameTime()*incrementSpeed*0.0005f;
|
|
||||||
c[0] += amount;
|
|
||||||
c[1] += amount;
|
|
||||||
|
|
||||||
SetShaderValue(shader, cLoc, c, SHADER_UNIFORM_VEC2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_SPACE)) incrementSpeed = 0; // Pause animation (c change)
|
||||||
|
if (IsKeyPressed(KEY_F1)) showControls = !showControls; // Toggle whether or not to show controls
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_RIGHT)) incrementSpeed++;
|
||||||
|
else if (IsKeyPressed(KEY_LEFT)) incrementSpeed--;
|
||||||
|
|
||||||
|
// If either left or right button is pressed, zoom in/out.
|
||||||
|
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT) || IsMouseButtonDown(MOUSE_BUTTON_RIGHT))
|
||||||
|
{
|
||||||
|
// Change zoom. If Mouse left -> zoom in. Mouse right -> zoom out.
|
||||||
|
zoom *= IsMouseButtonDown(MOUSE_BUTTON_LEFT)? zoomSpeed : 1.0f/zoomSpeed;
|
||||||
|
|
||||||
|
const Vector2 mousePos = GetMousePosition();
|
||||||
|
Vector2 offsetVelocity;
|
||||||
|
// Find the velocity at which to change the camera. Take the distance of the mouse
|
||||||
|
// from the center of the screen as the direction, and adjust magnitude based on
|
||||||
|
// the current zoom.
|
||||||
|
offsetVelocity.x = (mousePos.x/(float)screenWidth - 0.5f)*offsetSpeedMul/zoom;
|
||||||
|
offsetVelocity.y = (mousePos.y/(float)screenHeight - 0.5f)*offsetSpeedMul/zoom;
|
||||||
|
|
||||||
|
// Apply move velocity to camera
|
||||||
|
offset[0] += GetFrameTime()*offsetVelocity.x;
|
||||||
|
offset[1] += GetFrameTime()*offsetVelocity.y;
|
||||||
|
|
||||||
|
// Update the shader uniform values!
|
||||||
|
SetShaderValue(shader, zoomLoc, &zoom, SHADER_UNIFORM_FLOAT);
|
||||||
|
SetShaderValue(shader, offsetLoc, offset, SHADER_UNIFORM_VEC2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment c value with time
|
||||||
|
const float dc = GetFrameTime()*(float)incrementSpeed*0.0005f;
|
||||||
|
c[0] += dc;
|
||||||
|
c[1] += dc;
|
||||||
|
SetShaderValue(shader, cLoc, c, SHADER_UNIFORM_VEC2);
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
|
@ -178,7 +183,8 @@ int main(void)
|
||||||
DrawText("Press KEY_F1 to toggle these controls", 10, 30, 10, RAYWHITE);
|
DrawText("Press KEY_F1 to toggle these controls", 10, 30, 10, RAYWHITE);
|
||||||
DrawText("Press KEYS [1 - 6] to change point of interest", 10, 45, 10, RAYWHITE);
|
DrawText("Press KEYS [1 - 6] to change point of interest", 10, 45, 10, RAYWHITE);
|
||||||
DrawText("Press KEY_LEFT | KEY_RIGHT to change speed", 10, 60, 10, RAYWHITE);
|
DrawText("Press KEY_LEFT | KEY_RIGHT to change speed", 10, 60, 10, RAYWHITE);
|
||||||
DrawText("Press KEY_SPACE to pause movement animation", 10, 75, 10, RAYWHITE);
|
DrawText("Press KEY_SPACE to stop movement animation", 10, 75, 10, RAYWHITE);
|
||||||
|
DrawText("Press KEY_R to recenter the camera", 10, 90, 10, RAYWHITE);
|
||||||
}
|
}
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue