Merge remote-tracking branch 'refs/remotes/raysan5/develop' into develop
This commit is contained in:
commit
80f6b2f963
@ -47,7 +47,7 @@ int main()
|
|||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
UpdateCamera(&camera); // Update camera and player position
|
UpdateCamera(&camera); // Update camera
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
|
@ -39,7 +39,7 @@ int main()
|
|||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
UpdateCamera(&camera); // Update internal camera and our camera
|
UpdateCamera(&camera); // Update camera
|
||||||
|
|
||||||
if (IsKeyDown('Z')) camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
|
if (IsKeyDown('Z')) camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
@ -22,7 +22,7 @@ int main()
|
|||||||
|
|
||||||
// Define the camera to look into our 3d world
|
// Define the camera to look into our 3d world
|
||||||
Camera camera;
|
Camera camera;
|
||||||
camera.position = (Vector3){ 0.0f, 10.0f, 10.0f }; // Camera position
|
camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position
|
||||||
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
|
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
|
||||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
||||||
camera.fovy = 45.0f; // Camera field-of-view Y
|
camera.fovy = 45.0f; // Camera field-of-view Y
|
||||||
@ -34,9 +34,7 @@ int main()
|
|||||||
|
|
||||||
bool collision = false;
|
bool collision = false;
|
||||||
|
|
||||||
SetCameraMode(CAMERA_FREE); // Set a free camera mode
|
SetCameraMode(camera, CAMERA_FREE); // Set a free camera mode
|
||||||
SetCameraPosition(camera.position); // Set internal camera position to match our camera position
|
|
||||||
SetCameraFovy(camera.fovy); // Set internal camera field-of-view Y
|
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
@ -46,7 +44,7 @@ int main()
|
|||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
UpdateCamera(&camera); // Update internal camera and our camera
|
UpdateCamera(&camera); // Update camera
|
||||||
|
|
||||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||||||
{
|
{
|
||||||
|
@ -30,13 +30,15 @@ int main()
|
|||||||
|
|
||||||
// Define the camera to look into our 3d world
|
// Define the camera to look into our 3d world
|
||||||
Camera camera;
|
Camera camera;
|
||||||
camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position
|
camera.position = (Vector3){ 5.0f, 2.0f, 5.0f }; // Camera position
|
||||||
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
|
camera.target = (Vector3){ 0.0f, 2.0f, 0.0f }; // Camera looking at point
|
||||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
||||||
camera.fovy = 60.0f; // Camera field-of-view Y
|
camera.fovy = 60.0f; // Camera field-of-view Y
|
||||||
|
|
||||||
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
|
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
|
||||||
|
|
||||||
|
SetCameraMode(camera, CAMERA_FIRST_PERSON); // Set first person camera mode
|
||||||
|
|
||||||
SetTargetFPS(90); // Set our game to run at 90 frames-per-second
|
SetTargetFPS(90); // Set our game to run at 90 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -45,9 +47,10 @@ int main()
|
|||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
UpdateVrTracking();
|
if (IsVrSimulator()) UpdateCamera(&camera); // Update camera (simulator mode)
|
||||||
|
else UpdateVrTracking(&camera); // Update camera with device tracking data
|
||||||
|
|
||||||
if (IsKeyPressed(KEY_SPACE)) ToggleVrMode();
|
if (IsKeyPressed(KEY_SPACE)) ToggleVrMode(); // Toggle VR mode
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
@ -61,7 +64,7 @@ int main()
|
|||||||
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
|
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
|
||||||
DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON);
|
DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON);
|
||||||
|
|
||||||
DrawGrid(10, 1.0f);
|
DrawGrid(40, 1.0f);
|
||||||
|
|
||||||
End3dMode();
|
End3dMode();
|
||||||
|
|
||||||
|
@ -21,16 +21,13 @@ int main()
|
|||||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera free");
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera free");
|
||||||
|
|
||||||
// Define the camera to look into our 3d world
|
// Define the camera to look into our 3d world
|
||||||
Camera camera = {{ 0.0f, 10.0f, 10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
|
Camera camera = {{ 10.0f, 10.0f, 10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
|
||||||
|
|
||||||
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
|
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
|
||||||
|
|
||||||
Vector2 cubeScreenPosition;
|
Vector2 cubeScreenPosition;
|
||||||
|
|
||||||
SetCameraMode(CAMERA_FREE); // Set a free camera mode
|
SetCameraMode(camera, CAMERA_FREE); // Set a free camera mode
|
||||||
SetCameraPosition(camera.position); // Set internal camera position to match our camera position
|
|
||||||
SetCameraTarget(camera.target); // Set internal camera target to match our camera target
|
|
||||||
SetCameraFovy(camera.fovy); // Set internal camera field-of-view Y
|
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
@ -40,7 +37,7 @@ int main()
|
|||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
UpdateCamera(&camera); // Update internal camera and our camera
|
UpdateCamera(&camera); // Update camera
|
||||||
|
|
||||||
// Calculate cube screen space position (with a little offset to be in top)
|
// Calculate cube screen space position (with a little offset to be in top)
|
||||||
cubeScreenPosition = GetWorldToScreen((Vector3){cubePosition.x, cubePosition.y + 2.5f, cubePosition.z}, camera);
|
cubeScreenPosition = GetWorldToScreen((Vector3){cubePosition.x, cubePosition.y + 2.5f, cubePosition.z}, camera);
|
||||||
|
@ -26,20 +26,17 @@ int main()
|
|||||||
Texture2D bill = LoadTexture("resources/billboard.png"); // Our texture billboard
|
Texture2D bill = LoadTexture("resources/billboard.png"); // Our texture billboard
|
||||||
Vector3 billPosition = { 0.0f, 2.0f, 0.0f }; // Position where draw billboard
|
Vector3 billPosition = { 0.0f, 2.0f, 0.0f }; // Position where draw billboard
|
||||||
|
|
||||||
SetCameraMode(CAMERA_ORBITAL); // Set an orbital camera mode
|
SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode
|
||||||
SetCameraPosition(camera.position); // Set internal camera position to match our camera position
|
|
||||||
SetCameraTarget(camera.target); // Set internal camera target to match our camera target
|
|
||||||
SetCameraFovy(camera.fovy); // Set internal camera field-of-view Y
|
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Main game loop
|
// Main game loop
|
||||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
UpdateCamera(&camera); // Update internal camera and our camera
|
UpdateCamera(&camera); // Update camera
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
|
@ -45,7 +45,7 @@ int main()
|
|||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
UpdateCamera(&camera); // Update internal camera and our camera
|
UpdateCamera(&camera); // Update camera
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
|
@ -29,20 +29,19 @@ int main()
|
|||||||
map.material.texDiffuse = texture; // Set map diffuse texture
|
map.material.texDiffuse = texture; // Set map diffuse texture
|
||||||
Vector3 mapPosition = { -8.0f, 0.0f, -8.0f }; // Set model position (depends on model scaling!)
|
Vector3 mapPosition = { -8.0f, 0.0f, -8.0f }; // Set model position (depends on model scaling!)
|
||||||
|
|
||||||
UnloadImage(image); // Unload heightmap image from RAM, already uploaded to VRAM
|
UnloadImage(image); // Unload heightmap image from RAM, already uploaded to VRAM
|
||||||
|
|
||||||
SetCameraMode(CAMERA_ORBITAL); // Set an orbital camera mode
|
SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode
|
||||||
SetCameraPosition(camera.position); // Set internal camera position to match our custom camera position
|
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Main game loop
|
// Main game loop
|
||||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
UpdateCamera(&camera); // Update internal camera and our camera
|
UpdateCamera(&camera); // Update camera
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
|
@ -38,7 +38,6 @@ uniform Light lights[maxLights];
|
|||||||
|
|
||||||
vec3 ComputeLightPoint(Light l, vec3 n, vec3 v, float s)
|
vec3 ComputeLightPoint(Light l, vec3 n, vec3 v, float s)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1.0));
|
vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1.0));
|
||||||
vec3 surfaceToLight = l.position - surfacePos;
|
vec3 surfaceToLight = l.position - surfacePos;
|
||||||
|
|
||||||
@ -51,17 +50,14 @@ vec3 ComputeLightPoint(Light l, vec3 n, vec3 v, float s)
|
|||||||
if (diff > 0.0)
|
if (diff > 0.0)
|
||||||
{
|
{
|
||||||
vec3 h = normalize(-l.direction + v);
|
vec3 h = normalize(-l.direction + v);
|
||||||
spec = pow(dot(n, h), 3.0 + glossiness)*s;
|
spec = pow(abs(dot(n, h)), 3.0 + glossiness)*s;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (diff*l.diffuse.rgb + spec*colSpecular.rgb);
|
return (diff*l.diffuse.rgb + spec*colSpecular.rgb);
|
||||||
*/
|
|
||||||
return vec3(0.5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 ComputeLightDirectional(Light l, vec3 n, vec3 v, float s)
|
vec3 ComputeLightDirectional(Light l, vec3 n, vec3 v, float s)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
vec3 lightDir = normalize(-l.direction);
|
vec3 lightDir = normalize(-l.direction);
|
||||||
|
|
||||||
// Diffuse shading
|
// Diffuse shading
|
||||||
@ -72,18 +68,15 @@ vec3 ComputeLightDirectional(Light l, vec3 n, vec3 v, float s)
|
|||||||
if (diff > 0.0)
|
if (diff > 0.0)
|
||||||
{
|
{
|
||||||
vec3 h = normalize(lightDir + v);
|
vec3 h = normalize(lightDir + v);
|
||||||
spec = pow(dot(n, h), 3.0 + glossiness)*s;
|
spec = pow(abs(dot(n, h)), 3.0 + glossiness)*s;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Combine results
|
// Combine results
|
||||||
return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb);
|
return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb);
|
||||||
*/
|
|
||||||
return vec3(0.5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 ComputeLightSpot(Light l, vec3 n, vec3 v, float s)
|
vec3 ComputeLightSpot(Light l, vec3 n, vec3 v, float s)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1));
|
vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1));
|
||||||
vec3 lightToSurface = normalize(surfacePos - l.position);
|
vec3 lightToSurface = normalize(surfacePos - l.position);
|
||||||
vec3 lightDir = normalize(-l.direction);
|
vec3 lightDir = normalize(-l.direction);
|
||||||
@ -108,12 +101,10 @@ vec3 ComputeLightSpot(Light l, vec3 n, vec3 v, float s)
|
|||||||
if (diffAttenuation > 0.0)
|
if (diffAttenuation > 0.0)
|
||||||
{
|
{
|
||||||
vec3 h = normalize(lightDir + v);
|
vec3 h = normalize(lightDir + v);
|
||||||
spec = pow(dot(n, h), 3.0 + glossiness)*s;
|
spec = pow(abs(dot(n, h)), 3.0 + glossiness)*s;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb));
|
return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb));
|
||||||
*/
|
|
||||||
return vec3(0.5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
@ -140,7 +131,7 @@ void main()
|
|||||||
|
|
||||||
// Calculate specular texture color fetching or set to maximum specular value by default
|
// Calculate specular texture color fetching or set to maximum specular value by default
|
||||||
float spec = 1.0;
|
float spec = 1.0;
|
||||||
if (useSpecular == 1) spec *= normalize(texture2D(texture2, fragTexCoord).r);
|
if (useSpecular == 1) spec = texture2D(texture2, fragTexCoord).r;
|
||||||
|
|
||||||
for (int i = 0; i < maxLights; i++)
|
for (int i = 0; i < maxLights; i++)
|
||||||
{
|
{
|
||||||
|
@ -50,7 +50,7 @@ vec3 ComputeLightPoint(Light l, vec3 n, vec3 v, float s)
|
|||||||
if (diff > 0.0)
|
if (diff > 0.0)
|
||||||
{
|
{
|
||||||
vec3 h = normalize(-l.direction + v);
|
vec3 h = normalize(-l.direction + v);
|
||||||
spec = pow(dot(n, h), 3.0 + glossiness)*s;
|
spec = pow(abs(dot(n, h)), 3.0 + glossiness)*s;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (diff*l.diffuse.rgb + spec*colSpecular.rgb);
|
return (diff*l.diffuse.rgb + spec*colSpecular.rgb);
|
||||||
@ -68,7 +68,7 @@ vec3 ComputeLightDirectional(Light l, vec3 n, vec3 v, float s)
|
|||||||
if (diff > 0.0)
|
if (diff > 0.0)
|
||||||
{
|
{
|
||||||
vec3 h = normalize(lightDir + v);
|
vec3 h = normalize(lightDir + v);
|
||||||
spec = pow(dot(n, h), 3.0 + glossiness)*s;
|
spec = pow(abs(dot(n, h)), 3.0 + glossiness)*s;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Combine results
|
// Combine results
|
||||||
@ -101,7 +101,7 @@ vec3 ComputeLightSpot(Light l, vec3 n, vec3 v, float s)
|
|||||||
if (diffAttenuation > 0.0)
|
if (diffAttenuation > 0.0)
|
||||||
{
|
{
|
||||||
vec3 h = normalize(lightDir + v);
|
vec3 h = normalize(lightDir + v);
|
||||||
spec = pow(dot(n, h), 3.0 + glossiness)*s;
|
spec = pow(abs(dot(n, h)), 3.0 + glossiness)*s;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb));
|
return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb));
|
||||||
@ -131,7 +131,7 @@ void main()
|
|||||||
|
|
||||||
// Calculate specular texture color fetching or set to maximum specular value by default
|
// Calculate specular texture color fetching or set to maximum specular value by default
|
||||||
float spec = 1.0;
|
float spec = 1.0;
|
||||||
if (useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r);
|
if (useSpecular == 1) spec = texture(texture2, fragTexCoord).r;
|
||||||
|
|
||||||
for (int i = 0; i < maxLights; i++)
|
for (int i = 0; i < maxLights; i++)
|
||||||
{
|
{
|
||||||
|
@ -51,9 +51,7 @@ int main()
|
|||||||
RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight);
|
RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight);
|
||||||
|
|
||||||
// Setup orbital camera
|
// Setup orbital camera
|
||||||
SetCameraMode(CAMERA_ORBITAL); // Set an orbital camera mode
|
SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode
|
||||||
SetCameraPosition(camera.position); // Set internal camera position to match our camera position
|
|
||||||
SetCameraTarget(camera.target); // Set internal camera target to match our camera target
|
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
@ -71,7 +69,7 @@ int main()
|
|||||||
// Send new value to the shader to be used on drawing
|
// Send new value to the shader to be used on drawing
|
||||||
SetShaderValue(shader, swirlCenterLoc, swirlCenter, 2);
|
SetShaderValue(shader, swirlCenterLoc, swirlCenter, 2);
|
||||||
|
|
||||||
UpdateCamera(&camera); // Update internal camera and our camera
|
UpdateCamera(&camera); // Update camera
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
|
@ -42,7 +42,7 @@ int main()
|
|||||||
|
|
||||||
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
|
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
|
||||||
|
|
||||||
SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode
|
SetCameraMode(camera, CAMERA_FREE); // Set an orbital camera mode
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
@ -70,6 +70,9 @@ int main()
|
|||||||
End3dMode();
|
End3dMode();
|
||||||
|
|
||||||
DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, GRAY);
|
DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, GRAY);
|
||||||
|
|
||||||
|
DrawText(FormatText("Camera position: (%.2f, %.2f, %.2f)", camera.position.x, camera.position.y, camera.position.z), 600, 20, 10, BLACK);
|
||||||
|
DrawText(FormatText("Camera target: (%.2f, %.2f, %.2f)", camera.target.x, camera.target.y, camera.target.z), 600, 40, 10, GRAY);
|
||||||
|
|
||||||
DrawFPS(10, 10);
|
DrawFPS(10, 10);
|
||||||
|
|
||||||
|
@ -45,9 +45,7 @@ int main()
|
|||||||
RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight);
|
RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight);
|
||||||
|
|
||||||
// Setup orbital camera
|
// Setup orbital camera
|
||||||
SetCameraMode(CAMERA_ORBITAL); // Set an orbital camera mode
|
SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode
|
||||||
SetCameraPosition(camera.position); // Set internal camera position to match our camera position
|
|
||||||
SetCameraTarget(camera.target); // Set internal camera target to match our camera target
|
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
@ -57,7 +55,7 @@ int main()
|
|||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
UpdateCamera(&camera); // Update internal camera and our camera
|
UpdateCamera(&camera); // Update camera
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
@ -67,7 +65,7 @@ int main()
|
|||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
BeginTextureMode(target); // Enable drawing to texture
|
BeginTextureMode(target); // Enable drawing to texture
|
||||||
|
|
||||||
Begin3dMode(camera);
|
Begin3dMode(camera);
|
||||||
|
|
||||||
DrawModel(dwarf, position, 2.0f, WHITE); // Draw 3d model with texture
|
DrawModel(dwarf, position, 2.0f, WHITE); // Draw 3d model with texture
|
||||||
|
@ -64,9 +64,7 @@ int main()
|
|||||||
pointLight->radius = 3.0f;
|
pointLight->radius = 3.0f;
|
||||||
|
|
||||||
// Setup orbital camera
|
// Setup orbital camera
|
||||||
SetCameraMode(CAMERA_ORBITAL); // Set an orbital camera mode
|
SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode
|
||||||
SetCameraPosition(camera.position); // Set internal camera position to match our camera position
|
|
||||||
SetCameraTarget(camera.target); // Set internal camera target to match our camera target
|
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
@ -76,7 +74,7 @@ int main()
|
|||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
UpdateCamera(&camera); // Update internal camera and our camera
|
UpdateCamera(&camera); // Update camera
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
|
64
src/audio.c
64
src/audio.c
@ -79,6 +79,10 @@
|
|||||||
#define JAR_MOD_IMPLEMENTATION
|
#define JAR_MOD_IMPLEMENTATION
|
||||||
#include "external/jar_mod.h" // MOD loading functions
|
#include "external/jar_mod.h" // MOD loading functions
|
||||||
|
|
||||||
|
#define DR_FLAC_IMPLEMENTATION
|
||||||
|
#define DR_FLAC_NO_WIN32_IO
|
||||||
|
#include "external/dr_flac.h" // FLAC loading functions
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#undef bool
|
#undef bool
|
||||||
#endif
|
#endif
|
||||||
@ -98,12 +102,13 @@
|
|||||||
// Types and Structures Definition
|
// Types and Structures Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
typedef enum { MUSIC_AUDIO_OGG = 0, MUSIC_MODULE_XM, MUSIC_MODULE_MOD } MusicContextType;
|
typedef enum { MUSIC_AUDIO_OGG = 0, MUSIC_AUDIO_FLAC, MUSIC_MODULE_XM, MUSIC_MODULE_MOD } MusicContextType;
|
||||||
|
|
||||||
// Music type (file streaming from memory)
|
// Music type (file streaming from memory)
|
||||||
typedef struct MusicData {
|
typedef struct MusicData {
|
||||||
MusicContextType ctxType; // Type of music context (OGG, XM, MOD)
|
MusicContextType ctxType; // Type of music context (OGG, XM, MOD)
|
||||||
stb_vorbis *ctxOgg; // OGG audio context
|
stb_vorbis *ctxOgg; // OGG audio context
|
||||||
|
drflac *ctxFlac; // FLAC audio context
|
||||||
jar_xm_context_t *ctxXm; // XM chiptune context
|
jar_xm_context_t *ctxXm; // XM chiptune context
|
||||||
jar_mod_context_t ctxMod; // MOD chiptune context
|
jar_mod_context_t ctxMod; // MOD chiptune context
|
||||||
|
|
||||||
@ -128,6 +133,7 @@ typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
static Wave LoadWAV(const char *fileName); // Load WAV file
|
static Wave LoadWAV(const char *fileName); // Load WAV file
|
||||||
static Wave LoadOGG(const char *fileName); // Load OGG file
|
static Wave LoadOGG(const char *fileName); // Load OGG file
|
||||||
|
static Wave LoadFLAC(const char *fileName); // Load FLAC file
|
||||||
|
|
||||||
#if defined(AUDIO_STANDALONE)
|
#if defined(AUDIO_STANDALONE)
|
||||||
const char *GetExtension(const char *fileName); // Get the extension for a filename
|
const char *GetExtension(const char *fileName); // Get the extension for a filename
|
||||||
@ -212,6 +218,7 @@ Wave LoadWave(const char *fileName)
|
|||||||
|
|
||||||
if (strcmp(GetExtension(fileName), "wav") == 0) wave = LoadWAV(fileName);
|
if (strcmp(GetExtension(fileName), "wav") == 0) wave = LoadWAV(fileName);
|
||||||
else if (strcmp(GetExtension(fileName), "ogg") == 0) wave = LoadOGG(fileName);
|
else if (strcmp(GetExtension(fileName), "ogg") == 0) wave = LoadOGG(fileName);
|
||||||
|
else if (strcmp(GetExtension(fileName), "flac") == 0) wave = LoadFLAC(fileName);
|
||||||
else TraceLog(WARNING, "[%s] File extension not recognized, it can't be loaded", fileName);
|
else TraceLog(WARNING, "[%s] File extension not recognized, it can't be loaded", fileName);
|
||||||
|
|
||||||
return wave;
|
return wave;
|
||||||
@ -672,7 +679,7 @@ Music LoadMusicStream(const char *fileName)
|
|||||||
// Open ogg audio stream
|
// Open ogg audio stream
|
||||||
music->ctxOgg = stb_vorbis_open_filename(fileName, NULL, NULL);
|
music->ctxOgg = stb_vorbis_open_filename(fileName, NULL, NULL);
|
||||||
|
|
||||||
if (music->ctxOgg == NULL) TraceLog(WARNING, "[%s] OGG audio file could not be opened", fileName);
|
if (music->ctxOgg == NULL) TraceLog(WARNING, "[%s] OGG audio file could not be opened", fileName);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stb_vorbis_info info = stb_vorbis_get_info(music->ctxOgg); // Get Ogg file info
|
stb_vorbis_info info = stb_vorbis_get_info(music->ctxOgg); // Get Ogg file info
|
||||||
@ -691,6 +698,24 @@ Music LoadMusicStream(const char *fileName)
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (strcmp(GetExtension(fileName), "flac") == 0)
|
||||||
|
{
|
||||||
|
music->ctxFlac = drflac_open_file(fileName);
|
||||||
|
|
||||||
|
if (music->ctxFlac == NULL) TraceLog(WARNING, "[%s] FLAC audio file could not be opened", fileName);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
music->stream = InitAudioStream(music->ctxFlac->sampleRate, music->ctxFlac->bitsPerSample, music->ctxFlac->channels);
|
||||||
|
music->totalSamples = (unsigned int)music->ctxFlac->totalSampleCount;
|
||||||
|
music->samplesLeft = music->totalSamples;
|
||||||
|
music->ctxType = MUSIC_AUDIO_FLAC;
|
||||||
|
music->loop = true; // We loop by default
|
||||||
|
|
||||||
|
TraceLog(DEBUG, "[%s] FLAC sample rate: %i", fileName, music->ctxFlac->sampleRate);
|
||||||
|
TraceLog(DEBUG, "[%s] FLAC bits per sample: %i", fileName, music->ctxFlac->bitsPerSample);
|
||||||
|
TraceLog(DEBUG, "[%s] FLAC channels: %i", fileName, music->ctxFlac->channels);
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (strcmp(GetExtension(fileName), "xm") == 0)
|
else if (strcmp(GetExtension(fileName), "xm") == 0)
|
||||||
{
|
{
|
||||||
int result = jar_xm_create_context_from_file(&music->ctxXm, 48000, fileName);
|
int result = jar_xm_create_context_from_file(&music->ctxXm, 48000, fileName);
|
||||||
@ -739,6 +764,7 @@ void UnloadMusicStream(Music music)
|
|||||||
CloseAudioStream(music->stream);
|
CloseAudioStream(music->stream);
|
||||||
|
|
||||||
if (music->ctxType == MUSIC_AUDIO_OGG) stb_vorbis_close(music->ctxOgg);
|
if (music->ctxType == MUSIC_AUDIO_OGG) stb_vorbis_close(music->ctxOgg);
|
||||||
|
else if (music->ctxType == MUSIC_AUDIO_FLAC) drflac_free(music->ctxFlac);
|
||||||
else if (music->ctxType == MUSIC_MODULE_XM) jar_xm_free_context(music->ctxXm);
|
else if (music->ctxType == MUSIC_MODULE_XM) jar_xm_free_context(music->ctxXm);
|
||||||
else if (music->ctxType == MUSIC_MODULE_MOD) jar_mod_unload(&music->ctxMod);
|
else if (music->ctxType == MUSIC_MODULE_MOD) jar_mod_unload(&music->ctxMod);
|
||||||
|
|
||||||
@ -818,6 +844,20 @@ void UpdateMusicStream(Music music)
|
|||||||
UpdateAudioStream(music->stream, pcm, numSamplesOgg*music->stream.channels);
|
UpdateAudioStream(music->stream, pcm, numSamplesOgg*music->stream.channels);
|
||||||
music->samplesLeft -= (numSamplesOgg*music->stream.channels);
|
music->samplesLeft -= (numSamplesOgg*music->stream.channels);
|
||||||
|
|
||||||
|
} break;
|
||||||
|
case MUSIC_AUDIO_FLAC:
|
||||||
|
{
|
||||||
|
if (music->samplesLeft >= AUDIO_BUFFER_SIZE) numSamples = AUDIO_BUFFER_SIZE;
|
||||||
|
else numSamples = music->samplesLeft;
|
||||||
|
|
||||||
|
int pcmi[AUDIO_BUFFER_SIZE];
|
||||||
|
|
||||||
|
// NOTE: Returns the number of samples to process (should be the same as numSamples)
|
||||||
|
unsigned int numSamplesFlac = (unsigned int)drflac_read_s32(music->ctxFlac, numSamples, pcmi);
|
||||||
|
|
||||||
|
UpdateAudioStream(music->stream, pcmi, numSamplesFlac*music->stream.channels);
|
||||||
|
music->samplesLeft -= (numSamples*music->stream.channels);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case MUSIC_MODULE_XM:
|
case MUSIC_MODULE_XM:
|
||||||
{
|
{
|
||||||
@ -1197,7 +1237,7 @@ static Wave LoadOGG(const char *fileName)
|
|||||||
|
|
||||||
if (totalSeconds > 10) TraceLog(WARNING, "[%s] Ogg audio lenght is larger than 10 seconds (%f), that's a big file in memory, consider music streaming", fileName, totalSeconds);
|
if (totalSeconds > 10) TraceLog(WARNING, "[%s] Ogg audio lenght is larger than 10 seconds (%f), that's a big file in memory, consider music streaming", fileName, totalSeconds);
|
||||||
|
|
||||||
int totalSamples = totalSeconds*info.sample_rate*info.channels;
|
int totalSamples = (int)(totalSeconds*info.sample_rate*info.channels);
|
||||||
wave.sampleCount = totalSamples;
|
wave.sampleCount = totalSamples;
|
||||||
|
|
||||||
wave.data = (short *)malloc(totalSamplesLength*sizeof(short));
|
wave.data = (short *)malloc(totalSamplesLength*sizeof(short));
|
||||||
@ -1214,6 +1254,24 @@ static Wave LoadOGG(const char *fileName)
|
|||||||
return wave;
|
return wave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load FLAC file into Wave structure
|
||||||
|
// NOTE: Using dr_flac library
|
||||||
|
static Wave LoadFLAC(const char *fileName)
|
||||||
|
{
|
||||||
|
Wave wave;
|
||||||
|
|
||||||
|
// Decode an entire FLAC file in one go
|
||||||
|
uint64_t totalSampleCount;
|
||||||
|
wave.data = drflac_open_and_decode_file_s32(fileName, &wave.channels, &wave.sampleRate, &totalSampleCount);
|
||||||
|
|
||||||
|
wave.sampleCount = (int)totalSampleCount;
|
||||||
|
wave.sampleSize = 32;
|
||||||
|
|
||||||
|
if (wave.data == NULL) TraceLog(WARNING, "[%s] FLAC data could not be loaded", fileName);
|
||||||
|
|
||||||
|
return wave;
|
||||||
|
}
|
||||||
|
|
||||||
// Some required functions for audio standalone module version
|
// Some required functions for audio standalone module version
|
||||||
#if defined(AUDIO_STANDALONE)
|
#if defined(AUDIO_STANDALONE)
|
||||||
// Get the extension for a filename
|
// Get the extension for a filename
|
||||||
|
447
src/core.c
447
src/core.c
@ -18,7 +18,11 @@
|
|||||||
*
|
*
|
||||||
* On PLATFORM_RPI, graphic device is managed by EGL and input system is coded in raw mode.
|
* On PLATFORM_RPI, graphic device is managed by EGL and input system is coded in raw mode.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
* Module Configuration Flags:
|
||||||
|
*
|
||||||
|
* RL_LOAD_DEFAULT_FONT - Use external module functions to load default raylib font (module: text)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||||
* will the authors be held liable for any damages arising from the use of this software.
|
* will the authors be held liable for any damages arising from the use of this software.
|
||||||
@ -54,12 +58,12 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h> // Standard input / output lib
|
#include <stdio.h> // Standard input / output lib
|
||||||
#include <stdlib.h> // Declares malloc() and free() for memory management, rand(), atexit()
|
#include <stdlib.h> // Required for: malloc(), free(), rand(), atexit()
|
||||||
#include <stdint.h> // Required for typedef unsigned long long int uint64_t, used by hi-res timer
|
#include <stdint.h> // Required for: typedef unsigned long long int uint64_t, used by hi-res timer
|
||||||
#include <time.h> // Useful to initialize random seed - Android/RPI hi-res timer (NOTE: Linux only!)
|
#include <time.h> // Required for: time() - Android/RPI hi-res timer (NOTE: Linux only!)
|
||||||
#include <math.h> // Math related functions, tan() used to set perspective
|
#include <math.h> // Required for: tan() [Used in Begin3dMode() to set perspective]
|
||||||
#include <string.h> // String function definitions, memset()
|
#include <string.h> // Required for: strcmp()
|
||||||
#include <errno.h> // Macros for reporting and retrieving error conditions through error codes
|
//#include <errno.h> // Macros for reporting and retrieving error conditions through error codes
|
||||||
|
|
||||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||||
//#define GLFW_INCLUDE_NONE // Disable the standard OpenGL header inclusion on GLFW3
|
//#define GLFW_INCLUDE_NONE // Disable the standard OpenGL header inclusion on GLFW3
|
||||||
@ -75,8 +79,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PLATFORM_ANDROID)
|
#if defined(PLATFORM_ANDROID)
|
||||||
#include <jni.h> // Java native interface
|
//#include <android/sensor.h> // Android sensors functions (accelerometer, gyroscope, light...)
|
||||||
#include <android/sensor.h> // Android sensors functions
|
|
||||||
#include <android/window.h> // Defines AWINDOW_FLAG_FULLSCREEN and others
|
#include <android/window.h> // Defines AWINDOW_FLAG_FULLSCREEN and others
|
||||||
#include <android_native_app_glue.h> // Defines basic app state struct and manages activity
|
#include <android_native_app_glue.h> // Defines basic app state struct and manages activity
|
||||||
|
|
||||||
@ -124,12 +127,14 @@
|
|||||||
//#define DEFAULT_GAMEPAD_DEV "/dev/input/eventN"
|
//#define DEFAULT_GAMEPAD_DEV "/dev/input/eventN"
|
||||||
|
|
||||||
#define MOUSE_SENSITIVITY 0.8f
|
#define MOUSE_SENSITIVITY 0.8f
|
||||||
|
|
||||||
#define MAX_GAMEPADS 2 // Max number of gamepads supported
|
|
||||||
#define MAX_GAMEPAD_BUTTONS 11 // Max bumber of buttons supported (per gamepad)
|
|
||||||
#define MAX_GAMEPAD_AXIS 8 // Max number of axis supported (per gamepad)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MAX_GAMEPADS 4 // Max number of gamepads supported
|
||||||
|
#define MAX_GAMEPAD_BUTTONS 32 // Max bumber of buttons supported (per gamepad)
|
||||||
|
#define MAX_GAMEPAD_AXIS 8 // Max number of axis supported (per gamepad)
|
||||||
|
|
||||||
|
#define RL_LOAD_DEFAULT_FONT // Load default font on window initialization (module: text)
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Types and Structures Definition
|
// Types and Structures Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
@ -152,9 +157,6 @@ static const char *internalDataPath; // Android internal data path to
|
|||||||
static bool windowReady = false; // Used to detect display initialization
|
static bool windowReady = false; // Used to detect display initialization
|
||||||
static bool appEnabled = true; // Used to detec if app is active
|
static bool appEnabled = true; // Used to detec if app is active
|
||||||
static bool contextRebindRequired = false; // Used to know context rebind required
|
static bool contextRebindRequired = false; // Used to know context rebind required
|
||||||
|
|
||||||
static int previousButtonState[128] = { 1 }; // Required to check if button pressed/released once
|
|
||||||
static int currentButtonState[128] = { 1 }; // Required to check if button pressed/released once
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PLATFORM_RPI)
|
#if defined(PLATFORM_RPI)
|
||||||
@ -168,15 +170,11 @@ static int defaultKeyboardMode; // Used to store default keyboar
|
|||||||
// Mouse input variables
|
// Mouse input variables
|
||||||
static int mouseStream = -1; // Mouse device file descriptor
|
static int mouseStream = -1; // Mouse device file descriptor
|
||||||
static bool mouseReady = false; // Flag to know if mouse is ready
|
static bool mouseReady = false; // Flag to know if mouse is ready
|
||||||
pthread_t mouseThreadId; // Mouse reading thread id
|
static pthread_t mouseThreadId; // Mouse reading thread id
|
||||||
|
|
||||||
// Gamepad input variables
|
// Gamepad input variables
|
||||||
static int gamepadStream[MAX_GAMEPADS] = { -1 }; // Gamepad device file descriptor (two gamepads supported)
|
static int gamepadStream[MAX_GAMEPADS] = { -1 };// Gamepad device file descriptor
|
||||||
static bool gamepadReady[MAX_GAMEPADS] = { false }; // Flag to know if gamepad is ready (two gamepads supported)
|
static pthread_t gamepadThreadId; // Gamepad reading thread id
|
||||||
pthread_t gamepadThreadId; // Gamepad reading thread id
|
|
||||||
|
|
||||||
int gamepadButtons[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS]; // Gamepad buttons state
|
|
||||||
float gamepadAxisValues[MAX_GAMEPADS][MAX_GAMEPAD_AXIS]; // Gamepad axis state
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
|
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
|
||||||
@ -200,25 +198,32 @@ static Matrix downscaleView; // Matrix to downscale view (in case
|
|||||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
||||||
static const char *windowTitle; // Window text title...
|
static const char *windowTitle; // Window text title...
|
||||||
static bool cursorOnScreen = false; // Tracks if cursor is inside client area
|
static bool cursorOnScreen = false; // Tracks if cursor is inside client area
|
||||||
|
static bool cursorHidden = false; // Track if cursor is hidden
|
||||||
|
|
||||||
static char previousKeyState[512] = { 0 }; // Required to check if key pressed/released once
|
// Register mouse states
|
||||||
static char currentKeyState[512] = { 0 }; // Required to check if key pressed/released once
|
static char previousMouseState[3] = { 0 }; // Registers previous mouse button state
|
||||||
|
static char currentMouseState[3] = { 0 }; // Registers current mouse button state
|
||||||
|
static int previousMouseWheelY = 0; // Registers previous mouse wheel variation
|
||||||
|
static int currentMouseWheelY = 0; // Registers current mouse wheel variation
|
||||||
|
|
||||||
static char previousGamepadState[32] = {0}; // Required to check if gamepad btn pressed/released once
|
// Register gamepads states
|
||||||
static char currentGamepadState[32] = {0}; // Required to check if gamepad btn pressed/released once
|
static bool gamepadReady[MAX_GAMEPADS] = { false }; // Flag to know if gamepad is ready
|
||||||
|
static float gamepadAxisState[MAX_GAMEPADS][MAX_GAMEPAD_AXIS]; // Gamepad axis state
|
||||||
static char previousMouseState[3] = { 0 }; // Required to check if mouse btn pressed/released once
|
static char previousGamepadState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS]; // Previous gamepad buttons state
|
||||||
static char currentMouseState[3] = { 0 }; // Required to check if mouse btn pressed/released once
|
static char currentGamepadState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS]; // Current gamepad buttons state
|
||||||
|
|
||||||
static int previousMouseWheelY = 0; // Required to track mouse wheel variation
|
|
||||||
static int currentMouseWheelY = 0; // Required to track mouse wheel variation
|
|
||||||
|
|
||||||
|
// Keyboard configuration
|
||||||
static int exitKey = KEY_ESCAPE; // Default exit key (ESC)
|
static int exitKey = KEY_ESCAPE; // Default exit key (ESC)
|
||||||
static int lastKeyPressed = -1; // Register last key pressed
|
|
||||||
|
|
||||||
static bool cursorHidden; // Track if cursor is hidden
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Register keyboard states
|
||||||
|
static char previousKeyState[512] = { 0 }; // Registers previous frame key state
|
||||||
|
static char currentKeyState[512] = { 0 }; // Registers current frame key state
|
||||||
|
|
||||||
|
static int lastKeyPressed = -1; // Register last key pressed
|
||||||
|
static int lastGamepadButtonPressed = -1; // Register last gamepad button pressed
|
||||||
|
static int gamepadAxisCount = 0; // Register number of available gamepad axis
|
||||||
|
|
||||||
static Vector2 mousePosition; // Mouse position on screen
|
static Vector2 mousePosition; // Mouse position on screen
|
||||||
static Vector2 touchPosition[MAX_TOUCH_POINTS]; // Touch position on screen
|
static Vector2 touchPosition[MAX_TOUCH_POINTS]; // Touch position on screen
|
||||||
|
|
||||||
@ -238,11 +243,10 @@ static bool showLogo = false; // Track if showing logo at init is
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Other Modules Functions Declaration (required by core)
|
// Other Modules Functions Declaration (required by core)
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
#if defined(RL_LOAD_DEFAULT_FONT)
|
||||||
extern void LoadDefaultFont(void); // [Module: text] Loads default font on InitWindow()
|
extern void LoadDefaultFont(void); // [Module: text] Loads default font on InitWindow()
|
||||||
extern void UnloadDefaultFont(void); // [Module: text] Unloads default font from GPU memory
|
extern void UnloadDefaultFont(void); // [Module: text] Unloads default font from GPU memory
|
||||||
|
#endif
|
||||||
extern void ProcessGestureEvent(GestureEvent event); // [Module: gestures] Process gesture event and translate it into gestures
|
|
||||||
extern void UpdateGestures(void); // [Module: gestures] Update gestures detected (called in PollInputEvents())
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module specific Functions Declaration
|
// Module specific Functions Declaration
|
||||||
@ -311,9 +315,11 @@ void InitWindow(int width, int height, const char *title)
|
|||||||
// Init graphics device (display device and OpenGL context)
|
// Init graphics device (display device and OpenGL context)
|
||||||
InitGraphicsDevice(width, height);
|
InitGraphicsDevice(width, height);
|
||||||
|
|
||||||
// Load default font for convenience
|
#if defined(RL_LOAD_DEFAULT_FONT)
|
||||||
|
// Load default font
|
||||||
// NOTE: External function (defined in module: text)
|
// NOTE: External function (defined in module: text)
|
||||||
LoadDefaultFont();
|
LoadDefaultFont();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Init hi-res timer
|
// Init hi-res timer
|
||||||
InitTimer();
|
InitTimer();
|
||||||
@ -355,7 +361,7 @@ void InitWindow(int width, int height, const char *title)
|
|||||||
|
|
||||||
#if defined(PLATFORM_ANDROID)
|
#if defined(PLATFORM_ANDROID)
|
||||||
// Android activity initialization
|
// Android activity initialization
|
||||||
void InitWindow(int width, int height, struct android_app *state)
|
void InitWindow(int width, int height, void *state)
|
||||||
{
|
{
|
||||||
TraceLog(INFO, "Initializing raylib (v1.6.0)");
|
TraceLog(INFO, "Initializing raylib (v1.6.0)");
|
||||||
|
|
||||||
@ -364,7 +370,7 @@ void InitWindow(int width, int height, struct android_app *state)
|
|||||||
screenWidth = width;
|
screenWidth = width;
|
||||||
screenHeight = height;
|
screenHeight = height;
|
||||||
|
|
||||||
app = state;
|
app = (struct android_app *)state;
|
||||||
internalDataPath = app->activity->internalDataPath;
|
internalDataPath = app->activity->internalDataPath;
|
||||||
|
|
||||||
// Set desired windows flags before initializing anything
|
// Set desired windows flags before initializing anything
|
||||||
@ -420,7 +426,9 @@ void InitWindow(int width, int height, struct android_app *state)
|
|||||||
// Close Window and Terminate Context
|
// Close Window and Terminate Context
|
||||||
void CloseWindow(void)
|
void CloseWindow(void)
|
||||||
{
|
{
|
||||||
|
#if defined(RL_LOAD_DEFAULT_FONT)
|
||||||
UnloadDefaultFont();
|
UnloadDefaultFont();
|
||||||
|
#endif
|
||||||
|
|
||||||
rlglClose(); // De-init rlgl
|
rlglClose(); // De-init rlgl
|
||||||
|
|
||||||
@ -456,6 +464,9 @@ void CloseWindow(void)
|
|||||||
// Wait for mouse and gamepad threads to finish before closing
|
// Wait for mouse and gamepad threads to finish before closing
|
||||||
// NOTE: Those threads should already have finished at this point
|
// NOTE: Those threads should already have finished at this point
|
||||||
// because they are controlled by windowShouldClose variable
|
// because they are controlled by windowShouldClose variable
|
||||||
|
|
||||||
|
windowShouldClose = true; // Added to force threads to exit when the close window is called
|
||||||
|
|
||||||
pthread_join(mouseThreadId, NULL);
|
pthread_join(mouseThreadId, NULL);
|
||||||
pthread_join(gamepadThreadId, NULL);
|
pthread_join(gamepadThreadId, NULL);
|
||||||
#endif
|
#endif
|
||||||
@ -516,6 +527,65 @@ int GetScreenHeight(void)
|
|||||||
return screenHeight;
|
return screenHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(PLATFORM_ANDROID)
|
||||||
|
// Show mouse cursor
|
||||||
|
void ShowCursor()
|
||||||
|
{
|
||||||
|
#if defined(PLATFORM_DESKTOP)
|
||||||
|
#ifdef __linux
|
||||||
|
XUndefineCursor(glfwGetX11Display(), glfwGetX11Window(window));
|
||||||
|
#else
|
||||||
|
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
cursorHidden = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide mouse cursor
|
||||||
|
void HideCursor()
|
||||||
|
{
|
||||||
|
#if defined(PLATFORM_DESKTOP)
|
||||||
|
#ifdef __linux
|
||||||
|
XColor Col;
|
||||||
|
const char Nil[] = {0};
|
||||||
|
|
||||||
|
Pixmap Pix = XCreateBitmapFromData(glfwGetX11Display(), glfwGetX11Window(window), Nil, 1, 1);
|
||||||
|
Cursor Cur = XCreatePixmapCursor(glfwGetX11Display(), Pix, Pix, &Col, &Col, 0, 0);
|
||||||
|
|
||||||
|
XDefineCursor(glfwGetX11Display(), glfwGetX11Window(window), Cur);
|
||||||
|
XFreeCursor(glfwGetX11Display(), Cur);
|
||||||
|
#else
|
||||||
|
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
cursorHidden = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if mouse cursor is hidden
|
||||||
|
bool IsCursorHidden()
|
||||||
|
{
|
||||||
|
return cursorHidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable mouse cursor
|
||||||
|
void EnableCursor()
|
||||||
|
{
|
||||||
|
#if defined(PLATFORM_DESKTOP)
|
||||||
|
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||||
|
#endif
|
||||||
|
cursorHidden = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable mouse cursor
|
||||||
|
void DisableCursor()
|
||||||
|
{
|
||||||
|
#if defined(PLATFORM_DESKTOP)
|
||||||
|
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||||
|
#endif
|
||||||
|
cursorHidden = true;
|
||||||
|
}
|
||||||
|
#endif // !defined(PLATFORM_ANDROID)
|
||||||
|
|
||||||
// Sets Background Color
|
// Sets Background Color
|
||||||
void ClearBackground(Color color)
|
void ClearBackground(Color color)
|
||||||
{
|
{
|
||||||
@ -1034,7 +1104,6 @@ Matrix GetCameraMatrix(Camera camera)
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Functions Definition - Input (Keyboard, Mouse, Gamepad) Functions
|
// Module Functions Definition - Input (Keyboard, Mouse, Gamepad) Functions
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
|
||||||
// Detect if a key has been pressed once
|
// Detect if a key has been pressed once
|
||||||
bool IsKeyPressed(int key)
|
bool IsKeyPressed(int key)
|
||||||
{
|
{
|
||||||
@ -1057,7 +1126,7 @@ bool IsKeyDown(int key)
|
|||||||
bool IsKeyReleased(int key)
|
bool IsKeyReleased(int key)
|
||||||
{
|
{
|
||||||
bool released = false;
|
bool released = false;
|
||||||
|
|
||||||
if ((currentKeyState[key] != previousKeyState[key]) && (currentKeyState[key] == 0)) released = true;
|
if ((currentKeyState[key] != previousKeyState[key]) && (currentKeyState[key] == 0)) released = true;
|
||||||
else released = false;
|
else released = false;
|
||||||
|
|
||||||
@ -1081,64 +1150,9 @@ int GetKeyPressed(void)
|
|||||||
// NOTE: default exitKey is ESCAPE
|
// NOTE: default exitKey is ESCAPE
|
||||||
void SetExitKey(int key)
|
void SetExitKey(int key)
|
||||||
{
|
{
|
||||||
|
#if !defined(PLATFORM_ANDROID)
|
||||||
exitKey = key;
|
exitKey = key;
|
||||||
}
|
|
||||||
|
|
||||||
// Hide mouse cursor
|
|
||||||
void HideCursor()
|
|
||||||
{
|
|
||||||
#if defined(PLATFORM_DESKTOP)
|
|
||||||
#ifdef __linux
|
|
||||||
XColor Col;
|
|
||||||
const char Nil[] = {0};
|
|
||||||
|
|
||||||
Pixmap Pix = XCreateBitmapFromData(glfwGetX11Display(), glfwGetX11Window(window), Nil, 1, 1);
|
|
||||||
Cursor Cur = XCreatePixmapCursor(glfwGetX11Display(), Pix, Pix, &Col, &Col, 0, 0);
|
|
||||||
|
|
||||||
XDefineCursor(glfwGetX11Display(), glfwGetX11Window(window), Cur);
|
|
||||||
XFreeCursor(glfwGetX11Display(), Cur);
|
|
||||||
#else
|
|
||||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
cursorHidden = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show mouse cursor
|
|
||||||
void ShowCursor()
|
|
||||||
{
|
|
||||||
#if defined(PLATFORM_DESKTOP)
|
|
||||||
#ifdef __linux
|
|
||||||
XUndefineCursor(glfwGetX11Display(), glfwGetX11Window(window));
|
|
||||||
#else
|
|
||||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
cursorHidden = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable mouse cursor
|
|
||||||
void DisableCursor()
|
|
||||||
{
|
|
||||||
#if defined(PLATFORM_DESKTOP)
|
|
||||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
|
||||||
#endif
|
|
||||||
cursorHidden = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enable mouse cursor
|
|
||||||
void EnableCursor()
|
|
||||||
{
|
|
||||||
#if defined(PLATFORM_DESKTOP)
|
|
||||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
|
||||||
#endif
|
|
||||||
cursorHidden = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if mouse cursor is hidden
|
|
||||||
bool IsCursorHidden()
|
|
||||||
{
|
|
||||||
return cursorHidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Gamepad support not implemented in emscripten GLFW3 (PLATFORM_WEB)
|
// NOTE: Gamepad support not implemented in emscripten GLFW3 (PLATFORM_WEB)
|
||||||
@ -1147,33 +1161,51 @@ bool IsCursorHidden()
|
|||||||
bool IsGamepadAvailable(int gamepad)
|
bool IsGamepadAvailable(int gamepad)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
#if defined(PLATFORM_RPI)
|
#if !defined(PLATFORM_ANDROID)
|
||||||
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad]) result = true;
|
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad]) result = true;
|
||||||
#else
|
|
||||||
if (glfwJoystickPresent(gamepad) == 1) result = true;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check gamepad name (if available)
|
||||||
|
bool IsGamepadName(int gamepad, const char *name)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
const char *gamepadName = NULL;
|
||||||
|
|
||||||
|
if (gamepadReady[gamepad]) gamepadName = GetGamepadName(gamepad);
|
||||||
|
|
||||||
|
if ((name != NULL) && (gamepadName != NULL)) result = (strcmp(name, gamepadName) == 0);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return gamepad internal name id
|
||||||
|
const char *GetGamepadName(int gamepad)
|
||||||
|
{
|
||||||
|
#if defined(PLATFORM_DESKTOP)
|
||||||
|
if (gamepadReady[gamepad]) return glfwGetJoystickName(gamepad);
|
||||||
|
else return NULL;
|
||||||
|
#else
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return gamepad axis count
|
||||||
|
int GetGamepadAxisCount(int gamepad)
|
||||||
|
{
|
||||||
|
return gamepadAxisCount;
|
||||||
|
}
|
||||||
|
|
||||||
// Return axis movement vector for a gamepad
|
// Return axis movement vector for a gamepad
|
||||||
float GetGamepadAxisMovement(int gamepad, int axis)
|
float GetGamepadAxisMovement(int gamepad, int axis)
|
||||||
{
|
{
|
||||||
float value = 0;
|
float value = 0;
|
||||||
|
|
||||||
#if defined(PLATFORM_RPI)
|
#if !defined(PLATFORM_ANDROID)
|
||||||
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad])
|
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (axis < MAX_GAMEPAD_AXIS)) value = gamepadAxisState[gamepad][axis];
|
||||||
{
|
|
||||||
if (axis < MAX_GAMEPAD_AXIS) value = gamepadAxisValues[gamepad][axis];
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
const float *axes;
|
|
||||||
int axisCount = 0;
|
|
||||||
|
|
||||||
axes = glfwGetJoystickAxes(gamepad, &axisCount);
|
|
||||||
|
|
||||||
if (axis < axisCount) value = axes[axis];
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
@ -1184,14 +1216,11 @@ bool IsGamepadButtonPressed(int gamepad, int button)
|
|||||||
{
|
{
|
||||||
bool pressed = false;
|
bool pressed = false;
|
||||||
|
|
||||||
currentGamepadState[button] = IsGamepadButtonDown(gamepad, button);
|
#if !defined(PLATFORM_ANDROID)
|
||||||
|
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
|
||||||
if (currentGamepadState[button] != previousGamepadState[button])
|
(currentGamepadState[gamepad][button] != previousGamepadState[gamepad][button]) &&
|
||||||
{
|
(currentGamepadState[gamepad][button] == 1)) pressed = true;
|
||||||
if (currentGamepadState[button]) pressed = true;
|
#endif
|
||||||
previousGamepadState[button] = currentGamepadState[button];
|
|
||||||
}
|
|
||||||
else pressed = false;
|
|
||||||
|
|
||||||
return pressed;
|
return pressed;
|
||||||
}
|
}
|
||||||
@ -1201,18 +1230,9 @@ bool IsGamepadButtonDown(int gamepad, int button)
|
|||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
#if defined(PLATFORM_RPI)
|
#if !defined(PLATFORM_ANDROID)
|
||||||
// Get gamepad buttons information
|
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
|
||||||
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (gamepadButtons[gamepad][button] == 1)) result = true;
|
(currentGamepadState[gamepad][button] == 1)) result = true;
|
||||||
else result = false;
|
|
||||||
#else
|
|
||||||
const unsigned char *buttons;
|
|
||||||
int buttonsCount;
|
|
||||||
|
|
||||||
buttons = glfwGetJoystickButtons(gamepad, &buttonsCount);
|
|
||||||
|
|
||||||
if ((buttons != NULL) && (buttons[button] == GLFW_PRESS)) result = true;
|
|
||||||
else result = false;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -1222,15 +1242,12 @@ bool IsGamepadButtonDown(int gamepad, int button)
|
|||||||
bool IsGamepadButtonReleased(int gamepad, int button)
|
bool IsGamepadButtonReleased(int gamepad, int button)
|
||||||
{
|
{
|
||||||
bool released = false;
|
bool released = false;
|
||||||
|
|
||||||
currentGamepadState[button] = IsGamepadButtonUp(gamepad, button);
|
#if !defined(PLATFORM_ANDROID)
|
||||||
|
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
|
||||||
if (currentGamepadState[button] != previousGamepadState[button])
|
(currentGamepadState[gamepad][button] != previousGamepadState[gamepad][button]) &&
|
||||||
{
|
(currentGamepadState[gamepad][button] == 0)) released = true;
|
||||||
if (currentGamepadState[button]) released = true;
|
#endif
|
||||||
previousGamepadState[button] = currentGamepadState[button];
|
|
||||||
}
|
|
||||||
else released = false;
|
|
||||||
|
|
||||||
return released;
|
return released;
|
||||||
}
|
}
|
||||||
@ -1240,24 +1257,19 @@ bool IsGamepadButtonUp(int gamepad, int button)
|
|||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
#if defined(PLATFORM_RPI)
|
#if !defined(PLATFORM_ANDROID)
|
||||||
// Get gamepad buttons information
|
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
|
||||||
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (gamepadButtons[gamepad][button] == 0)) result = true;
|
(currentGamepadState[gamepad][button] == 0)) result = true;
|
||||||
else result = false;
|
|
||||||
#else
|
|
||||||
const unsigned char *buttons;
|
|
||||||
int buttonsCount;
|
|
||||||
|
|
||||||
buttons = glfwGetJoystickButtons(gamepad, &buttonsCount);
|
|
||||||
|
|
||||||
if ((buttons != NULL) && (buttons[button] == GLFW_RELEASE)) result = true;
|
|
||||||
else result = false;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif //defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
|
||||||
|
|
||||||
|
// Get the last gamepad button pressed
|
||||||
|
int GetGamepadButtonPressed(void)
|
||||||
|
{
|
||||||
|
return lastGamepadButtonPressed;
|
||||||
|
}
|
||||||
|
|
||||||
// Detect if a mouse button has been pressed once
|
// Detect if a mouse button has been pressed once
|
||||||
bool IsMouseButtonPressed(int button)
|
bool IsMouseButtonPressed(int button)
|
||||||
@ -1411,37 +1423,6 @@ Vector2 GetTouchPosition(int index)
|
|||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(PLATFORM_ANDROID)
|
|
||||||
// Detect if a button has been pressed once
|
|
||||||
bool IsButtonPressed(int button)
|
|
||||||
{
|
|
||||||
bool pressed = false;
|
|
||||||
|
|
||||||
if ((currentButtonState[button] != previousButtonState[button]) && (currentButtonState[button] == 0)) pressed = true;
|
|
||||||
else pressed = false;
|
|
||||||
|
|
||||||
return pressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Detect if a button is being pressed (button held down)
|
|
||||||
bool IsButtonDown(int button)
|
|
||||||
{
|
|
||||||
if (currentButtonState[button] == 0) return true;
|
|
||||||
else return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Detect if a button has been released once
|
|
||||||
bool IsButtonReleased(int button)
|
|
||||||
{
|
|
||||||
bool released = false;
|
|
||||||
|
|
||||||
if ((currentButtonState[button] != previousButtonState[button]) && (currentButtonState[button] == 1)) released = true;
|
|
||||||
else released = false;
|
|
||||||
|
|
||||||
return released;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module specific Functions Definition
|
// Module specific Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
@ -1924,8 +1905,9 @@ static bool GetKeyStatus(int key)
|
|||||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||||
return glfwGetKey(window, key);
|
return glfwGetKey(window, key);
|
||||||
#elif defined(PLATFORM_ANDROID)
|
#elif defined(PLATFORM_ANDROID)
|
||||||
// TODO: Check for virtual keyboard
|
// NOTE: Android supports up to 260 keys
|
||||||
return false;
|
if (key < 0 || key > 260) return false;
|
||||||
|
else return currentKeyState[key];
|
||||||
#elif defined(PLATFORM_RPI)
|
#elif defined(PLATFORM_RPI)
|
||||||
// NOTE: Keys states are filled in PollInputEvents()
|
// NOTE: Keys states are filled in PollInputEvents()
|
||||||
if (key < 0 || key > 511) return false;
|
if (key < 0 || key > 511) return false;
|
||||||
@ -1953,6 +1935,13 @@ static void PollInputEvents(void)
|
|||||||
// NOTE: Gestures update must be called every frame to reset gestures correctly
|
// NOTE: Gestures update must be called every frame to reset gestures correctly
|
||||||
// because ProcessGestureEvent() is just called on an event, not every frame
|
// because ProcessGestureEvent() is just called on an event, not every frame
|
||||||
UpdateGestures();
|
UpdateGestures();
|
||||||
|
|
||||||
|
// Reset last key pressed registered
|
||||||
|
lastKeyPressed = -1;
|
||||||
|
|
||||||
|
// Reset last gamepad button pressed registered
|
||||||
|
lastGamepadButtonPressed = -1;
|
||||||
|
gamepadAxisCount = 0;
|
||||||
|
|
||||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||||
// Mouse input polling
|
// Mouse input polling
|
||||||
@ -1963,9 +1952,8 @@ static void PollInputEvents(void)
|
|||||||
|
|
||||||
mousePosition.x = (float)mouseX;
|
mousePosition.x = (float)mouseX;
|
||||||
mousePosition.y = (float)mouseY;
|
mousePosition.y = (float)mouseY;
|
||||||
|
|
||||||
// Keyboard input polling (automatically managed by GLFW3 through callback)
|
// Keyboard input polling (automatically managed by GLFW3 through callback)
|
||||||
lastKeyPressed = -1;
|
|
||||||
|
|
||||||
// Register previous keys states
|
// Register previous keys states
|
||||||
for (int i = 0; i < 512; i++) previousKeyState[i] = currentKeyState[i];
|
for (int i = 0; i < 512; i++) previousKeyState[i] = currentKeyState[i];
|
||||||
@ -1975,13 +1963,62 @@ static void PollInputEvents(void)
|
|||||||
|
|
||||||
previousMouseWheelY = currentMouseWheelY;
|
previousMouseWheelY = currentMouseWheelY;
|
||||||
currentMouseWheelY = 0;
|
currentMouseWheelY = 0;
|
||||||
|
|
||||||
|
// Check if gamepads are ready
|
||||||
|
// NOTE: We do it here in case of disconection
|
||||||
|
for (int i = 0; i < MAX_GAMEPADS; i++)
|
||||||
|
{
|
||||||
|
if (glfwJoystickPresent(i)) gamepadReady[i] = true;
|
||||||
|
else gamepadReady[i] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register gamepads buttons events
|
||||||
|
for (int i = 0; i < MAX_GAMEPADS; i++)
|
||||||
|
{
|
||||||
|
if (gamepadReady[i]) // Check if gamepad is available
|
||||||
|
{
|
||||||
|
// Register previous gamepad states
|
||||||
|
for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) previousGamepadState[i][k] = currentGamepadState[i][k];
|
||||||
|
|
||||||
|
// Get current gamepad state
|
||||||
|
// NOTE: There is no callback available, so we get it manually
|
||||||
|
const unsigned char *buttons;
|
||||||
|
int buttonsCount;
|
||||||
|
|
||||||
glfwPollEvents(); // Register keyboard/mouse events... and window events!
|
buttons = glfwGetJoystickButtons(i, &buttonsCount);
|
||||||
|
|
||||||
|
for (int k = 0; (buttons != NULL) && (k < buttonsCount) && (buttonsCount < MAX_GAMEPAD_BUTTONS); k++)
|
||||||
|
{
|
||||||
|
if (buttons[k] == GLFW_PRESS)
|
||||||
|
{
|
||||||
|
currentGamepadState[i][k] = 1;
|
||||||
|
lastGamepadButtonPressed = k;
|
||||||
|
}
|
||||||
|
else currentGamepadState[i][k] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get current axis state
|
||||||
|
const float *axes;
|
||||||
|
int axisCount = 0;
|
||||||
|
|
||||||
|
axes = glfwGetJoystickAxes(i, &axisCount);
|
||||||
|
|
||||||
|
for (int k = 0; (axes != NULL) && (k < axisCount) && (k < MAX_GAMEPAD_AXIS); k++)
|
||||||
|
{
|
||||||
|
gamepadAxisState[i][k] = axes[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
gamepadAxisCount = axisCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwPollEvents(); // Register keyboard/mouse events (callbacks)... and window events!
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PLATFORM_ANDROID)
|
#if defined(PLATFORM_ANDROID)
|
||||||
// Register previous keys states
|
// Register previous keys states
|
||||||
for (int i = 0; i < 128; i++) previousButtonState[i] = currentButtonState[i];
|
// NOTE: Android supports up to 260 keys
|
||||||
|
for (int i = 0; i < 260; i++) previousKeyState[i] = currentKeyState[i];
|
||||||
|
|
||||||
// Poll Events (registered events)
|
// Poll Events (registered events)
|
||||||
// NOTE: Activity is paused if not enabled (appEnabled)
|
// NOTE: Activity is paused if not enabled (appEnabled)
|
||||||
@ -2245,9 +2282,11 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
|||||||
// Init graphics device (display device and OpenGL context)
|
// Init graphics device (display device and OpenGL context)
|
||||||
InitGraphicsDevice(screenWidth, screenHeight);
|
InitGraphicsDevice(screenWidth, screenHeight);
|
||||||
|
|
||||||
// Load default font for convenience
|
#if defined(RL_LOAD_DEFAULT_FONT)
|
||||||
|
// Load default font
|
||||||
// NOTE: External function (defined in module: text)
|
// NOTE: External function (defined in module: text)
|
||||||
LoadDefaultFont();
|
LoadDefaultFont();
|
||||||
|
#endif
|
||||||
|
|
||||||
// TODO: GPU assets reload in case of lost focus (lost context)
|
// TODO: GPU assets reload in case of lost focus (lost context)
|
||||||
// NOTE: This problem has been solved just unbinding and rebinding context from display
|
// NOTE: This problem has been solved just unbinding and rebinding context from display
|
||||||
@ -2356,7 +2395,13 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
|||||||
//int32_t AKeyEvent_getMetaState(event);
|
//int32_t AKeyEvent_getMetaState(event);
|
||||||
|
|
||||||
// Save current button and its state
|
// Save current button and its state
|
||||||
currentButtonState[keycode] = AKeyEvent_getAction(event); // Down = 0, Up = 1
|
// NOTE: Android key action is 0 for down and 1 for up
|
||||||
|
if (AKeyEvent_getAction(event) == 0)
|
||||||
|
{
|
||||||
|
currentKeyState[keycode] = 1; // Key down
|
||||||
|
lastKeyPressed = keycode;
|
||||||
|
}
|
||||||
|
else currentKeyState[keycode] = 0; // Key up
|
||||||
|
|
||||||
if (keycode == AKEYCODE_POWER)
|
if (keycode == AKEYCODE_POWER)
|
||||||
{
|
{
|
||||||
@ -2802,7 +2847,9 @@ static void *GamepadThread(void *arg)
|
|||||||
if (gamepadEvent.number < MAX_GAMEPAD_BUTTONS)
|
if (gamepadEvent.number < MAX_GAMEPAD_BUTTONS)
|
||||||
{
|
{
|
||||||
// 1 - button pressed, 0 - button released
|
// 1 - button pressed, 0 - button released
|
||||||
gamepadButtons[i][gamepadEvent.number] = (int)gamepadEvent.value;
|
currentGamepadState[i][gamepadEvent.number] = (int)gamepadEvent.value;
|
||||||
|
|
||||||
|
if ((int)gamepadEvent.value == 1) lastGamepadButtonPressed = gamepadEvent.number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (gamepadEvent.type == JS_EVENT_AXIS)
|
else if (gamepadEvent.type == JS_EVENT_AXIS)
|
||||||
@ -2812,7 +2859,7 @@ static void *GamepadThread(void *arg)
|
|||||||
if (gamepadEvent.number < MAX_GAMEPAD_AXIS)
|
if (gamepadEvent.number < MAX_GAMEPAD_AXIS)
|
||||||
{
|
{
|
||||||
// NOTE: Scaling of gamepadEvent.value to get values between -1..1
|
// NOTE: Scaling of gamepadEvent.value to get values between -1..1
|
||||||
gamepadAxisValues[i][gamepadEvent.number] = (float)gamepadEvent.value/32768;
|
gamepadAxisState[i][gamepadEvent.number] = (float)gamepadEvent.value/32768;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4395
src/external/dr_flac.h
vendored
Normal file
4395
src/external/dr_flac.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
5
src/external/openal_soft/include/AL/alext.h
vendored
5
src/external/openal_soft/include/AL/alext.h
vendored
@ -431,6 +431,11 @@ ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCi
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef AL_SOFT_gain_clamp_ex
|
||||||
|
#define AL_SOFT_gain_clamp_ex 1
|
||||||
|
#define AL_GAIN_LIMIT_SOFT 0x200E
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
BIN
src/external/openal_soft/lib/win32/libOpenAL32.a
vendored
Normal file
BIN
src/external/openal_soft/lib/win32/libOpenAL32.a
vendored
Normal file
Binary file not shown.
118
src/models.c
118
src/models.c
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Basic functions to draw 3d shapes and load/draw 3d models (.OBJ)
|
* Basic functions to draw 3d shapes and load/draw 3d models (.OBJ)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||||
* will the authors be held liable for any damages arising from the use of this software.
|
* will the authors be held liable for any damages arising from the use of this software.
|
||||||
@ -87,8 +87,8 @@ void DrawCircle3D(Vector3 center, float radius, float rotationAngle, Vector3 rot
|
|||||||
{
|
{
|
||||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
|
|
||||||
rlVertex3f(sin(DEG2RAD*i)*radius, cos(DEG2RAD*i)*radius, 0.0f);
|
rlVertex3f(sinf(DEG2RAD*i)*radius, cosf(DEG2RAD*i)*radius, 0.0f);
|
||||||
rlVertex3f(sin(DEG2RAD*(i + 10))*radius, cos(DEG2RAD*(i + 10))*radius, 0.0f);
|
rlVertex3f(sinf(DEG2RAD*(i + 10))*radius, cosf(DEG2RAD*(i + 10))*radius, 0.0f);
|
||||||
}
|
}
|
||||||
rlEnd();
|
rlEnd();
|
||||||
rlPopMatrix();
|
rlPopMatrix();
|
||||||
@ -325,25 +325,25 @@ void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color
|
|||||||
{
|
{
|
||||||
for (int j = 0; j < slices; j++)
|
for (int j = 0; j < slices; j++)
|
||||||
{
|
{
|
||||||
rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i))*sin(DEG2RAD*(j*360/slices)),
|
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*i))*sinf(DEG2RAD*(j*360/slices)),
|
||||||
sin(DEG2RAD*(270+(180/(rings + 1))*i)),
|
sinf(DEG2RAD*(270+(180/(rings + 1))*i)),
|
||||||
cos(DEG2RAD*(270+(180/(rings + 1))*i))*cos(DEG2RAD*(j*360/slices)));
|
cosf(DEG2RAD*(270+(180/(rings + 1))*i))*cosf(DEG2RAD*(j*360/slices)));
|
||||||
rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sin(DEG2RAD*((j+1)*360/slices)),
|
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360/slices)),
|
||||||
sin(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
|
sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
|
||||||
cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cos(DEG2RAD*((j+1)*360/slices)));
|
cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360/slices)));
|
||||||
rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sin(DEG2RAD*(j*360/slices)),
|
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*(j*360/slices)),
|
||||||
sin(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
|
sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
|
||||||
cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cos(DEG2RAD*(j*360/slices)));
|
cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*(j*360/slices)));
|
||||||
|
|
||||||
rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i))*sin(DEG2RAD*(j*360/slices)),
|
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*i))*sinf(DEG2RAD*(j*360/slices)),
|
||||||
sin(DEG2RAD*(270+(180/(rings + 1))*i)),
|
sinf(DEG2RAD*(270+(180/(rings + 1))*i)),
|
||||||
cos(DEG2RAD*(270+(180/(rings + 1))*i))*cos(DEG2RAD*(j*360/slices)));
|
cosf(DEG2RAD*(270+(180/(rings + 1))*i))*cosf(DEG2RAD*(j*360/slices)));
|
||||||
rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i)))*sin(DEG2RAD*((j+1)*360/slices)),
|
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i)))*sinf(DEG2RAD*((j+1)*360/slices)),
|
||||||
sin(DEG2RAD*(270+(180/(rings + 1))*(i))),
|
sinf(DEG2RAD*(270+(180/(rings + 1))*(i))),
|
||||||
cos(DEG2RAD*(270+(180/(rings + 1))*(i)))*cos(DEG2RAD*((j+1)*360/slices)));
|
cosf(DEG2RAD*(270+(180/(rings + 1))*(i)))*cosf(DEG2RAD*((j+1)*360/slices)));
|
||||||
rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sin(DEG2RAD*((j+1)*360/slices)),
|
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360/slices)),
|
||||||
sin(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
|
sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
|
||||||
cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cos(DEG2RAD*((j+1)*360/slices)));
|
cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360/slices)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rlEnd();
|
rlEnd();
|
||||||
@ -364,26 +364,26 @@ void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Col
|
|||||||
{
|
{
|
||||||
for (int j = 0; j < slices; j++)
|
for (int j = 0; j < slices; j++)
|
||||||
{
|
{
|
||||||
rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i))*sin(DEG2RAD*(j*360/slices)),
|
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*i))*sinf(DEG2RAD*(j*360/slices)),
|
||||||
sin(DEG2RAD*(270+(180/(rings + 1))*i)),
|
sinf(DEG2RAD*(270+(180/(rings + 1))*i)),
|
||||||
cos(DEG2RAD*(270+(180/(rings + 1))*i))*cos(DEG2RAD*(j*360/slices)));
|
cosf(DEG2RAD*(270+(180/(rings + 1))*i))*cosf(DEG2RAD*(j*360/slices)));
|
||||||
rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sin(DEG2RAD*((j+1)*360/slices)),
|
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360/slices)),
|
||||||
sin(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
|
sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
|
||||||
cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cos(DEG2RAD*((j+1)*360/slices)));
|
cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360/slices)));
|
||||||
|
|
||||||
rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sin(DEG2RAD*((j+1)*360/slices)),
|
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360/slices)),
|
||||||
sin(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
|
sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
|
||||||
cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cos(DEG2RAD*((j+1)*360/slices)));
|
cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360/slices)));
|
||||||
rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sin(DEG2RAD*(j*360/slices)),
|
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*(j*360/slices)),
|
||||||
sin(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
|
sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
|
||||||
cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cos(DEG2RAD*(j*360/slices)));
|
cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*(j*360/slices)));
|
||||||
|
|
||||||
rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sin(DEG2RAD*(j*360/slices)),
|
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*(j*360/slices)),
|
||||||
sin(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
|
sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
|
||||||
cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cos(DEG2RAD*(j*360/slices)));
|
cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*(j*360/slices)));
|
||||||
rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i))*sin(DEG2RAD*(j*360/slices)),
|
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*i))*sinf(DEG2RAD*(j*360/slices)),
|
||||||
sin(DEG2RAD*(270+(180/(rings + 1))*i)),
|
sinf(DEG2RAD*(270+(180/(rings + 1))*i)),
|
||||||
cos(DEG2RAD*(270+(180/(rings + 1))*i))*cos(DEG2RAD*(j*360/slices)));
|
cosf(DEG2RAD*(270+(180/(rings + 1))*i))*cosf(DEG2RAD*(j*360/slices)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rlEnd();
|
rlEnd();
|
||||||
@ -407,21 +407,21 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
|
|||||||
// Draw Body -------------------------------------------------------------------------------------
|
// Draw Body -------------------------------------------------------------------------------------
|
||||||
for (int i = 0; i < 360; i += 360/sides)
|
for (int i = 0; i < 360; i += 360/sides)
|
||||||
{
|
{
|
||||||
rlVertex3f(sin(DEG2RAD*i)*radiusBottom, 0, cos(DEG2RAD*i)*radiusBottom); //Bottom Left
|
rlVertex3f(sinf(DEG2RAD*i)*radiusBottom, 0, cosf(DEG2RAD*i)*radiusBottom); //Bottom Left
|
||||||
rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusBottom, 0, cos(DEG2RAD*(i+360/sides))*radiusBottom); //Bottom Right
|
rlVertex3f(sinf(DEG2RAD*(i+360/sides))*radiusBottom, 0, cosf(DEG2RAD*(i+360/sides))*radiusBottom); //Bottom Right
|
||||||
rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusTop, height, cos(DEG2RAD*(i+360/sides))*radiusTop); //Top Right
|
rlVertex3f(sinf(DEG2RAD*(i+360/sides))*radiusTop, height, cosf(DEG2RAD*(i+360/sides))*radiusTop); //Top Right
|
||||||
|
|
||||||
rlVertex3f(sin(DEG2RAD*i)*radiusTop, height, cos(DEG2RAD*i)*radiusTop); //Top Left
|
rlVertex3f(sinf(DEG2RAD*i)*radiusTop, height, cosf(DEG2RAD*i)*radiusTop); //Top Left
|
||||||
rlVertex3f(sin(DEG2RAD*i)*radiusBottom, 0, cos(DEG2RAD*i)*radiusBottom); //Bottom Left
|
rlVertex3f(sinf(DEG2RAD*i)*radiusBottom, 0, cosf(DEG2RAD*i)*radiusBottom); //Bottom Left
|
||||||
rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusTop, height, cos(DEG2RAD*(i+360/sides))*radiusTop); //Top Right
|
rlVertex3f(sinf(DEG2RAD*(i+360/sides))*radiusTop, height, cosf(DEG2RAD*(i+360/sides))*radiusTop); //Top Right
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw Cap --------------------------------------------------------------------------------------
|
// Draw Cap --------------------------------------------------------------------------------------
|
||||||
for (int i = 0; i < 360; i += 360/sides)
|
for (int i = 0; i < 360; i += 360/sides)
|
||||||
{
|
{
|
||||||
rlVertex3f(0, height, 0);
|
rlVertex3f(0, height, 0);
|
||||||
rlVertex3f(sin(DEG2RAD*i)*radiusTop, height, cos(DEG2RAD*i)*radiusTop);
|
rlVertex3f(sinf(DEG2RAD*i)*radiusTop, height, cosf(DEG2RAD*i)*radiusTop);
|
||||||
rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusTop, height, cos(DEG2RAD*(i+360/sides))*radiusTop);
|
rlVertex3f(sinf(DEG2RAD*(i+360/sides))*radiusTop, height, cosf(DEG2RAD*(i+360/sides))*radiusTop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -430,8 +430,8 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
|
|||||||
for (int i = 0; i < 360; i += 360/sides)
|
for (int i = 0; i < 360; i += 360/sides)
|
||||||
{
|
{
|
||||||
rlVertex3f(0, height, 0);
|
rlVertex3f(0, height, 0);
|
||||||
rlVertex3f(sin(DEG2RAD*i)*radiusBottom, 0, cos(DEG2RAD*i)*radiusBottom);
|
rlVertex3f(sinf(DEG2RAD*i)*radiusBottom, 0, cosf(DEG2RAD*i)*radiusBottom);
|
||||||
rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusBottom, 0, cos(DEG2RAD*(i+360/sides))*radiusBottom);
|
rlVertex3f(sinf(DEG2RAD*(i+360/sides))*radiusBottom, 0, cosf(DEG2RAD*(i+360/sides))*radiusBottom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,8 +439,8 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
|
|||||||
for (int i = 0; i < 360; i += 360/sides)
|
for (int i = 0; i < 360; i += 360/sides)
|
||||||
{
|
{
|
||||||
rlVertex3f(0, 0, 0);
|
rlVertex3f(0, 0, 0);
|
||||||
rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusBottom, 0, cos(DEG2RAD*(i+360/sides))*radiusBottom);
|
rlVertex3f(sinf(DEG2RAD*(i+360/sides))*radiusBottom, 0, cosf(DEG2RAD*(i+360/sides))*radiusBottom);
|
||||||
rlVertex3f(sin(DEG2RAD*i)*radiusBottom, 0, cos(DEG2RAD*i)*radiusBottom);
|
rlVertex3f(sinf(DEG2RAD*i)*radiusBottom, 0, cosf(DEG2RAD*i)*radiusBottom);
|
||||||
}
|
}
|
||||||
rlEnd();
|
rlEnd();
|
||||||
rlPopMatrix();
|
rlPopMatrix();
|
||||||
@ -460,17 +460,17 @@ void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, fl
|
|||||||
|
|
||||||
for (int i = 0; i < 360; i += 360/sides)
|
for (int i = 0; i < 360; i += 360/sides)
|
||||||
{
|
{
|
||||||
rlVertex3f(sin(DEG2RAD*i)*radiusBottom, 0, cos(DEG2RAD*i)*radiusBottom);
|
rlVertex3f(sinf(DEG2RAD*i)*radiusBottom, 0, cosf(DEG2RAD*i)*radiusBottom);
|
||||||
rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusBottom, 0, cos(DEG2RAD*(i+360/sides))*radiusBottom);
|
rlVertex3f(sinf(DEG2RAD*(i+360/sides))*radiusBottom, 0, cosf(DEG2RAD*(i+360/sides))*radiusBottom);
|
||||||
|
|
||||||
rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusBottom, 0, cos(DEG2RAD*(i+360/sides))*radiusBottom);
|
rlVertex3f(sinf(DEG2RAD*(i+360/sides))*radiusBottom, 0, cosf(DEG2RAD*(i+360/sides))*radiusBottom);
|
||||||
rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusTop, height, cos(DEG2RAD*(i+360/sides))*radiusTop);
|
rlVertex3f(sinf(DEG2RAD*(i+360/sides))*radiusTop, height, cosf(DEG2RAD*(i+360/sides))*radiusTop);
|
||||||
|
|
||||||
rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusTop, height, cos(DEG2RAD*(i+360/sides))*radiusTop);
|
rlVertex3f(sinf(DEG2RAD*(i+360/sides))*radiusTop, height, cosf(DEG2RAD*(i+360/sides))*radiusTop);
|
||||||
rlVertex3f(sin(DEG2RAD*i)*radiusTop, height, cos(DEG2RAD*i)*radiusTop);
|
rlVertex3f(sinf(DEG2RAD*i)*radiusTop, height, cosf(DEG2RAD*i)*radiusTop);
|
||||||
|
|
||||||
rlVertex3f(sin(DEG2RAD*i)*radiusTop, height, cos(DEG2RAD*i)*radiusTop);
|
rlVertex3f(sinf(DEG2RAD*i)*radiusTop, height, cosf(DEG2RAD*i)*radiusTop);
|
||||||
rlVertex3f(sin(DEG2RAD*i)*radiusBottom, 0, cos(DEG2RAD*i)*radiusBottom);
|
rlVertex3f(sinf(DEG2RAD*i)*radiusBottom, 0, cosf(DEG2RAD*i)*radiusBottom);
|
||||||
}
|
}
|
||||||
rlEnd();
|
rlEnd();
|
||||||
rlPopMatrix();
|
rlPopMatrix();
|
||||||
|
140
src/raylib.h
140
src/raylib.h
@ -77,10 +77,6 @@
|
|||||||
#define PLATFORM_DESKTOP
|
#define PLATFORM_DESKTOP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PLATFORM_ANDROID)
|
|
||||||
typedef struct android_app; // Define android_app struct (android_native_app_glue.h)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(BUILDING_DLL)
|
#if defined(_WIN32) && defined(BUILDING_DLL)
|
||||||
#define RLAPI __declspec(dllexport) // We are building raylib as a Win32 DLL
|
#define RLAPI __declspec(dllexport) // We are building raylib as a Win32 DLL
|
||||||
#elif defined(_WIN32) && defined(RAYLIB_DLL)
|
#elif defined(_WIN32) && defined(RAYLIB_DLL)
|
||||||
@ -93,7 +89,7 @@
|
|||||||
// Some basic Defines
|
// Some basic Defines
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
#ifndef PI
|
#ifndef PI
|
||||||
#define PI 3.14159265358979323846
|
#define PI 3.14159265358979323846f
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DEG2RAD (PI/180.0f)
|
#define DEG2RAD (PI/180.0f)
|
||||||
@ -174,15 +170,18 @@
|
|||||||
#define KEY_Y 89
|
#define KEY_Y 89
|
||||||
#define KEY_Z 90
|
#define KEY_Z 90
|
||||||
|
|
||||||
|
#if defined(PLATFORM_ANDROID)
|
||||||
|
// Android Physical Buttons
|
||||||
|
#define KEY_BACK 4
|
||||||
|
#define KEY_MENU 82
|
||||||
|
#define KEY_VOLUME_UP 24
|
||||||
|
#define KEY_VOLUME_DOWN 25
|
||||||
|
#endif
|
||||||
|
|
||||||
// Mouse Buttons
|
// Mouse Buttons
|
||||||
#define MOUSE_LEFT_BUTTON 0
|
#define MOUSE_LEFT_BUTTON 0
|
||||||
#if defined(PLATFORM_WEB)
|
#define MOUSE_RIGHT_BUTTON 1
|
||||||
#define MOUSE_RIGHT_BUTTON 2
|
#define MOUSE_MIDDLE_BUTTON 2
|
||||||
#define MOUSE_MIDDLE_BUTTON 1
|
|
||||||
#else
|
|
||||||
#define MOUSE_RIGHT_BUTTON 1
|
|
||||||
#define MOUSE_MIDDLE_BUTTON 2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Touch points registered
|
// Touch points registered
|
||||||
#define MAX_TOUCH_POINTS 2
|
#define MAX_TOUCH_POINTS 2
|
||||||
@ -190,24 +189,35 @@
|
|||||||
// Gamepad Number
|
// Gamepad Number
|
||||||
#define GAMEPAD_PLAYER1 0
|
#define GAMEPAD_PLAYER1 0
|
||||||
#define GAMEPAD_PLAYER2 1
|
#define GAMEPAD_PLAYER2 1
|
||||||
#define GAMEPAD_PLAYER3 2 // Not supported
|
#define GAMEPAD_PLAYER3 2
|
||||||
#define GAMEPAD_PLAYER4 3 // Not supported
|
#define GAMEPAD_PLAYER4 3
|
||||||
|
|
||||||
// Gamepad Buttons
|
// Gamepad Buttons/Axis
|
||||||
|
|
||||||
// PS3 USB Controller
|
// PS3 USB Controller Buttons
|
||||||
#define GAMEPAD_PS3_BUTTON_A 2
|
#define GAMEPAD_PS3_BUTTON_TRIANGLE 0
|
||||||
#define GAMEPAD_PS3_BUTTON_B 1
|
#define GAMEPAD_PS3_BUTTON_CIRCLE 1
|
||||||
#define GAMEPAD_PS3_BUTTON_X 3
|
#define GAMEPAD_PS3_BUTTON_CROSS 2
|
||||||
#define GAMEPAD_PS3_BUTTON_Y 4
|
#define GAMEPAD_PS3_BUTTON_SQUARE 3
|
||||||
#define GAMEPAD_PS3_BUTTON_R1 7
|
|
||||||
#define GAMEPAD_PS3_BUTTON_R2 5
|
|
||||||
#define GAMEPAD_PS3_BUTTON_L1 6
|
#define GAMEPAD_PS3_BUTTON_L1 6
|
||||||
#define GAMEPAD_PS3_BUTTON_L2 8
|
#define GAMEPAD_PS3_BUTTON_R1 7
|
||||||
|
#define GAMEPAD_PS3_BUTTON_L2 4
|
||||||
|
#define GAMEPAD_PS3_BUTTON_R2 5
|
||||||
|
#define GAMEPAD_PS3_BUTTON_START 8
|
||||||
#define GAMEPAD_PS3_BUTTON_SELECT 9
|
#define GAMEPAD_PS3_BUTTON_SELECT 9
|
||||||
#define GAMEPAD_PS3_BUTTON_START 10
|
#define GAMEPAD_PS3_BUTTON_UP 24
|
||||||
|
#define GAMEPAD_PS3_BUTTON_RIGHT 25
|
||||||
|
#define GAMEPAD_PS3_BUTTON_DOWN 26
|
||||||
|
#define GAMEPAD_PS3_BUTTON_LEFT 27
|
||||||
|
#define GAMEPAD_PS3_BUTTON_PS 12
|
||||||
|
|
||||||
// TODO: Add PS3 d-pad axis
|
// PS3 USB Controller Axis
|
||||||
|
#define GAMEPAD_PS3_AXIS_LEFT_X 0
|
||||||
|
#define GAMEPAD_PS3_AXIS_LEFT_Y 1
|
||||||
|
#define GAMEPAD_PS3_AXIS_RIGHT_X 2
|
||||||
|
#define GAMEPAD_PS3_AXIS_RIGHT_Y 5
|
||||||
|
#define GAMEPAD_PS3_AXIS_L2 3 // 1.0(not pressed) --> -1.0(completely pressed)
|
||||||
|
#define GAMEPAD_PS3_AXIS_R2 4 // 1.0(not pressed) --> -1.0(completely pressed)
|
||||||
|
|
||||||
// Xbox360 USB Controller Buttons
|
// Xbox360 USB Controller Buttons
|
||||||
#define GAMEPAD_XBOX_BUTTON_A 0
|
#define GAMEPAD_XBOX_BUTTON_A 0
|
||||||
@ -218,32 +228,31 @@
|
|||||||
#define GAMEPAD_XBOX_BUTTON_RB 5
|
#define GAMEPAD_XBOX_BUTTON_RB 5
|
||||||
#define GAMEPAD_XBOX_BUTTON_SELECT 6
|
#define GAMEPAD_XBOX_BUTTON_SELECT 6
|
||||||
#define GAMEPAD_XBOX_BUTTON_START 7
|
#define GAMEPAD_XBOX_BUTTON_START 7
|
||||||
|
#define GAMEPAD_XBOX_BUTTON_UP 10
|
||||||
|
#define GAMEPAD_XBOX_BUTTON_RIGHT 11
|
||||||
|
#define GAMEPAD_XBOX_BUTTON_DOWN 12
|
||||||
|
#define GAMEPAD_XBOX_BUTTON_LEFT 13
|
||||||
|
#define GAMEPAD_XBOX_BUTTON_HOME 9
|
||||||
|
|
||||||
|
// Xbox360 USB Controller Axis
|
||||||
|
#define GAMEPAD_XBOX_AXIS_LEFT_X 0
|
||||||
|
#define GAMEPAD_XBOX_AXIS_LEFT_Y 1
|
||||||
|
#define GAMEPAD_XBOX_AXIS_RIGHT_X 2
|
||||||
|
#define GAMEPAD_XBOX_AXIS_RIGHT_Y 3
|
||||||
|
#define GAMEPAD_XBOX_AXIS_LT 4 // -1.0(not pressed) --> 1.0(completely pressed)
|
||||||
|
#define GAMEPAD_XBOX_AXIS_RT 5 // -1.0(not pressed) --> 1.0(completely pressed)
|
||||||
|
|
||||||
|
/*
|
||||||
|
// NOTE: For Raspberry Pi, axis must be reconfigured
|
||||||
#if defined(PLATFORM_RPI)
|
#if defined(PLATFORM_RPI)
|
||||||
#define GAMEPAD_XBOX_AXIS_DPAD_X 7
|
#define GAMEPAD_XBOX_AXIS_LEFT_X 7
|
||||||
#define GAMEPAD_XBOX_AXIS_DPAD_Y 6
|
#define GAMEPAD_XBOX_AXIS_LEFT_Y 6
|
||||||
#define GAMEPAD_XBOX_AXIS_RIGHT_X 3
|
#define GAMEPAD_XBOX_AXIS_RIGHT_X 3
|
||||||
#define GAMEPAD_XBOX_AXIS_RIGHT_Y 4
|
#define GAMEPAD_XBOX_AXIS_RIGHT_Y 4
|
||||||
#define GAMEPAD_XBOX_AXIS_LT 2
|
#define GAMEPAD_XBOX_AXIS_LT 2
|
||||||
#define GAMEPAD_XBOX_AXIS_RT 5
|
#define GAMEPAD_XBOX_AXIS_RT 5
|
||||||
#else
|
|
||||||
#define GAMEPAD_XBOX_BUTTON_UP 10
|
|
||||||
#define GAMEPAD_XBOX_BUTTON_DOWN 12
|
|
||||||
#define GAMEPAD_XBOX_BUTTON_LEFT 13
|
|
||||||
#define GAMEPAD_XBOX_BUTTON_RIGHT 11
|
|
||||||
#define GAMEPAD_XBOX_AXIS_RIGHT_X 4
|
|
||||||
#define GAMEPAD_XBOX_AXIS_RIGHT_Y 3
|
|
||||||
#define GAMEPAD_XBOX_AXIS_LT_RT 2
|
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
#define GAMEPAD_XBOX_AXIS_LEFT_X 0
|
|
||||||
#define GAMEPAD_XBOX_AXIS_LEFT_Y 1
|
|
||||||
|
|
||||||
// Android Physic Buttons
|
|
||||||
#define ANDROID_BACK 4
|
|
||||||
#define ANDROID_MENU 82
|
|
||||||
#define ANDROID_VOLUME_UP 24
|
|
||||||
#define ANDROID_VOLUME_DOWN 25
|
|
||||||
|
|
||||||
// NOTE: MSC C++ compiler does not support compound literals (C99 feature)
|
// NOTE: MSC C++ compiler does not support compound literals (C99 feature)
|
||||||
// Plain structures in C++ (without constructors) can be initialized from { } initializers.
|
// Plain structures in C++ (without constructors) can be initialized from { } initializers.
|
||||||
@ -540,6 +549,21 @@ typedef enum {
|
|||||||
COMPRESSED_ASTC_8x8_RGBA // 2 bpp
|
COMPRESSED_ASTC_8x8_RGBA // 2 bpp
|
||||||
} TextureFormat;
|
} TextureFormat;
|
||||||
|
|
||||||
|
// Texture parameters: filter mode
|
||||||
|
// NOTE 1: Filtering considers mipmaps if available in the texture
|
||||||
|
// NOTE 2: Filter is accordingly set for minification and magnification
|
||||||
|
typedef enum {
|
||||||
|
FILTER_POINT = 0, // No filter, just pixel aproximation
|
||||||
|
FILTER_BILINEAR, // Linear filtering
|
||||||
|
FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps)
|
||||||
|
FILTER_ANISOTROPIC_4X, // Anisotropic filtering 4x
|
||||||
|
FILTER_ANISOTROPIC_8X, // Anisotropic filtering 8x
|
||||||
|
FILTER_ANISOTROPIC_16X, // Anisotropic filtering 16x
|
||||||
|
} TextureFilterMode;
|
||||||
|
|
||||||
|
// Texture parameters: wrap mode
|
||||||
|
typedef enum { WRAP_REPEAT = 0, WRAP_CLAMP, WRAP_MIRROR } TextureWrapMode;
|
||||||
|
|
||||||
// Color blending modes (pre-defined)
|
// Color blending modes (pre-defined)
|
||||||
typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode;
|
typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode;
|
||||||
|
|
||||||
@ -594,7 +618,7 @@ extern "C" { // Prevents name mangling of functions
|
|||||||
// Window and Graphics Device Functions (Module: core)
|
// Window and Graphics Device Functions (Module: core)
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
#if defined(PLATFORM_ANDROID)
|
#if defined(PLATFORM_ANDROID)
|
||||||
RLAPI void InitWindow(int width, int height, struct android_app *state); // Init Android Activity and OpenGL Graphics
|
RLAPI void InitWindow(int width, int height, void *state); // Init Android Activity and OpenGL Graphics (struct android_app)
|
||||||
#elif defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
#elif defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
||||||
RLAPI void InitWindow(int width, int height, const char *title); // Initialize Window and OpenGL Graphics
|
RLAPI void InitWindow(int width, int height, const char *title); // Initialize Window and OpenGL Graphics
|
||||||
#endif
|
#endif
|
||||||
@ -606,11 +630,13 @@ RLAPI void ToggleFullscreen(void); // Fullscreen
|
|||||||
RLAPI int GetScreenWidth(void); // Get current screen width
|
RLAPI int GetScreenWidth(void); // Get current screen width
|
||||||
RLAPI int GetScreenHeight(void); // Get current screen height
|
RLAPI int GetScreenHeight(void); // Get current screen height
|
||||||
|
|
||||||
|
#if !defined(PLATFORM_ANDROID)
|
||||||
RLAPI void ShowCursor(void); // Shows cursor
|
RLAPI void ShowCursor(void); // Shows cursor
|
||||||
RLAPI void HideCursor(void); // Hides cursor
|
RLAPI void HideCursor(void); // Hides cursor
|
||||||
RLAPI bool IsCursorHidden(void); // Returns true if cursor is not visible
|
RLAPI bool IsCursorHidden(void); // Returns true if cursor is not visible
|
||||||
RLAPI void EnableCursor(void); // Enables cursor
|
RLAPI void EnableCursor(void); // Enables cursor
|
||||||
RLAPI void DisableCursor(void); // Disables cursor
|
RLAPI void DisableCursor(void); // Disables cursor
|
||||||
|
#endif
|
||||||
|
|
||||||
RLAPI void ClearBackground(Color color); // Sets Background Color
|
RLAPI void ClearBackground(Color color); // Sets Background Color
|
||||||
RLAPI void BeginDrawing(void); // Setup drawing canvas to start drawing
|
RLAPI void BeginDrawing(void); // Setup drawing canvas to start drawing
|
||||||
@ -653,7 +679,6 @@ RLAPI int StorageLoadValue(int position); // Storage loa
|
|||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Input Handling Functions (Module: core)
|
// Input Handling Functions (Module: core)
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
|
||||||
RLAPI bool IsKeyPressed(int key); // Detect if a key has been pressed once
|
RLAPI bool IsKeyPressed(int key); // Detect if a key has been pressed once
|
||||||
RLAPI bool IsKeyDown(int key); // Detect if a key is being pressed
|
RLAPI bool IsKeyDown(int key); // Detect if a key is being pressed
|
||||||
RLAPI bool IsKeyReleased(int key); // Detect if a key has been released once
|
RLAPI bool IsKeyReleased(int key); // Detect if a key has been released once
|
||||||
@ -662,12 +687,15 @@ RLAPI int GetKeyPressed(void); // Get latest key
|
|||||||
RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
|
RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
|
||||||
|
|
||||||
RLAPI bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
|
RLAPI bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
|
||||||
RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Return axis movement value for a gamepad axis
|
RLAPI bool IsGamepadName(int gamepad, const char *name); // Check gamepad name (if available)
|
||||||
|
RLAPI const char *GetGamepadName(int gamepad); // Return gamepad internal name id
|
||||||
RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Detect if a gamepad button has been pressed once
|
RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Detect if a gamepad button has been pressed once
|
||||||
RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Detect if a gamepad button is being pressed
|
RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Detect if a gamepad button is being pressed
|
||||||
RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Detect if a gamepad button has been released once
|
RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Detect if a gamepad button has been released once
|
||||||
RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Detect if a gamepad button is NOT being pressed
|
RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Detect if a gamepad button is NOT being pressed
|
||||||
#endif
|
RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed
|
||||||
|
RLAPI int GetGamepadAxisCount(int gamepad); // Return gamepad axis count for a gamepad
|
||||||
|
RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Return axis movement value for a gamepad axis
|
||||||
|
|
||||||
RLAPI bool IsMouseButtonPressed(int button); // Detect if a mouse button has been pressed once
|
RLAPI bool IsMouseButtonPressed(int button); // Detect if a mouse button has been pressed once
|
||||||
RLAPI bool IsMouseButtonDown(int button); // Detect if a mouse button is being pressed
|
RLAPI bool IsMouseButtonDown(int button); // Detect if a mouse button is being pressed
|
||||||
@ -683,12 +711,6 @@ RLAPI int GetTouchX(void); // Returns touch p
|
|||||||
RLAPI int GetTouchY(void); // Returns touch position Y for touch point 0 (relative to screen size)
|
RLAPI int GetTouchY(void); // Returns touch position Y for touch point 0 (relative to screen size)
|
||||||
RLAPI Vector2 GetTouchPosition(int index); // Returns touch position XY for a touch point index (relative to screen size)
|
RLAPI Vector2 GetTouchPosition(int index); // Returns touch position XY for a touch point index (relative to screen size)
|
||||||
|
|
||||||
#if defined(PLATFORM_ANDROID)
|
|
||||||
bool IsButtonPressed(int button); // Detect if an android physic button has been pressed
|
|
||||||
bool IsButtonDown(int button); // Detect if an android physic button is being pressed
|
|
||||||
bool IsButtonReleased(int button); // Detect if an android physic button has been released
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Gestures and Touch Handling Functions (Module: gestures)
|
// Gestures and Touch Handling Functions (Module: gestures)
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
@ -762,6 +784,7 @@ RLAPI void UnloadTexture(Texture2D texture);
|
|||||||
RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory
|
RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory
|
||||||
RLAPI Color *GetImageData(Image image); // Get pixel data from image as a Color struct array
|
RLAPI Color *GetImageData(Image image); // Get pixel data from image as a Color struct array
|
||||||
RLAPI Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image
|
RLAPI Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image
|
||||||
|
RLAPI void UpdateTexture(Texture2D texture, void *pixels); // Update GPU texture with new data
|
||||||
RLAPI void ImageToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two)
|
RLAPI void ImageToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two)
|
||||||
RLAPI void ImageFormat(Image *image, int newFormat); // Convert image data to desired format
|
RLAPI void ImageFormat(Image *image, int newFormat); // Convert image data to desired format
|
||||||
RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image
|
RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image
|
||||||
@ -783,7 +806,8 @@ RLAPI void ImageColorGrayscale(Image *image);
|
|||||||
RLAPI void ImageColorContrast(Image *image, float contrast); // Modify image color: contrast (-100 to 100)
|
RLAPI void ImageColorContrast(Image *image, float contrast); // Modify image color: contrast (-100 to 100)
|
||||||
RLAPI void ImageColorBrightness(Image *image, int brightness); // Modify image color: brightness (-255 to 255)
|
RLAPI void ImageColorBrightness(Image *image, int brightness); // Modify image color: brightness (-255 to 255)
|
||||||
RLAPI void GenTextureMipmaps(Texture2D texture); // Generate GPU mipmaps for a texture
|
RLAPI void GenTextureMipmaps(Texture2D texture); // Generate GPU mipmaps for a texture
|
||||||
RLAPI void UpdateTexture(Texture2D texture, void *pixels); // Update GPU texture with new data
|
RLAPI void SetTextureFilter(Texture2D texture, int filterMode); // Set texture scaling filter mode
|
||||||
|
RLAPI void SetTextureWrap(Texture2D texture, int wrapMode); // Set texture wrapping mode
|
||||||
|
|
||||||
RLAPI void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
|
RLAPI void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
|
||||||
RLAPI void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2
|
RLAPI void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2
|
||||||
@ -797,6 +821,7 @@ RLAPI void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle dest
|
|||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
RLAPI SpriteFont GetDefaultFont(void); // Get the default SpriteFont
|
RLAPI SpriteFont GetDefaultFont(void); // Get the default SpriteFont
|
||||||
RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory
|
RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory
|
||||||
|
RLAPI SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int numChars, int *fontChars); // Load a SpriteFont from TTF font with parameters
|
||||||
RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory
|
RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory
|
||||||
|
|
||||||
RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
|
RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
|
||||||
@ -896,7 +921,8 @@ RLAPI void DestroyLight(Light light); // Des
|
|||||||
RLAPI void InitVrDevice(int vdDevice); // Init VR device
|
RLAPI void InitVrDevice(int vdDevice); // Init VR device
|
||||||
RLAPI void CloseVrDevice(void); // Close VR device
|
RLAPI void CloseVrDevice(void); // Close VR device
|
||||||
RLAPI bool IsVrDeviceReady(void); // Detect if VR device (or simulator) is ready
|
RLAPI bool IsVrDeviceReady(void); // Detect if VR device (or simulator) is ready
|
||||||
RLAPI void UpdateVrTracking(void); // Update VR tracking (position and orientation)
|
RLAPI bool IsVrSimulator(void); // Detect if VR simulator is running
|
||||||
|
RLAPI void UpdateVrTracking(Camera *camera); // Update VR tracking (position and orientation) and camera
|
||||||
RLAPI void ToggleVrMode(void); // Enable/Disable VR experience (device or simulator)
|
RLAPI void ToggleVrMode(void); // Enable/Disable VR experience (device or simulator)
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
@ -912,7 +938,7 @@ RLAPI Sound LoadSound(const char *fileName); // Load so
|
|||||||
RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data
|
RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data
|
||||||
RLAPI Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource)
|
RLAPI Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource)
|
||||||
RLAPI void UpdateSound(Sound sound, void *data, int numSamples); // Update sound buffer with new data
|
RLAPI void UpdateSound(Sound sound, void *data, int numSamples); // Update sound buffer with new data
|
||||||
RLAPI void UnloadWave(Wave wave);
|
RLAPI void UnloadWave(Wave wave); // Unload wave data
|
||||||
RLAPI void UnloadSound(Sound sound); // Unload sound
|
RLAPI void UnloadSound(Sound sound); // Unload sound
|
||||||
RLAPI void PlaySound(Sound sound); // Play a sound
|
RLAPI void PlaySound(Sound sound); // Play a sound
|
||||||
RLAPI void PauseSound(Sound sound); // Pause a sound
|
RLAPI void PauseSound(Sound sound); // Pause a sound
|
||||||
|
115
src/rlgl.c
115
src/rlgl.c
@ -35,7 +35,7 @@
|
|||||||
#include <math.h> // Required for: atan2()
|
#include <math.h> // Required for: atan2()
|
||||||
|
|
||||||
#ifndef RLGL_STANDALONE
|
#ifndef RLGL_STANDALONE
|
||||||
#include "raymath.h" // Required for Vector3 and Matrix functions
|
#include "raymath.h" // Required for: Vector3 and Matrix functions
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(GRAPHICS_API_OPENGL_11)
|
#if defined(GRAPHICS_API_OPENGL_11)
|
||||||
@ -140,6 +140,14 @@
|
|||||||
#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93b7
|
#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93b7
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT
|
||||||
|
#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT
|
||||||
|
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(GRAPHICS_API_OPENGL_11)
|
#if defined(GRAPHICS_API_OPENGL_11)
|
||||||
#define GL_UNSIGNED_SHORT_5_6_5 0x8363
|
#define GL_UNSIGNED_SHORT_5_6_5 0x8363
|
||||||
#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
|
#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
|
||||||
@ -283,14 +291,21 @@ static Shader standardShader; // Shader with support for lighting
|
|||||||
static Shader currentShader; // Shader to be used on rendering (by default, defaultShader)
|
static Shader currentShader; // Shader to be used on rendering (by default, defaultShader)
|
||||||
static bool standardShaderLoaded = false; // Flag to track if standard shader has been loaded
|
static bool standardShaderLoaded = false; // Flag to track if standard shader has been loaded
|
||||||
|
|
||||||
// Flags for supported extensions
|
// Extension supported flag: VAO
|
||||||
static bool vaoSupported = false; // VAO support (OpenGL ES2 could not support VAO extension)
|
static bool vaoSupported = false; // VAO support (OpenGL ES2 could not support VAO extension)
|
||||||
|
|
||||||
// Compressed textures support flags
|
// Extension supported flag: Compressed textures
|
||||||
static bool texCompETC1Supported = false; // ETC1 texture compression support
|
static bool texCompETC1Supported = false; // ETC1 texture compression support
|
||||||
static bool texCompETC2Supported = false; // ETC2/EAC texture compression support
|
static bool texCompETC2Supported = false; // ETC2/EAC texture compression support
|
||||||
static bool texCompPVRTSupported = false; // PVR texture compression support
|
static bool texCompPVRTSupported = false; // PVR texture compression support
|
||||||
static bool texCompASTCSupported = false; // ASTC texture compression support
|
static bool texCompASTCSupported = false; // ASTC texture compression support
|
||||||
|
|
||||||
|
// Extension supported flag: Anisotropic filtering
|
||||||
|
static bool texAnisotropicFilterSupported = false; // Anisotropic texture filtering support
|
||||||
|
static float maxAnisotropicLevel = 0.0f; // Maximum anisotropy level supported (minimum is 2.0f)
|
||||||
|
|
||||||
|
// Extension supported flag: Clamp mirror wrap mode
|
||||||
|
static bool texClampMirrorSupported = false; // Clamp mirror wrap mode supported
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(RLGL_OCULUS_SUPPORT)
|
#if defined(RLGL_OCULUS_SUPPORT)
|
||||||
@ -372,11 +387,11 @@ static char *ReadTextFile(const char *fileName); // Read chars array from
|
|||||||
|
|
||||||
#if defined(RLGL_OCULUS_SUPPORT)
|
#if defined(RLGL_OCULUS_SUPPORT)
|
||||||
#if !defined(RLGL_STANDALONE)
|
#if !defined(RLGL_STANDALONE)
|
||||||
static bool InitOculusDevice(void); // Initialize Oculus device (returns true if success)
|
static bool InitOculusDevice(void); // Initialize Oculus device (returns true if success)
|
||||||
static void CloseOculusDevice(void); // Close Oculus device
|
static void CloseOculusDevice(void); // Close Oculus device
|
||||||
static void UpdateOculusTracking(void); // Update Oculus head position-orientation tracking
|
static void UpdateOculusTracking(Camera *camera); // Update Oculus head position-orientation tracking
|
||||||
static void BeginOculusDrawing(void); // Setup Oculus buffers for drawing
|
static void BeginOculusDrawing(void); // Setup Oculus buffers for drawing
|
||||||
static void EndOculusDrawing(void); // Finish Oculus drawing and blit framebuffer to mirror
|
static void EndOculusDrawing(void); // Finish Oculus drawing and blit framebuffer to mirror
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height); // Load Oculus required buffers
|
static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height); // Load Oculus required buffers
|
||||||
@ -871,6 +886,37 @@ void rlDisableTexture(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set texture parameters (wrap mode/filter mode)
|
||||||
|
void rlTextureParameters(unsigned int id, int param, int value)
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, id);
|
||||||
|
|
||||||
|
switch (param)
|
||||||
|
{
|
||||||
|
case RL_TEXTURE_WRAP_S:
|
||||||
|
case RL_TEXTURE_WRAP_T:
|
||||||
|
{
|
||||||
|
if ((value == RL_WRAP_CLAMP_MIRROR) && !texClampMirrorSupported) TraceLog(WARNING, "Clamp mirror wrap mode not supported");
|
||||||
|
else glTexParameteri(GL_TEXTURE_2D, param, value);
|
||||||
|
} break;
|
||||||
|
case RL_TEXTURE_MAG_FILTER:
|
||||||
|
case RL_TEXTURE_MIN_FILTER: glTexParameteri(GL_TEXTURE_2D, param, value); break;
|
||||||
|
case RL_TEXTURE_ANISOTROPIC_FILTER:
|
||||||
|
{
|
||||||
|
if (value <= maxAnisotropicLevel) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, value);
|
||||||
|
else if (maxAnisotropicLevel > 0.0f)
|
||||||
|
{
|
||||||
|
TraceLog(WARNING, "[TEX ID %i] Maximum anisotropic filter level supported is %iX", id, maxAnisotropicLevel);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, value);
|
||||||
|
}
|
||||||
|
else TraceLog(WARNING, "Anisotropic filtering not supported");
|
||||||
|
} break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
|
||||||
// Enable rendering to texture (fbo)
|
// Enable rendering to texture (fbo)
|
||||||
void rlEnableRenderTexture(unsigned int id)
|
void rlEnableRenderTexture(unsigned int id)
|
||||||
{
|
{
|
||||||
@ -1124,7 +1170,7 @@ void rlglInit(int width, int height)
|
|||||||
// Check NPOT textures support
|
// Check NPOT textures support
|
||||||
// NOTE: Only check on OpenGL ES, OpenGL 3.3 has NPOT textures full support as core feature
|
// NOTE: Only check on OpenGL ES, OpenGL 3.3 has NPOT textures full support as core feature
|
||||||
if (strcmp(extList[i], (const char *)"GL_OES_texture_npot") == 0) npotSupported = true;
|
if (strcmp(extList[i], (const char *)"GL_OES_texture_npot") == 0) npotSupported = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// DDS texture compression support
|
// DDS texture compression support
|
||||||
if ((strcmp(extList[i], (const char *)"GL_EXT_texture_compression_s3tc") == 0) ||
|
if ((strcmp(extList[i], (const char *)"GL_EXT_texture_compression_s3tc") == 0) ||
|
||||||
@ -1143,6 +1189,16 @@ void rlglInit(int width, int height)
|
|||||||
|
|
||||||
// ASTC texture compression support
|
// ASTC texture compression support
|
||||||
if (strcmp(extList[i], (const char *)"GL_KHR_texture_compression_astc_hdr") == 0) texCompASTCSupported = true;
|
if (strcmp(extList[i], (const char *)"GL_KHR_texture_compression_astc_hdr") == 0) texCompASTCSupported = true;
|
||||||
|
|
||||||
|
// Anisotropic texture filter support
|
||||||
|
if (strcmp(extList[i], (const char *)"GL_EXT_texture_filter_anisotropic") == 0)
|
||||||
|
{
|
||||||
|
texAnisotropicFilterSupported = true;
|
||||||
|
glGetFloatv(0x84FF, &maxAnisotropicLevel); // GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clamp mirror wrap mode supported
|
||||||
|
if (strcmp(extList[i], (const char *)"GL_EXT_texture_mirror_clamp") == 0) texClampMirrorSupported = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@ -1162,6 +1218,9 @@ void rlglInit(int width, int height)
|
|||||||
if (texCompETC2Supported) TraceLog(INFO, "[EXTENSION] ETC2/EAC compressed textures supported");
|
if (texCompETC2Supported) TraceLog(INFO, "[EXTENSION] ETC2/EAC compressed textures supported");
|
||||||
if (texCompPVRTSupported) TraceLog(INFO, "[EXTENSION] PVRT compressed textures supported");
|
if (texCompPVRTSupported) TraceLog(INFO, "[EXTENSION] PVRT compressed textures supported");
|
||||||
if (texCompASTCSupported) TraceLog(INFO, "[EXTENSION] ASTC compressed textures supported");
|
if (texCompASTCSupported) TraceLog(INFO, "[EXTENSION] ASTC compressed textures supported");
|
||||||
|
|
||||||
|
if (texAnisotropicFilterSupported) TraceLog(INFO, "[EXTENSION] Anisotropic textures filtering supported (max: %.0fX)", maxAnisotropicLevel);
|
||||||
|
if (texClampMirrorSupported) TraceLog(INFO, "[EXTENSION] Clamp mirror wrap texture mode supported");
|
||||||
|
|
||||||
// Initialize buffers, default shaders and default textures
|
// Initialize buffers, default shaders and default textures
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
@ -1522,7 +1581,7 @@ RenderTexture2D rlglLoadRenderTexture(int width, int height)
|
|||||||
target.texture.id = 0;
|
target.texture.id = 0;
|
||||||
target.texture.width = width;
|
target.texture.width = width;
|
||||||
target.texture.height = height;
|
target.texture.height = height;
|
||||||
target.texture.format = UNCOMPRESSED_R8G8B8;
|
target.texture.format = UNCOMPRESSED_R8G8B8A8;
|
||||||
target.texture.mipmaps = 1;
|
target.texture.mipmaps = 1;
|
||||||
|
|
||||||
target.depth.id = 0;
|
target.depth.id = 0;
|
||||||
@ -1539,7 +1598,7 @@ RenderTexture2D rlglLoadRenderTexture(int width, int height)
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
#if defined(GRAPHICS_API_OPENGL_33)
|
#if defined(GRAPHICS_API_OPENGL_33)
|
||||||
@ -1687,6 +1746,7 @@ void rlglGenerateMipmaps(Texture2D texture)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
|
//glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE); // Hint for mipmaps generation algorythm: GL_FASTEST, GL_NICEST, GL_DONT_CARE
|
||||||
glGenerateMipmap(GL_TEXTURE_2D); // Generate mipmaps automatically
|
glGenerateMipmap(GL_TEXTURE_2D); // Generate mipmaps automatically
|
||||||
TraceLog(INFO, "[TEX ID %i] Mipmaps generated automatically", texture.id);
|
TraceLog(INFO, "[TEX ID %i] Mipmaps generated automatically", texture.id);
|
||||||
|
|
||||||
@ -2653,7 +2713,7 @@ void InitVrDevice(int vrDevice)
|
|||||||
hmd.hResolution = 2160; // HMD horizontal resolution in pixels
|
hmd.hResolution = 2160; // HMD horizontal resolution in pixels
|
||||||
hmd.vResolution = 1200; // HMD vertical resolution in pixels
|
hmd.vResolution = 1200; // HMD vertical resolution in pixels
|
||||||
hmd.hScreenSize = 0.133793f; // HMD horizontal size in meters
|
hmd.hScreenSize = 0.133793f; // HMD horizontal size in meters
|
||||||
hmd.vScreenSize = 0.0669; // HMD vertical size in meters
|
hmd.vScreenSize = 0.0669f; // HMD vertical size in meters
|
||||||
hmd.vScreenCenter = 0.04678f; // HMD screen center in meters
|
hmd.vScreenCenter = 0.04678f; // HMD screen center in meters
|
||||||
hmd.eyeToScreenDistance = 0.041f; // HMD distance between eye and display in meters
|
hmd.eyeToScreenDistance = 0.041f; // HMD distance between eye and display in meters
|
||||||
hmd.lensSeparationDistance = 0.07f; // HMD lens separation distance in meters
|
hmd.lensSeparationDistance = 0.07f; // HMD lens separation distance in meters
|
||||||
@ -2710,6 +2770,12 @@ bool IsVrDeviceReady(void)
|
|||||||
return (vrDeviceReady || vrSimulator) && vrEnabled;
|
return (vrDeviceReady || vrSimulator) && vrEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Detect if VR simulator is running
|
||||||
|
bool IsVrSimulator(void)
|
||||||
|
{
|
||||||
|
return vrSimulator;
|
||||||
|
}
|
||||||
|
|
||||||
// Enable/Disable VR experience (device or simulator)
|
// Enable/Disable VR experience (device or simulator)
|
||||||
void ToggleVrMode(void)
|
void ToggleVrMode(void)
|
||||||
{
|
{
|
||||||
@ -2728,16 +2794,13 @@ void ToggleVrMode(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update VR tracking (position and orientation)
|
// Update VR tracking (position and orientation) and camera
|
||||||
void UpdateVrTracking(void)
|
// NOTE: Camera (position, target, up) gets update with head tracking information
|
||||||
|
void UpdateVrTracking(Camera *camera)
|
||||||
{
|
{
|
||||||
#if defined(RLGL_OCULUS_SUPPORT)
|
#if defined(RLGL_OCULUS_SUPPORT)
|
||||||
if (vrDeviceReady) UpdateOculusTracking();
|
if (vrDeviceReady) UpdateOculusTracking(camera);
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
{
|
|
||||||
// TODO: Use alternative inputs (mouse, keyboard) to simulate tracking data (eyes position/orientation)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Begin Oculus drawing configuration
|
// Begin Oculus drawing configuration
|
||||||
@ -3779,8 +3842,8 @@ static void SetStereoConfig(VrDeviceInfo hmd)
|
|||||||
|
|
||||||
// Compute lens parameters
|
// Compute lens parameters
|
||||||
float lensShift = (hmd.hScreenSize*0.25f - hmd.lensSeparationDistance*0.5f)/hmd.hScreenSize;
|
float lensShift = (hmd.hScreenSize*0.25f - hmd.lensSeparationDistance*0.5f)/hmd.hScreenSize;
|
||||||
float leftLensCenter[2] = { 0.25 + lensShift, 0.5f };
|
float leftLensCenter[2] = { 0.25f + lensShift, 0.5f };
|
||||||
float rightLensCenter[2] = { 0.75 - lensShift, 0.5f };
|
float rightLensCenter[2] = { 0.75f - lensShift, 0.5f };
|
||||||
float leftScreenCenter[2] = { 0.25f, 0.5f };
|
float leftScreenCenter[2] = { 0.25f, 0.5f };
|
||||||
float rightScreenCenter[2] = { 0.75f, 0.5f };
|
float rightScreenCenter[2] = { 0.75f, 0.5f };
|
||||||
|
|
||||||
@ -3797,8 +3860,8 @@ static void SetStereoConfig(VrDeviceInfo hmd)
|
|||||||
|
|
||||||
float normScreenWidth = 0.5f;
|
float normScreenWidth = 0.5f;
|
||||||
float normScreenHeight = 1.0f;
|
float normScreenHeight = 1.0f;
|
||||||
float scaleIn[2] = { 2/normScreenWidth, 2/normScreenHeight/aspect };
|
float scaleIn[2] = { 2.0f/normScreenWidth, 2.0f/normScreenHeight/aspect };
|
||||||
float scale[2] = { normScreenWidth*0.5/distortionScale, normScreenHeight*0.5*aspect/distortionScale };
|
float scale[2] = { normScreenWidth*0.5f/distortionScale, normScreenHeight*0.5f*aspect/distortionScale };
|
||||||
|
|
||||||
TraceLog(DEBUG, "VR: Distortion Shader: LeftLensCenter = { %f, %f }", leftLensCenter[0], leftLensCenter[1]);
|
TraceLog(DEBUG, "VR: Distortion Shader: LeftLensCenter = { %f, %f }", leftLensCenter[0], leftLensCenter[1]);
|
||||||
TraceLog(DEBUG, "VR: Distortion Shader: RightLensCenter = { %f, %f }", rightLensCenter[0], rightLensCenter[1]);
|
TraceLog(DEBUG, "VR: Distortion Shader: RightLensCenter = { %f, %f }", rightLensCenter[0], rightLensCenter[1]);
|
||||||
@ -4076,7 +4139,7 @@ OCULUSAPI void CloseOculusDevice(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update Oculus head position-orientation tracking
|
// Update Oculus head position-orientation tracking
|
||||||
OCULUSAPI void UpdateOculusTracking(void)
|
OCULUSAPI void UpdateOculusTracking(Camera *camera)
|
||||||
{
|
{
|
||||||
frameIndex++;
|
frameIndex++;
|
||||||
|
|
||||||
@ -4086,6 +4149,10 @@ OCULUSAPI void UpdateOculusTracking(void)
|
|||||||
layer.eyeLayer.RenderPose[0] = eyePoses[0];
|
layer.eyeLayer.RenderPose[0] = eyePoses[0];
|
||||||
layer.eyeLayer.RenderPose[1] = eyePoses[1];
|
layer.eyeLayer.RenderPose[1] = eyePoses[1];
|
||||||
|
|
||||||
|
// TODO: Update external camera with eyePoses data (position, orientation)
|
||||||
|
// NOTE: We can simplify to simple camera if we consider IPD and HMD device configuration again later
|
||||||
|
// it will be useful for the user to draw, lets say, billboards oriented to camera
|
||||||
|
|
||||||
// Get session status information
|
// Get session status information
|
||||||
ovrSessionStatus sessionStatus;
|
ovrSessionStatus sessionStatus;
|
||||||
ovr_GetSessionStatus(session, &sessionStatus);
|
ovr_GetSessionStatus(session, &sessionStatus);
|
||||||
|
42
src/rlgl.h
42
src/rlgl.h
@ -90,15 +90,33 @@
|
|||||||
#define MAX_QUADS_BATCH 1024 // Be careful with text, every letter maps a quad
|
#define MAX_QUADS_BATCH 1024 // Be careful with text, every letter maps a quad
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Texture parameters (equivalent to OpenGL defines)
|
||||||
|
#define RL_TEXTURE_WRAP_S 0x2802 // GL_TEXTURE_WRAP_S
|
||||||
|
#define RL_TEXTURE_WRAP_T 0x2803 // GL_TEXTURE_WRAP_T
|
||||||
|
#define RL_TEXTURE_MAG_FILTER 0x2800 // GL_TEXTURE_MAG_FILTER
|
||||||
|
#define RL_TEXTURE_MIN_FILTER 0x2801 // GL_TEXTURE_MIN_FILTER
|
||||||
|
#define RL_TEXTURE_ANISOTROPIC_FILTER 0x3000 // Anisotropic filter (custom identifier)
|
||||||
|
|
||||||
|
#define RL_FILTER_NEAREST 0x2600 // GL_NEAREST
|
||||||
|
#define RL_FILTER_LINEAR 0x2601 // GL_LINEAR
|
||||||
|
#define RL_FILTER_MIP_NEAREST 0x2700 // GL_NEAREST_MIPMAP_NEAREST
|
||||||
|
#define RL_FILTER_NEAREST_MIP_LINEAR 0x2702 // GL_NEAREST_MIPMAP_LINEAR
|
||||||
|
#define RL_FILTER_LINEAR_MIP_NEAREST 0x2701 // GL_LINEAR_MIPMAP_NEAREST
|
||||||
|
#define RL_FILTER_MIP_LINEAR 0x2703 // GL_LINEAR_MIPMAP_LINEAR
|
||||||
|
|
||||||
|
#define RL_WRAP_REPEAT 0x2901 // GL_REPEAT
|
||||||
|
#define RL_WRAP_CLAMP 0x812F // GL_CLAMP_TO_EDGE
|
||||||
|
#define RL_WRAP_CLAMP_MIRROR 0x8742 // GL_MIRROR_CLAMP_EXT
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Types and Structures Definition
|
// Types and Structures Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
typedef enum { OPENGL_11 = 1, OPENGL_21, OPENGL_33, OPENGL_ES_20 } GlVersion;
|
||||||
|
|
||||||
typedef enum { RL_PROJECTION, RL_MODELVIEW, RL_TEXTURE } MatrixMode;
|
typedef enum { RL_PROJECTION, RL_MODELVIEW, RL_TEXTURE } MatrixMode;
|
||||||
|
|
||||||
typedef enum { RL_LINES, RL_TRIANGLES, RL_QUADS } DrawMode;
|
typedef enum { RL_LINES, RL_TRIANGLES, RL_QUADS } DrawMode;
|
||||||
|
|
||||||
typedef enum { OPENGL_11 = 1, OPENGL_21, OPENGL_33, OPENGL_ES_20 } GlVersion;
|
|
||||||
|
|
||||||
#if defined(RLGL_STANDALONE)
|
#if defined(RLGL_STANDALONE)
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
// Boolean type
|
// Boolean type
|
||||||
@ -236,6 +254,21 @@ typedef enum { OPENGL_11 = 1, OPENGL_21, OPENGL_33, OPENGL_ES_20 } GlVersion;
|
|||||||
|
|
||||||
// Light types
|
// Light types
|
||||||
typedef enum { LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT } LightType;
|
typedef enum { LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT } LightType;
|
||||||
|
|
||||||
|
// Texture parameters: filter mode
|
||||||
|
// NOTE 1: Filtering considers mipmaps if available in the texture
|
||||||
|
// NOTE 2: Filter is accordingly set for minification and magnification
|
||||||
|
typedef enum {
|
||||||
|
FILTER_POINT = 0, // No filter, just pixel aproximation
|
||||||
|
FILTER_BILINEAR, // Linear filtering
|
||||||
|
FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps)
|
||||||
|
FILTER_ANISOTROPIC_4X, // Anisotropic filtering 4x
|
||||||
|
FILTER_ANISOTROPIC_8X, // Anisotropic filtering 8x
|
||||||
|
FILTER_ANISOTROPIC_16X, // Anisotropic filtering 16x
|
||||||
|
} TextureFilterMode;
|
||||||
|
|
||||||
|
// Texture parameters: wrap mode
|
||||||
|
typedef enum { WRAP_REPEAT = 0, WRAP_CLAMP, WRAP_MIRROR } TextureWrapMode;
|
||||||
|
|
||||||
// Color blending modes (pre-defined)
|
// Color blending modes (pre-defined)
|
||||||
typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode;
|
typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode;
|
||||||
@ -296,6 +329,7 @@ void rlColor4f(float x, float y, float z, float w); // Define one vertex (color)
|
|||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
void rlEnableTexture(unsigned int id); // Enable texture usage
|
void rlEnableTexture(unsigned int id); // Enable texture usage
|
||||||
void rlDisableTexture(void); // Disable texture usage
|
void rlDisableTexture(void); // Disable texture usage
|
||||||
|
void rlTextureParameters(unsigned int id, int param, int value); // Set texture parameters (filter, wrap)
|
||||||
void rlEnableRenderTexture(unsigned int id); // Enable render texture (fbo)
|
void rlEnableRenderTexture(unsigned int id); // Enable render texture (fbo)
|
||||||
void rlDisableRenderTexture(void); // Disable render texture (fbo), return to default framebuffer
|
void rlDisableRenderTexture(void); // Disable render texture (fbo), return to default framebuffer
|
||||||
void rlEnableDepthTest(void); // Enable depth test
|
void rlEnableDepthTest(void); // Enable depth test
|
||||||
@ -375,13 +409,13 @@ float *MatrixToFloat(Matrix mat);
|
|||||||
void InitVrDevice(int vrDevice); // Init VR device
|
void InitVrDevice(int vrDevice); // Init VR device
|
||||||
void CloseVrDevice(void); // Close VR device
|
void CloseVrDevice(void); // Close VR device
|
||||||
bool IsVrDeviceReady(void); // Detect if VR device (or simulator) is ready
|
bool IsVrDeviceReady(void); // Detect if VR device (or simulator) is ready
|
||||||
void UpdateVrTracking(void); // Update VR tracking (position and orientation)
|
void UpdateVrTracking(Camera *camera); // Update VR tracking (position and orientation) and camera
|
||||||
void ToggleVrMode(void); // Enable/Disable VR experience (device or simulator)
|
void ToggleVrMode(void); // Enable/Disable VR experience (device or simulator)
|
||||||
|
|
||||||
// Oculus Rift API for direct access the device (no simulator)
|
// Oculus Rift API for direct access the device (no simulator)
|
||||||
bool InitOculusDevice(void); // Initialize Oculus device (returns true if success)
|
bool InitOculusDevice(void); // Initialize Oculus device (returns true if success)
|
||||||
void CloseOculusDevice(void); // Close Oculus device
|
void CloseOculusDevice(void); // Close Oculus device
|
||||||
void UpdateOculusTracking(void); // Update Oculus head position-orientation tracking
|
void UpdateOculusTracking(Camera *camera); // Update Oculus head position-orientation tracking (and camera)
|
||||||
void BeginOculusDrawing(void); // Setup Oculus buffers for drawing
|
void BeginOculusDrawing(void); // Setup Oculus buffers for drawing
|
||||||
void EndOculusDrawing(void); // Finish Oculus drawing and blit framebuffer to mirror
|
void EndOculusDrawing(void); // Finish Oculus drawing and blit framebuffer to mirror
|
||||||
#endif
|
#endif
|
||||||
|
83
src/rlua.h
83
src/rlua.h
@ -2824,6 +2824,28 @@ int lua_IsAudioDeviceReady(lua_State* L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lua_LoadWave(lua_State* L)
|
||||||
|
{
|
||||||
|
const char * arg1 = LuaGetArgument_string(L, 1);
|
||||||
|
Wave result = LoadWave((char *)arg1);
|
||||||
|
LuaPush_Wave(L, result);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_LoadWaveEx(lua_State* L)
|
||||||
|
{
|
||||||
|
// TODO: Wave LoadWaveEx(float *data, int sampleCount, int sampleRate, int sampleSize, int channels);
|
||||||
|
|
||||||
|
int arg1 = 0;
|
||||||
|
int arg2 = LuaGetArgument_int(L, 2);
|
||||||
|
int arg3 = LuaGetArgument_int(L, 3);
|
||||||
|
int arg4 = LuaGetArgument_int(L, 4);
|
||||||
|
int arg5 = LuaGetArgument_int(L, 5);
|
||||||
|
Wave result = LoadWaveEx(arg1, arg2, arg3, arg4, arg5);
|
||||||
|
LuaPush_Wave(L, result);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int lua_LoadSound(lua_State* L)
|
int lua_LoadSound(lua_State* L)
|
||||||
{
|
{
|
||||||
const char * arg1 = LuaGetArgument_string(L, 1);
|
const char * arg1 = LuaGetArgument_string(L, 1);
|
||||||
@ -2849,6 +2871,22 @@ int lua_LoadSoundFromRES(lua_State* L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lua_UpdateSound(lua_State* L)
|
||||||
|
{
|
||||||
|
Sound arg1 = LuaGetArgument_Sound(L, 1);
|
||||||
|
const char * arg2 = LuaGetArgument_string(L, 2);
|
||||||
|
int * arg3 = LuaGetArgument_int(L, 3);
|
||||||
|
UpdateSound(arg1, arg2, arg3);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_UnloadWave(lua_State* L)
|
||||||
|
{
|
||||||
|
Wave arg1 = LuaGetArgument_Wave(L, 1);
|
||||||
|
UnloadWave(arg1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int lua_UnloadSound(lua_State* L)
|
int lua_UnloadSound(lua_State* L)
|
||||||
{
|
{
|
||||||
Sound arg1 = LuaGetArgument_Sound(L, 1);
|
Sound arg1 = LuaGetArgument_Sound(L, 1);
|
||||||
@ -2908,6 +2946,43 @@ int lua_SetSoundPitch(lua_State* L)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lua_WaveFormat(lua_State* L)
|
||||||
|
{
|
||||||
|
Wave arg1 = LuaGetArgument_Wave(L, 1);
|
||||||
|
int arg2 = LuaGetArgument_int(L, 2);
|
||||||
|
int arg3 = LuaGetArgument_int(L, 3);
|
||||||
|
int arg4 = LuaGetArgument_int(L, 4);
|
||||||
|
WaveFormat(arg1, arg2, arg3, arg4);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_LoadMusicStream(lua_State* L)
|
||||||
|
{
|
||||||
|
Wave arg1 = LuaGetArgument_Wave(L, 1);
|
||||||
|
Wave result = WaveCopy(arg1);
|
||||||
|
LuaPush_Wave(L, result);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_WaveCrop(lua_State* L)
|
||||||
|
{
|
||||||
|
Wave arg1 = LuaGetArgument_Wave(L, 1);
|
||||||
|
int arg2 = LuaGetArgument_int(L, 2);
|
||||||
|
int arg3 = LuaGetArgument_int(L, 3);
|
||||||
|
WaveCrop(arg1, arg2, arg3);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_GetWaveData(lua_State* L)
|
||||||
|
{
|
||||||
|
// TODO: float *GetWaveData(Wave wave);
|
||||||
|
|
||||||
|
Wave arg1 = LuaGetArgument_Wave(L, 1);
|
||||||
|
float result = GetWaveData(arg1);
|
||||||
|
LuaPush_float(L, result);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int lua_LoadMusicStream(lua_State* L)
|
int lua_LoadMusicStream(lua_State* L)
|
||||||
{
|
{
|
||||||
const char * arg1 = LuaGetArgument_string(L, 1);
|
const char * arg1 = LuaGetArgument_string(L, 1);
|
||||||
@ -3799,9 +3874,13 @@ static luaL_Reg raylib_functions[] = {
|
|||||||
REG(InitAudioDevice)
|
REG(InitAudioDevice)
|
||||||
REG(CloseAudioDevice)
|
REG(CloseAudioDevice)
|
||||||
REG(IsAudioDeviceReady)
|
REG(IsAudioDeviceReady)
|
||||||
|
REG(LoadWave)
|
||||||
|
REG(LoadWaveEx)
|
||||||
REG(LoadSound)
|
REG(LoadSound)
|
||||||
REG(LoadSoundFromWave)
|
REG(LoadSoundFromWave)
|
||||||
REG(LoadSoundFromRES)
|
REG(LoadSoundFromRES)
|
||||||
|
REG(UpdateSound)
|
||||||
|
REG(UnloadWave)
|
||||||
REG(UnloadSound)
|
REG(UnloadSound)
|
||||||
REG(PlaySound)
|
REG(PlaySound)
|
||||||
REG(PauseSound)
|
REG(PauseSound)
|
||||||
@ -3810,6 +3889,10 @@ static luaL_Reg raylib_functions[] = {
|
|||||||
REG(IsSoundPlaying)
|
REG(IsSoundPlaying)
|
||||||
REG(SetSoundVolume)
|
REG(SetSoundVolume)
|
||||||
REG(SetSoundPitch)
|
REG(SetSoundPitch)
|
||||||
|
REG(WaveFormat)
|
||||||
|
REG(WaveCopy)
|
||||||
|
REG(WaveCrop)
|
||||||
|
REG(GetWaveData)
|
||||||
|
|
||||||
REG(LoadMusicStream)
|
REG(LoadMusicStream)
|
||||||
REG(UnloadMusicStream)
|
REG(UnloadMusicStream)
|
||||||
|
@ -90,7 +90,7 @@ static const char fStandardShaderStr[] =
|
|||||||
" if (diff > 0.0)\n"
|
" if (diff > 0.0)\n"
|
||||||
" {\n"
|
" {\n"
|
||||||
" vec3 h = normalize(-l.direction + v);\n"
|
" vec3 h = normalize(-l.direction + v);\n"
|
||||||
" spec = pow(dot(n, h), 3.0 + glossiness)*s;\n"
|
" spec = pow(abs(dot(n, h)), 3.0 + glossiness)*s;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
" return (diff*l.diffuse.rgb + spec*colSpecular.rgb);\n"
|
" return (diff*l.diffuse.rgb + spec*colSpecular.rgb);\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
@ -103,7 +103,7 @@ static const char fStandardShaderStr[] =
|
|||||||
" if (diff > 0.0)\n"
|
" if (diff > 0.0)\n"
|
||||||
" {\n"
|
" {\n"
|
||||||
" vec3 h = normalize(lightDir + v);\n"
|
" vec3 h = normalize(lightDir + v);\n"
|
||||||
" spec = pow(dot(n, h), 3.0 + glossiness)*s;\n"
|
" spec = pow(abs(dot(n, h)), 3.0 + glossiness)*s;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
" return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb);\n"
|
" return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb);\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
@ -124,7 +124,7 @@ static const char fStandardShaderStr[] =
|
|||||||
" if (diffAttenuation > 0.0)\n"
|
" if (diffAttenuation > 0.0)\n"
|
||||||
" {\n"
|
" {\n"
|
||||||
" vec3 h = normalize(lightDir + v);\n"
|
" vec3 h = normalize(lightDir + v);\n"
|
||||||
" spec = pow(dot(n, h), 3.0 + glossiness)*s;\n"
|
" spec = pow(abs(dot(n, h)), 3.0 + glossiness)*s;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
" return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb));\n"
|
" return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb));\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
@ -152,9 +152,9 @@ static const char fStandardShaderStr[] =
|
|||||||
" }\n"
|
" }\n"
|
||||||
" float spec = 1.0;\n"
|
" float spec = 1.0;\n"
|
||||||
#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
|
#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
|
||||||
" if (useSpecular == 1) spec *= normalize(texture2D(texture2, fragTexCoord).r);\n"
|
" if (useSpecular == 1) spec = texture2D(texture2, fragTexCoord).r;\n"
|
||||||
#elif defined(GRAPHICS_API_OPENGL_33)
|
#elif defined(GRAPHICS_API_OPENGL_33)
|
||||||
" if (useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r);\n"
|
" if (useSpecular == 1) spec = texture(texture2, fragTexCoord).r;\n"
|
||||||
#endif
|
#endif
|
||||||
" for (int i = 0; i < maxLights; i++)\n"
|
" for (int i = 0; i < maxLights; i++)\n"
|
||||||
" {\n"
|
" {\n"
|
||||||
|
43
src/shapes.c
43
src/shapes.c
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Basic functions to draw 2d Shapes and check collisions
|
* Basic functions to draw 2d Shapes and check collisions
|
||||||
*
|
*
|
||||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||||
* will the authors be held liable for any damages arising from the use of this software.
|
* will the authors be held liable for any damages arising from the use of this software.
|
||||||
@ -25,9 +25,8 @@
|
|||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
|
||||||
#include <stdlib.h> // Required for abs() function
|
#include <stdlib.h> // Required for: abs()
|
||||||
#include <math.h> // Math related functions, sin() and cos() used on DrawCircle*
|
#include <math.h> // Required for: sinf(), cosf(), sqrtf()
|
||||||
// sqrt() and pow() and abs() used on CheckCollision*
|
|
||||||
|
|
||||||
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
|
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
|
||||||
|
|
||||||
@ -71,7 +70,7 @@ void DrawPixelV(Vector2 position, Color color)
|
|||||||
rlBegin(RL_LINES);
|
rlBegin(RL_LINES);
|
||||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
rlVertex2f(position.x, position.y);
|
rlVertex2f(position.x, position.y);
|
||||||
rlVertex2i(position.x + 1, position.y + 1);
|
rlVertex2f(position.x + 1.0f, position.y + 1.0f);
|
||||||
rlEnd();
|
rlEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +97,7 @@ void DrawLineV(Vector2 startPos, Vector2 endPos, Color color)
|
|||||||
// Draw a color-filled circle
|
// Draw a color-filled circle
|
||||||
void DrawCircle(int centerX, int centerY, float radius, Color color)
|
void DrawCircle(int centerX, int centerY, float radius, Color color)
|
||||||
{
|
{
|
||||||
DrawCircleV((Vector2){ centerX, centerY }, radius, color);
|
DrawCircleV((Vector2){ (float)centerX, (float)centerY }, radius, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a gradient-filled circle
|
// Draw a gradient-filled circle
|
||||||
@ -111,9 +110,9 @@ void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Co
|
|||||||
rlColor4ub(color1.r, color1.g, color1.b, color1.a);
|
rlColor4ub(color1.r, color1.g, color1.b, color1.a);
|
||||||
rlVertex2i(centerX, centerY);
|
rlVertex2i(centerX, centerY);
|
||||||
rlColor4ub(color2.r, color2.g, color2.b, color2.a);
|
rlColor4ub(color2.r, color2.g, color2.b, color2.a);
|
||||||
rlVertex2f(centerX + sin(DEG2RAD*i)*radius, centerY + cos(DEG2RAD*i)*radius);
|
rlVertex2f(centerX + sinf(DEG2RAD*i)*radius, centerY + cosf(DEG2RAD*i)*radius);
|
||||||
rlColor4ub(color2.r, color2.g, color2.b, color2.a);
|
rlColor4ub(color2.r, color2.g, color2.b, color2.a);
|
||||||
rlVertex2f(centerX + sin(DEG2RAD*(i + 10))*radius, centerY + cos(DEG2RAD*(i + 10))*radius);
|
rlVertex2f(centerX + sinf(DEG2RAD*(i + 10))*radius, centerY + cosf(DEG2RAD*(i + 10))*radius);
|
||||||
}
|
}
|
||||||
rlEnd();
|
rlEnd();
|
||||||
}
|
}
|
||||||
@ -129,9 +128,9 @@ void DrawCircleV(Vector2 center, float radius, Color color)
|
|||||||
{
|
{
|
||||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
|
|
||||||
rlVertex2i(center.x, center.y);
|
rlVertex2f(center.x, center.y);
|
||||||
rlVertex2f(center.x + sin(DEG2RAD*i)*radius, center.y + cos(DEG2RAD*i)*radius);
|
rlVertex2f(center.x + sinf(DEG2RAD*i)*radius, center.y + cosf(DEG2RAD*i)*radius);
|
||||||
rlVertex2f(center.x + sin(DEG2RAD*(i + 10))*radius, center.y + cos(DEG2RAD*(i + 10))*radius);
|
rlVertex2f(center.x + sinf(DEG2RAD*(i + 10))*radius, center.y + cosf(DEG2RAD*(i + 10))*radius);
|
||||||
}
|
}
|
||||||
rlEnd();
|
rlEnd();
|
||||||
}
|
}
|
||||||
@ -144,10 +143,10 @@ void DrawCircleV(Vector2 center, float radius, Color color)
|
|||||||
{
|
{
|
||||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
|
|
||||||
rlVertex2i(center.x, center.y);
|
rlVertex2f(center.x, center.y);
|
||||||
rlVertex2f(center.x + sin(DEG2RAD*i)*radius, center.y + cos(DEG2RAD*i)*radius);
|
rlVertex2f(center.x + sinf(DEG2RAD*i)*radius, center.y + cosf(DEG2RAD*i)*radius);
|
||||||
rlVertex2f(center.x + sin(DEG2RAD*(i + 10))*radius, center.y + cos(DEG2RAD*(i + 10))*radius);
|
rlVertex2f(center.x + sinf(DEG2RAD*(i + 10))*radius, center.y + cosf(DEG2RAD*(i + 10))*radius);
|
||||||
rlVertex2f(center.x + sin(DEG2RAD*(i + 20))*radius, center.y + cos(DEG2RAD*(i + 20))*radius);
|
rlVertex2f(center.x + sinf(DEG2RAD*(i + 20))*radius, center.y + cosf(DEG2RAD*(i + 20))*radius);
|
||||||
}
|
}
|
||||||
rlEnd();
|
rlEnd();
|
||||||
|
|
||||||
@ -164,8 +163,8 @@ void DrawCircleLines(int centerX, int centerY, float radius, Color color)
|
|||||||
// NOTE: Circle outline is drawn pixel by pixel every degree (0 to 360)
|
// NOTE: Circle outline is drawn pixel by pixel every degree (0 to 360)
|
||||||
for (int i = 0; i < 360; i += 10)
|
for (int i = 0; i < 360; i += 10)
|
||||||
{
|
{
|
||||||
rlVertex2f(centerX + sin(DEG2RAD*i)*radius, centerY + cos(DEG2RAD*i)*radius);
|
rlVertex2f(centerX + sinf(DEG2RAD*i)*radius, centerY + cosf(DEG2RAD*i)*radius);
|
||||||
rlVertex2f(centerX + sin(DEG2RAD*(i + 10))*radius, centerY + cos(DEG2RAD*(i + 10))*radius);
|
rlVertex2f(centerX + sinf(DEG2RAD*(i + 10))*radius, centerY + cosf(DEG2RAD*(i + 10))*radius);
|
||||||
}
|
}
|
||||||
rlEnd();
|
rlEnd();
|
||||||
}
|
}
|
||||||
@ -330,9 +329,9 @@ void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color col
|
|||||||
{
|
{
|
||||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
|
|
||||||
rlVertex2i(0, 0);
|
rlVertex2f(0, 0);
|
||||||
rlVertex2f(sin(DEG2RAD*i)*radius, cos(DEG2RAD*i)*radius);
|
rlVertex2f(sinf(DEG2RAD*i)*radius, cosf(DEG2RAD*i)*radius);
|
||||||
rlVertex2f(sin(DEG2RAD*(i + 360/sides))*radius, cos(DEG2RAD*(i + 360/sides))*radius);
|
rlVertex2f(sinf(DEG2RAD*(i + 360/sides))*radius, cosf(DEG2RAD*(i + 360/sides))*radius);
|
||||||
}
|
}
|
||||||
rlEnd();
|
rlEnd();
|
||||||
rlPopMatrix();
|
rlPopMatrix();
|
||||||
@ -434,7 +433,7 @@ bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, floa
|
|||||||
float dx = center2.x - center1.x; // X distance between centers
|
float dx = center2.x - center1.x; // X distance between centers
|
||||||
float dy = center2.y - center1.y; // Y distance between centers
|
float dy = center2.y - center1.y; // Y distance between centers
|
||||||
|
|
||||||
float distance = sqrt(dx*dx + dy*dy); // Distance between centers
|
float distance = sqrtf(dx*dx + dy*dy); // Distance between centers
|
||||||
|
|
||||||
if (distance <= (radius1 + radius2)) collision = true;
|
if (distance <= (radius1 + radius2)) collision = true;
|
||||||
|
|
||||||
@ -457,7 +456,7 @@ bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec)
|
|||||||
if (dx <= (rec.width/2)) { return true; }
|
if (dx <= (rec.width/2)) { return true; }
|
||||||
if (dy <= (rec.height/2)) { return true; }
|
if (dy <= (rec.height/2)) { return true; }
|
||||||
|
|
||||||
float cornerDistanceSq = pow(dx - rec.width/2, 2) + pow(dy - rec.height/2, 2);
|
float cornerDistanceSq = (dx - rec.width/2)*(dx - rec.width/2) + (dy - rec.height/2)*(dy - rec.height/2);
|
||||||
|
|
||||||
return (cornerDistanceSq <= (radius*radius));
|
return (cornerDistanceSq <= (radius*radius));
|
||||||
}
|
}
|
||||||
|
212
src/text.c
212
src/text.c
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Basic functions to load SpriteFonts and draw Text
|
* Basic functions to load SpriteFonts and draw Text
|
||||||
*
|
*
|
||||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||||
* will the authors be held liable for any damages arising from the use of this software.
|
* will the authors be held liable for any damages arising from the use of this software.
|
||||||
@ -30,9 +30,10 @@
|
|||||||
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
|
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
|
||||||
#include <stdio.h> // Required for: FILE, fopen(), fclose(), fscanf(), feof(), rewind(), fgets()
|
#include <stdio.h> // Required for: FILE, fopen(), fclose(), fscanf(), feof(), rewind(), fgets()
|
||||||
|
|
||||||
#include "utils.h" // Required for: GetExtension()
|
#include "utils.h" // Required for: GetExtension(), GetNextPOT()
|
||||||
|
|
||||||
// Following libs are used on LoadTTF()
|
// Following libs are used on LoadTTF()
|
||||||
|
//#define STBTT_STATIC
|
||||||
#define STB_TRUETYPE_IMPLEMENTATION
|
#define STB_TRUETYPE_IMPLEMENTATION
|
||||||
#include "external/stb_truetype.h" // Required for: stbtt_BakeFontBitmap()
|
#include "external/stb_truetype.h" // Required for: stbtt_BakeFontBitmap()
|
||||||
|
|
||||||
@ -43,7 +44,6 @@
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Defines and Macros
|
// Defines and Macros
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
#define FONT_FIRST_CHAR 32 // NOTE: Expected first char for a sprite font
|
|
||||||
#define MAX_FORMATTEXT_LENGTH 64
|
#define MAX_FORMATTEXT_LENGTH 64
|
||||||
#define MAX_SUBTEXT_LENGTH 64
|
#define MAX_SUBTEXT_LENGTH 64
|
||||||
|
|
||||||
@ -68,12 +68,12 @@ static SpriteFont defaultFont; // Default font provided by raylib
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module specific Functions Declaration
|
// Module specific Functions Declaration
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
static int GetCharIndex(SpriteFont font, int letter);
|
||||||
|
|
||||||
static SpriteFont LoadImageFont(Image image, Color key, int firstChar); // Load a Image font file (XNA style)
|
static SpriteFont LoadImageFont(Image image, Color key, int firstChar); // Load a Image font file (XNA style)
|
||||||
static SpriteFont LoadRBMF(const char *fileName); // Load a rBMF font file (raylib BitMap Font)
|
static SpriteFont LoadRBMF(const char *fileName); // Load a rBMF font file (raylib BitMap Font)
|
||||||
static SpriteFont LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file)
|
static SpriteFont LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file)
|
||||||
|
static SpriteFont LoadTTF(const char *fileName, int fontSize, int numChars, int *fontChars); // Load spritefont from TTF data
|
||||||
// Generate a sprite font image from TTF data
|
|
||||||
static SpriteFont LoadTTF(const char *fileName, int fontSize, int firstChar, int numChars);
|
|
||||||
|
|
||||||
extern void LoadDefaultFont(void);
|
extern void LoadDefaultFont(void);
|
||||||
extern void UnloadDefaultFont(void);
|
extern void UnloadDefaultFont(void);
|
||||||
@ -198,7 +198,7 @@ extern void LoadDefaultFont(void)
|
|||||||
|
|
||||||
for (int i = 0; i < defaultFont.numChars; i++)
|
for (int i = 0; i < defaultFont.numChars; i++)
|
||||||
{
|
{
|
||||||
defaultFont.charValues[i] = FONT_FIRST_CHAR + i; // First char is 32
|
defaultFont.charValues[i] = 32 + i; // First char is 32
|
||||||
|
|
||||||
defaultFont.charRecs[i].x = currentPosX;
|
defaultFont.charRecs[i].x = currentPosX;
|
||||||
defaultFont.charRecs[i].y = charsDivisor + currentLine*(charsHeight + charsDivisor);
|
defaultFont.charRecs[i].y = charsDivisor + currentLine*(charsHeight + charsDivisor);
|
||||||
@ -249,17 +249,18 @@ SpriteFont LoadSpriteFont(const char *fileName)
|
|||||||
// Default hardcoded values for ttf file loading
|
// Default hardcoded values for ttf file loading
|
||||||
#define DEFAULT_TTF_FONTSIZE 32 // Font first character (32 - space)
|
#define DEFAULT_TTF_FONTSIZE 32 // Font first character (32 - space)
|
||||||
#define DEFAULT_TTF_NUMCHARS 95 // ASCII 32..126 is 95 glyphs
|
#define DEFAULT_TTF_NUMCHARS 95 // ASCII 32..126 is 95 glyphs
|
||||||
|
#define DEFAULT_FIRST_CHAR 32 // Expected first char for image spritefont
|
||||||
|
|
||||||
SpriteFont spriteFont = { 0 };
|
SpriteFont spriteFont = { 0 };
|
||||||
|
|
||||||
// Check file extension
|
// Check file extension
|
||||||
if (strcmp(GetExtension(fileName),"rbmf") == 0) spriteFont = LoadRBMF(fileName);
|
if (strcmp(GetExtension(fileName),"rbmf") == 0) spriteFont = LoadRBMF(fileName);
|
||||||
else if (strcmp(GetExtension(fileName),"ttf") == 0) spriteFont = LoadTTF(fileName, DEFAULT_TTF_FONTSIZE, FONT_FIRST_CHAR, DEFAULT_TTF_NUMCHARS);
|
else if (strcmp(GetExtension(fileName),"ttf") == 0) spriteFont = LoadSpriteFontTTF(fileName, DEFAULT_TTF_FONTSIZE, 0, NULL);
|
||||||
else if (strcmp(GetExtension(fileName),"fnt") == 0) spriteFont = LoadBMFont(fileName);
|
else if (strcmp(GetExtension(fileName),"fnt") == 0) spriteFont = LoadBMFont(fileName);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Image image = LoadImage(fileName);
|
Image image = LoadImage(fileName);
|
||||||
if (image.data != NULL) spriteFont = LoadImageFont(image, MAGENTA, FONT_FIRST_CHAR);
|
if (image.data != NULL) spriteFont = LoadImageFont(image, MAGENTA, DEFAULT_FIRST_CHAR);
|
||||||
UnloadImage(image);
|
UnloadImage(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,6 +269,38 @@ SpriteFont LoadSpriteFont(const char *fileName)
|
|||||||
TraceLog(WARNING, "[%s] SpriteFont could not be loaded, using default font", fileName);
|
TraceLog(WARNING, "[%s] SpriteFont could not be loaded, using default font", fileName);
|
||||||
spriteFont = GetDefaultFont();
|
spriteFont = GetDefaultFont();
|
||||||
}
|
}
|
||||||
|
else SetTextureFilter(spriteFont.texture, FILTER_POINT); // By default we set point filter (best performance)
|
||||||
|
|
||||||
|
return spriteFont;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load SpriteFont from TTF file with custom parameters
|
||||||
|
// NOTE: You can pass an array with desired characters, those characters should be available in the font
|
||||||
|
// if array is NULL, default char set is selected 32..126
|
||||||
|
SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int numChars, int *fontChars)
|
||||||
|
{
|
||||||
|
SpriteFont spriteFont = { 0 };
|
||||||
|
|
||||||
|
if (strcmp(GetExtension(fileName),"ttf") == 0)
|
||||||
|
{
|
||||||
|
if ((fontChars == NULL) || (numChars == 0))
|
||||||
|
{
|
||||||
|
int totalChars = 95; // Default charset [32..126]
|
||||||
|
|
||||||
|
int *defaultFontChars = (int *)malloc(totalChars*sizeof(int));
|
||||||
|
|
||||||
|
for (int i = 0; i < totalChars; i++) defaultFontChars[i] = i + 32; // Default first character: SPACE[32]
|
||||||
|
|
||||||
|
spriteFont = LoadTTF(fileName, fontSize, totalChars, defaultFontChars);
|
||||||
|
}
|
||||||
|
else spriteFont = LoadTTF(fileName, fontSize, numChars, fontChars);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spriteFont.texture.id == 0)
|
||||||
|
{
|
||||||
|
TraceLog(WARNING, "[%s] SpriteFont could not be generated, using default font", fileName);
|
||||||
|
spriteFont = GetDefaultFont();
|
||||||
|
}
|
||||||
|
|
||||||
return spriteFont;
|
return spriteFont;
|
||||||
}
|
}
|
||||||
@ -293,13 +326,17 @@ void UnloadSpriteFont(SpriteFont spriteFont)
|
|||||||
// NOTE: chars spacing is proportional to fontSize
|
// NOTE: chars spacing is proportional to fontSize
|
||||||
void DrawText(const char *text, int posX, int posY, int fontSize, Color color)
|
void DrawText(const char *text, int posX, int posY, int fontSize, Color color)
|
||||||
{
|
{
|
||||||
Vector2 position = { (float)posX, (float)posY };
|
// Check if default font has been loaded
|
||||||
|
if (defaultFont.texture.id != 0)
|
||||||
|
{
|
||||||
|
Vector2 position = { (float)posX, (float)posY };
|
||||||
|
|
||||||
int defaultFontSize = 10; // Default Font chars height in pixel
|
int defaultFontSize = 10; // Default Font chars height in pixel
|
||||||
if (fontSize < defaultFontSize) fontSize = defaultFontSize;
|
if (fontSize < defaultFontSize) fontSize = defaultFontSize;
|
||||||
int spacing = fontSize/defaultFontSize;
|
int spacing = fontSize/defaultFontSize;
|
||||||
|
|
||||||
DrawTextEx(defaultFont, text, position, (float)fontSize, spacing, color);
|
DrawTextEx(GetDefaultFont(), text, position, (float)fontSize, spacing, color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw text using SpriteFont
|
// Draw text using SpriteFont
|
||||||
@ -321,22 +358,18 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float
|
|||||||
|
|
||||||
for (int i = 0; i < length; i++)
|
for (int i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
// TODO: Right now we are supposing characters that follow a continous order and start at FONT_FIRST_CHAR,
|
|
||||||
// this sytem can be improved to support any characters order and init value...
|
|
||||||
// An intermediate table could be created to link char values with predefined char position index in chars rectangle array
|
|
||||||
|
|
||||||
if ((unsigned char)text[i] == 0xc2) // UTF-8 encoding identification HACK!
|
if ((unsigned char)text[i] == 0xc2) // UTF-8 encoding identification HACK!
|
||||||
{
|
{
|
||||||
// Support UTF-8 encoded values from [0xc2 0x80] -> [0xc2 0xbf](¿)
|
// Support UTF-8 encoded values from [0xc2 0x80] -> [0xc2 0xbf](¿)
|
||||||
letter = (unsigned char)text[i + 1];
|
letter = (unsigned char)text[i + 1];
|
||||||
rec = spriteFont.charRecs[letter - FONT_FIRST_CHAR];
|
rec = spriteFont.charRecs[GetCharIndex(spriteFont, (int)letter)];
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
else if ((unsigned char)text[i] == 0xc3) // UTF-8 encoding identification HACK!
|
else if ((unsigned char)text[i] == 0xc3) // UTF-8 encoding identification HACK!
|
||||||
{
|
{
|
||||||
// Support UTF-8 encoded values from [0xc3 0x80](À) -> [0xc3 0xbf](ÿ)
|
// Support UTF-8 encoded values from [0xc3 0x80](À) -> [0xc3 0xbf](ÿ)
|
||||||
letter = (unsigned char)text[i + 1];
|
letter = (unsigned char)text[i + 1];
|
||||||
rec = spriteFont.charRecs[letter - FONT_FIRST_CHAR + 64];
|
rec = spriteFont.charRecs[GetCharIndex(spriteFont, (int)letter + 64)];
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -348,17 +381,19 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float
|
|||||||
textOffsetX = 0;
|
textOffsetX = 0;
|
||||||
rec.x = -1;
|
rec.x = -1;
|
||||||
}
|
}
|
||||||
else rec = spriteFont.charRecs[(int)text[i] - FONT_FIRST_CHAR];
|
else rec = spriteFont.charRecs[GetCharIndex(spriteFont, (int)text[i])];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rec.x > 0)
|
if (rec.x >= 0)
|
||||||
{
|
{
|
||||||
DrawTexturePro(spriteFont.texture, rec, (Rectangle){ position.x + textOffsetX + spriteFont.charOffsets[(int)text[i] - FONT_FIRST_CHAR].x*scaleFactor,
|
int index = GetCharIndex(spriteFont, (int)text[i]);
|
||||||
position.y + textOffsetY + spriteFont.charOffsets[(int)text[i] - FONT_FIRST_CHAR].y*scaleFactor,
|
|
||||||
|
DrawTexturePro(spriteFont.texture, rec, (Rectangle){ position.x + textOffsetX + spriteFont.charOffsets[index].x*scaleFactor,
|
||||||
|
position.y + textOffsetY + spriteFont.charOffsets[index].y*scaleFactor,
|
||||||
rec.width*scaleFactor, rec.height*scaleFactor} , (Vector2){ 0, 0 }, 0.0f, tint);
|
rec.width*scaleFactor, rec.height*scaleFactor} , (Vector2){ 0, 0 }, 0.0f, tint);
|
||||||
|
|
||||||
if (spriteFont.charAdvanceX[(int)text[i] - FONT_FIRST_CHAR] == 0) textOffsetX += (rec.width*scaleFactor + spacing);
|
if (spriteFont.charAdvanceX[index] == 0) textOffsetX += (rec.width*scaleFactor + spacing);
|
||||||
else textOffsetX += (spriteFont.charAdvanceX[(int)text[i] - FONT_FIRST_CHAR]*scaleFactor + spacing);
|
else textOffsetX += (spriteFont.charAdvanceX[index]*scaleFactor + spacing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -404,13 +439,17 @@ const char *SubText(const char *text, int position, int length)
|
|||||||
// Measure string width for default font
|
// Measure string width for default font
|
||||||
int MeasureText(const char *text, int fontSize)
|
int MeasureText(const char *text, int fontSize)
|
||||||
{
|
{
|
||||||
Vector2 vec;
|
Vector2 vec = { 0.0f, 0.0f };
|
||||||
|
|
||||||
int defaultFontSize = 10; // Default Font chars height in pixel
|
// Check if default font has been loaded
|
||||||
if (fontSize < defaultFontSize) fontSize = defaultFontSize;
|
if (defaultFont.texture.id != 0)
|
||||||
int spacing = fontSize/defaultFontSize;
|
{
|
||||||
|
int defaultFontSize = 10; // Default Font chars height in pixel
|
||||||
|
if (fontSize < defaultFontSize) fontSize = defaultFontSize;
|
||||||
|
int spacing = fontSize/defaultFontSize;
|
||||||
|
|
||||||
vec = MeasureTextEx(defaultFont, text, fontSize, spacing);
|
vec = MeasureTextEx(GetDefaultFont(), text, fontSize, spacing);
|
||||||
|
}
|
||||||
|
|
||||||
return (int)vec.x;
|
return (int)vec.x;
|
||||||
}
|
}
|
||||||
@ -434,8 +473,10 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int
|
|||||||
|
|
||||||
if (text[i] != '\n')
|
if (text[i] != '\n')
|
||||||
{
|
{
|
||||||
if (spriteFont.charAdvanceX[(int)text[i] - FONT_FIRST_CHAR] != 0) textWidth += spriteFont.charAdvanceX[(int)text[i] - FONT_FIRST_CHAR];
|
int index = GetCharIndex(spriteFont, (int)text[i]);
|
||||||
else textWidth += (spriteFont.charRecs[(int)text[i] - FONT_FIRST_CHAR].width + spriteFont.charOffsets[(int)text[i] - FONT_FIRST_CHAR].x);
|
|
||||||
|
if (spriteFont.charAdvanceX[index] != 0) textWidth += spriteFont.charAdvanceX[index];
|
||||||
|
else textWidth += (spriteFont.charRecs[index].width + spriteFont.charOffsets[index].x);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -492,7 +533,28 @@ void DrawFPS(int posX, int posY)
|
|||||||
// Module specific Functions Definition
|
// Module specific Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Load a Image font file (XNA style)
|
static int GetCharIndex(SpriteFont font, int letter)
|
||||||
|
{
|
||||||
|
//#define UNORDERED_CHARSET
|
||||||
|
#if defined(UNORDERED_CHARSET)
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < font.numChars; i++)
|
||||||
|
{
|
||||||
|
if (font.charValues[i] == letter)
|
||||||
|
{
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return index;
|
||||||
|
#else
|
||||||
|
return (letter - 32);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load an Image font file (XNA style)
|
||||||
static SpriteFont LoadImageFont(Image image, Color key, int firstChar)
|
static SpriteFont LoadImageFont(Image image, Color key, int firstChar)
|
||||||
{
|
{
|
||||||
#define COLOR_EQUAL(col1, col2) ((col1.r == col2.r)&&(col1.g == col2.g)&&(col1.b == col2.b)&&(col1.a == col2.a))
|
#define COLOR_EQUAL(col1, col2) ((col1.r == col2.r)&&(col1.g == col2.g)&&(col1.b == col2.b)&&(col1.a == col2.a))
|
||||||
@ -503,8 +565,8 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar)
|
|||||||
int x = 0;
|
int x = 0;
|
||||||
int y = 0;
|
int y = 0;
|
||||||
|
|
||||||
// Default number of characters expected supported
|
// Default number of characters supported
|
||||||
#define MAX_FONTCHARS 128
|
#define MAX_FONTCHARS 256
|
||||||
|
|
||||||
// We allocate a temporal arrays for chars data measures,
|
// We allocate a temporal arrays for chars data measures,
|
||||||
// once we get the actual number of chars, we copy data to a sized arrays
|
// once we get the actual number of chars, we copy data to a sized arrays
|
||||||
@ -565,15 +627,24 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar)
|
|||||||
xPosToRead = charSpacing;
|
xPosToRead = charSpacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(pixels);
|
|
||||||
|
|
||||||
TraceLog(DEBUG, "SpriteFont data parsed correctly from image");
|
TraceLog(DEBUG, "SpriteFont data parsed correctly from image");
|
||||||
|
|
||||||
|
// NOTE: We need to remove key color borders from image to avoid weird
|
||||||
|
// artifacts on texture scaling when using FILTER_BILINEAR or FILTER_TRILINEAR
|
||||||
|
for (int i = 0; i < image.height*image.width; i++) if (COLOR_EQUAL(pixels[i], key)) pixels[i] = BLANK;
|
||||||
|
|
||||||
|
// Create a new image with the processed color data (key color replaced by BLANK)
|
||||||
|
Image fontClear = LoadImageEx(pixels, image.width, image.height);
|
||||||
|
|
||||||
|
free(pixels); // Free pixels array memory
|
||||||
|
|
||||||
// Create spritefont with all data parsed from image
|
// Create spritefont with all data parsed from image
|
||||||
SpriteFont spriteFont = { 0 };
|
SpriteFont spriteFont = { 0 };
|
||||||
|
|
||||||
spriteFont.texture = LoadTextureFromImage(image); // Convert loaded image to OpenGL texture
|
spriteFont.texture = LoadTextureFromImage(fontClear); // Convert processed image to OpenGL texture
|
||||||
spriteFont.numChars = index;
|
spriteFont.numChars = index;
|
||||||
|
|
||||||
|
UnloadImage(fontClear); // Unload processed image once converted to texture
|
||||||
|
|
||||||
// We got tempCharValues and tempCharsRecs populated with chars data
|
// We got tempCharValues and tempCharsRecs populated with chars data
|
||||||
// Now we move temp data to sized charValues and charRecs arrays
|
// Now we move temp data to sized charValues and charRecs arrays
|
||||||
@ -803,8 +874,13 @@ static SpriteFont LoadBMFont(const char *fileName)
|
|||||||
strncat(texPath, texFileName, strlen(texFileName));
|
strncat(texPath, texFileName, strlen(texFileName));
|
||||||
|
|
||||||
TraceLog(DEBUG, "[%s] Font texture loading path: %s", fileName, texPath);
|
TraceLog(DEBUG, "[%s] Font texture loading path: %s", fileName, texPath);
|
||||||
|
|
||||||
|
Image imFont = LoadImage(texPath);
|
||||||
|
|
||||||
font.texture = LoadTexture(texPath);
|
if (imFont.format == UNCOMPRESSED_GRAYSCALE) ImageAlphaMask(&imFont, imFont);
|
||||||
|
|
||||||
|
font.texture = LoadTextureFromImage(imFont);
|
||||||
|
|
||||||
font.size = fontSize;
|
font.size = fontSize;
|
||||||
font.numChars = numChars;
|
font.numChars = numChars;
|
||||||
font.charValues = (int *)malloc(numChars*sizeof(int));
|
font.charValues = (int *)malloc(numChars*sizeof(int));
|
||||||
@ -812,22 +888,18 @@ static SpriteFont LoadBMFont(const char *fileName)
|
|||||||
font.charOffsets = (Vector2 *)malloc(numChars*sizeof(Vector2));
|
font.charOffsets = (Vector2 *)malloc(numChars*sizeof(Vector2));
|
||||||
font.charAdvanceX = (int *)malloc(numChars*sizeof(int));
|
font.charAdvanceX = (int *)malloc(numChars*sizeof(int));
|
||||||
|
|
||||||
|
UnloadImage(imFont);
|
||||||
|
|
||||||
free(texPath);
|
free(texPath);
|
||||||
|
|
||||||
int charId, charX, charY, charWidth, charHeight, charOffsetX, charOffsetY, charAdvanceX;
|
int charId, charX, charY, charWidth, charHeight, charOffsetX, charOffsetY, charAdvanceX;
|
||||||
|
|
||||||
bool unorderedChars = false;
|
|
||||||
int firstChar = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < numChars; i++)
|
for (int i = 0; i < numChars; i++)
|
||||||
{
|
{
|
||||||
fgets(buffer, MAX_BUFFER_SIZE, fntFile);
|
fgets(buffer, MAX_BUFFER_SIZE, fntFile);
|
||||||
sscanf(buffer, "char id=%i x=%i y=%i width=%i height=%i xoffset=%i yoffset=%i xadvance=%i",
|
sscanf(buffer, "char id=%i x=%i y=%i width=%i height=%i xoffset=%i yoffset=%i xadvance=%i",
|
||||||
&charId, &charX, &charY, &charWidth, &charHeight, &charOffsetX, &charOffsetY, &charAdvanceX);
|
&charId, &charX, &charY, &charWidth, &charHeight, &charOffsetX, &charOffsetY, &charAdvanceX);
|
||||||
|
|
||||||
if (i == 0) firstChar = charId;
|
|
||||||
else if (i != (charId - firstChar)) unorderedChars = true;
|
|
||||||
|
|
||||||
// Save data properly in sprite font
|
// Save data properly in sprite font
|
||||||
font.charValues[i] = charId;
|
font.charValues[i] = charId;
|
||||||
font.charRecs[i] = (Rectangle){ charX, charY, charWidth, charHeight };
|
font.charRecs[i] = (Rectangle){ charX, charY, charWidth, charHeight };
|
||||||
@ -837,11 +909,7 @@ static SpriteFont LoadBMFont(const char *fileName)
|
|||||||
|
|
||||||
fclose(fntFile);
|
fclose(fntFile);
|
||||||
|
|
||||||
if (firstChar != FONT_FIRST_CHAR) TraceLog(WARNING, "BMFont not supported: expected SPACE(32) as first character, falling back to default font");
|
if (font.texture.id == 0)
|
||||||
else if (unorderedChars) TraceLog(WARNING, "BMFont not supported: unordered chars data, falling back to default font");
|
|
||||||
|
|
||||||
// NOTE: Font data could be not ordered by charId: 32,33,34,35... raylib does not support unordered BMFonts
|
|
||||||
if ((firstChar != FONT_FIRST_CHAR) || (unorderedChars) || (font.texture.id == 0))
|
|
||||||
{
|
{
|
||||||
UnloadSpriteFont(font);
|
UnloadSpriteFont(font);
|
||||||
font = GetDefaultFont();
|
font = GetDefaultFont();
|
||||||
@ -853,14 +921,17 @@ static SpriteFont LoadBMFont(const char *fileName)
|
|||||||
|
|
||||||
// Generate a sprite font from TTF file data (font size required)
|
// Generate a sprite font from TTF file data (font size required)
|
||||||
// TODO: Review texture packing method and generation (use oversampling)
|
// TODO: Review texture packing method and generation (use oversampling)
|
||||||
static SpriteFont LoadTTF(const char *fileName, int fontSize, int firstChar, int numChars)
|
static SpriteFont LoadTTF(const char *fileName, int fontSize, int numChars, int *fontChars)
|
||||||
{
|
{
|
||||||
// NOTE: Generated font uses some hardcoded values
|
// NOTE: Font texture size is predicted (being as much conservative as possible)
|
||||||
#define FONT_TEXTURE_WIDTH 512 // Font texture width
|
// Predictive method consist of supposing same number of chars by line-column (sqrtf)
|
||||||
#define FONT_TEXTURE_HEIGHT 512 // Font texture height
|
// and a maximum character width of 3/4 of fontSize... it worked ok with all my tests...
|
||||||
|
int textureSize = GetNextPOT(ceil((float)fontSize*3/4)*ceil(sqrtf((float)numChars)));
|
||||||
|
|
||||||
|
TraceLog(INFO, "TTF spritefont loading: Predicted texture size: %ix%i", textureSize, textureSize);
|
||||||
|
|
||||||
unsigned char *ttfBuffer = (unsigned char *)malloc(1 << 25);
|
unsigned char *ttfBuffer = (unsigned char *)malloc(1 << 25);
|
||||||
unsigned char *dataBitmap = (unsigned char *)malloc(FONT_TEXTURE_WIDTH*FONT_TEXTURE_HEIGHT*sizeof(unsigned char)); // One channel bitmap returned!
|
unsigned char *dataBitmap = (unsigned char *)malloc(textureSize*textureSize*sizeof(unsigned char)); // One channel bitmap returned!
|
||||||
stbtt_bakedchar *charData = (stbtt_bakedchar *)malloc(sizeof(stbtt_bakedchar)*numChars);
|
stbtt_bakedchar *charData = (stbtt_bakedchar *)malloc(sizeof(stbtt_bakedchar)*numChars);
|
||||||
|
|
||||||
SpriteFont font = { 0 };
|
SpriteFont font = { 0 };
|
||||||
@ -869,40 +940,47 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int firstChar, int
|
|||||||
|
|
||||||
if (ttfFile == NULL)
|
if (ttfFile == NULL)
|
||||||
{
|
{
|
||||||
TraceLog(WARNING, "[%s] FNT file could not be opened", fileName);
|
TraceLog(WARNING, "[%s] TTF file could not be opened", fileName);
|
||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
fread(ttfBuffer, 1, 1<<25, ttfFile);
|
fread(ttfBuffer, 1, 1<<25, ttfFile);
|
||||||
|
|
||||||
|
if (fontChars[0] != 32) TraceLog(WARNING, "TTF spritefont loading: first character is not SPACE(32) character");
|
||||||
|
|
||||||
// NOTE: Using stb_truetype crappy packing method, no guarante the font fits the image...
|
// NOTE: Using stb_truetype crappy packing method, no guarante the font fits the image...
|
||||||
stbtt_BakeFontBitmap(ttfBuffer,0, fontSize, dataBitmap, FONT_TEXTURE_WIDTH, FONT_TEXTURE_HEIGHT, firstChar, numChars, charData);
|
// TODO: Replace this function by a proper packing method and support random chars order,
|
||||||
|
// we already receive a list (fontChars) with the ordered expected characters
|
||||||
|
int result = stbtt_BakeFontBitmap(ttfBuffer, 0, fontSize, dataBitmap, textureSize, textureSize, fontChars[0], numChars, charData);
|
||||||
|
|
||||||
|
//if (result > 0) TraceLog(INFO, "TTF spritefont loading: first unused row of generated bitmap: %i", result);
|
||||||
|
if (result < 0) TraceLog(WARNING, "TTF spritefont loading: Not all the characters fit in the font");
|
||||||
|
|
||||||
free(ttfBuffer);
|
free(ttfBuffer);
|
||||||
|
|
||||||
// Convert image data from grayscale to to UNCOMPRESSED_GRAY_ALPHA
|
// Convert image data from grayscale to to UNCOMPRESSED_GRAY_ALPHA
|
||||||
unsigned char *dataGrayAlpha = (unsigned char *)malloc(FONT_TEXTURE_WIDTH*FONT_TEXTURE_HEIGHT*sizeof(unsigned char)*2); // Two channels
|
unsigned char *dataGrayAlpha = (unsigned char *)malloc(textureSize*textureSize*sizeof(unsigned char)*2); // Two channels
|
||||||
int k = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < FONT_TEXTURE_WIDTH*FONT_TEXTURE_HEIGHT; i++)
|
for (int i = 0, k = 0; i < textureSize*textureSize; i++, k += 2)
|
||||||
{
|
{
|
||||||
dataGrayAlpha[k] = 255;
|
dataGrayAlpha[k] = 255;
|
||||||
dataGrayAlpha[k + 1] = dataBitmap[i];
|
dataGrayAlpha[k + 1] = dataBitmap[i];
|
||||||
|
|
||||||
k += 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(dataBitmap);
|
free(dataBitmap);
|
||||||
|
|
||||||
// Sprite font generation from TTF extracted data
|
// Sprite font generation from TTF extracted data
|
||||||
Image image;
|
Image image;
|
||||||
image.width = FONT_TEXTURE_WIDTH;
|
image.width = textureSize;
|
||||||
image.height = FONT_TEXTURE_HEIGHT;
|
image.height = textureSize;
|
||||||
image.mipmaps = 1;
|
image.mipmaps = 1;
|
||||||
image.format = UNCOMPRESSED_GRAY_ALPHA;
|
image.format = UNCOMPRESSED_GRAY_ALPHA;
|
||||||
image.data = dataGrayAlpha;
|
image.data = dataGrayAlpha;
|
||||||
|
|
||||||
font.texture = LoadTextureFromImage(image);
|
font.texture = LoadTextureFromImage(image);
|
||||||
|
|
||||||
|
//WritePNG("generated_ttf_image.png", (unsigned char *)image.data, image.width, image.height, 2);
|
||||||
|
|
||||||
UnloadImage(image); // Unloads dataGrayAlpha
|
UnloadImage(image); // Unloads dataGrayAlpha
|
||||||
|
|
||||||
font.size = fontSize;
|
font.size = fontSize;
|
||||||
@ -914,7 +992,7 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int firstChar, int
|
|||||||
|
|
||||||
for (int i = 0; i < font.numChars; i++)
|
for (int i = 0; i < font.numChars; i++)
|
||||||
{
|
{
|
||||||
font.charValues[i] = i + firstChar;
|
font.charValues[i] = fontChars[i];
|
||||||
|
|
||||||
font.charRecs[i].x = (int)charData[i].x0;
|
font.charRecs[i].x = (int)charData[i].x0;
|
||||||
font.charRecs[i].y = (int)charData[i].y0;
|
font.charRecs[i].y = (int)charData[i].y0;
|
||||||
|
145
src/textures.c
145
src/textures.c
@ -8,7 +8,7 @@
|
|||||||
* stb_image - Multiple formats image loading (JPEG, PNG, BMP, TGA, PSD, GIF, PIC)
|
* stb_image - Multiple formats image loading (JPEG, PNG, BMP, TGA, PSD, GIF, PIC)
|
||||||
* NOTE: stb_image has been slightly modified, original library: https://github.com/nothings/stb
|
* NOTE: stb_image has been slightly modified, original library: https://github.com/nothings/stb
|
||||||
*
|
*
|
||||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||||
* will the authors be held liable for any damages arising from the use of this software.
|
* will the authors be held liable for any damages arising from the use of this software.
|
||||||
@ -229,7 +229,7 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int
|
|||||||
// TODO: Review function to support multiple color modes
|
// TODO: Review function to support multiple color modes
|
||||||
Image LoadImageFromRES(const char *rresName, int resId)
|
Image LoadImageFromRES(const char *rresName, int resId)
|
||||||
{
|
{
|
||||||
Image image;
|
Image image = { 0 };
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
char id[4]; // rRES file identifier
|
char id[4]; // rRES file identifier
|
||||||
@ -442,6 +442,96 @@ void UnloadRenderTexture(RenderTexture2D target)
|
|||||||
if (target.id != 0) rlDeleteRenderTextures(target);
|
if (target.id != 0) rlDeleteRenderTextures(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set texture scaling filter mode
|
||||||
|
void SetTextureFilter(Texture2D texture, int filterMode)
|
||||||
|
{
|
||||||
|
switch (filterMode)
|
||||||
|
{
|
||||||
|
case FILTER_POINT:
|
||||||
|
{
|
||||||
|
if (texture.mipmaps > 1)
|
||||||
|
{
|
||||||
|
// RL_FILTER_MIP_NEAREST - tex filter: POINT, mipmaps filter: POINT (sharp switching between mipmaps)
|
||||||
|
rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_MIP_NEAREST);
|
||||||
|
|
||||||
|
// RL_FILTER_NEAREST - tex filter: POINT (no filter), no mipmaps
|
||||||
|
rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_NEAREST);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// RL_FILTER_NEAREST - tex filter: POINT (no filter), no mipmaps
|
||||||
|
rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_NEAREST);
|
||||||
|
rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_NEAREST);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case FILTER_BILINEAR:
|
||||||
|
{
|
||||||
|
if (texture.mipmaps > 1)
|
||||||
|
{
|
||||||
|
// RL_FILTER_LINEAR_MIP_NEAREST - tex filter: BILINEAR, mipmaps filter: POINT (sharp switching between mipmaps)
|
||||||
|
// Alternative: RL_FILTER_NEAREST_MIP_LINEAR - tex filter: POINT, mipmaps filter: BILINEAR (smooth transition between mipmaps)
|
||||||
|
rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_LINEAR_MIP_NEAREST);
|
||||||
|
|
||||||
|
// RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps
|
||||||
|
rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps
|
||||||
|
rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_LINEAR);
|
||||||
|
rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case FILTER_TRILINEAR:
|
||||||
|
{
|
||||||
|
if (texture.mipmaps > 1)
|
||||||
|
{
|
||||||
|
// RL_FILTER_MIP_LINEAR - tex filter: BILINEAR, mipmaps filter: BILINEAR (smooth transition between mipmaps)
|
||||||
|
rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_MIP_LINEAR);
|
||||||
|
|
||||||
|
// RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps
|
||||||
|
rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TraceLog(WARNING, "[TEX ID %i] No mipmaps available for TRILINEAR texture filtering", texture.id);
|
||||||
|
|
||||||
|
// RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps
|
||||||
|
rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_LINEAR);
|
||||||
|
rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case FILTER_ANISOTROPIC_4X: rlTextureParameters(texture.id, RL_TEXTURE_ANISOTROPIC_FILTER, 4); break;
|
||||||
|
case FILTER_ANISOTROPIC_8X: rlTextureParameters(texture.id, RL_TEXTURE_ANISOTROPIC_FILTER, 8); break;
|
||||||
|
case FILTER_ANISOTROPIC_16X: rlTextureParameters(texture.id, RL_TEXTURE_ANISOTROPIC_FILTER, 16); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set texture wrapping mode
|
||||||
|
void SetTextureWrap(Texture2D texture, int wrapMode)
|
||||||
|
{
|
||||||
|
switch (wrapMode)
|
||||||
|
{
|
||||||
|
case WRAP_REPEAT:
|
||||||
|
{
|
||||||
|
rlTextureParameters(texture.id, RL_TEXTURE_WRAP_S, RL_WRAP_REPEAT);
|
||||||
|
rlTextureParameters(texture.id, RL_TEXTURE_WRAP_T, RL_WRAP_REPEAT);
|
||||||
|
} break;
|
||||||
|
case WRAP_CLAMP:
|
||||||
|
{
|
||||||
|
rlTextureParameters(texture.id, RL_TEXTURE_WRAP_S, RL_WRAP_CLAMP);
|
||||||
|
rlTextureParameters(texture.id, RL_TEXTURE_WRAP_T, RL_WRAP_CLAMP);
|
||||||
|
} break;
|
||||||
|
case WRAP_MIRROR:
|
||||||
|
{
|
||||||
|
rlTextureParameters(texture.id, RL_TEXTURE_WRAP_S, RL_WRAP_CLAMP_MIRROR);
|
||||||
|
rlTextureParameters(texture.id, RL_TEXTURE_WRAP_T, RL_WRAP_CLAMP_MIRROR);
|
||||||
|
} break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get pixel data from image in the form of Color struct array
|
// Get pixel data from image in the form of Color struct array
|
||||||
Color *GetImageData(Image image)
|
Color *GetImageData(Image image)
|
||||||
{
|
{
|
||||||
@ -694,28 +784,45 @@ void ImageFormat(Image *image, int newFormat)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply alpha mask to image
|
// Apply alpha mask to image
|
||||||
// NOTE 1: Returned image is RGBA - 32bit
|
// NOTE 1: Returned image is GRAY_ALPHA (16bit) or RGBA (32bit)
|
||||||
// NOTE 2: alphaMask should be same size as image
|
// NOTE 2: alphaMask should be same size as image
|
||||||
void ImageAlphaMask(Image *image, Image alphaMask)
|
void ImageAlphaMask(Image *image, Image alphaMask)
|
||||||
{
|
{
|
||||||
if (image->format >= COMPRESSED_DXT1_RGB)
|
if ((image->width != alphaMask.width) || (image->height != alphaMask.height))
|
||||||
|
{
|
||||||
|
TraceLog(WARNING, "Alpha mask must be same size as image");
|
||||||
|
}
|
||||||
|
else if (image->format >= COMPRESSED_DXT1_RGB)
|
||||||
{
|
{
|
||||||
TraceLog(WARNING, "Alpha mask can not be applied to compressed data formats");
|
TraceLog(WARNING, "Alpha mask can not be applied to compressed data formats");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Force mask to be Grayscale
|
// Force mask to be Grayscale
|
||||||
Image mask = ImageCopy(alphaMask);
|
Image mask = ImageCopy(alphaMask);
|
||||||
ImageFormat(&mask, UNCOMPRESSED_GRAYSCALE);
|
if (mask.format != UNCOMPRESSED_GRAYSCALE) ImageFormat(&mask, UNCOMPRESSED_GRAYSCALE);
|
||||||
|
|
||||||
// Convert image to RGBA
|
// In case image is only grayscale, we just add alpha channel
|
||||||
if (image->format != UNCOMPRESSED_R8G8B8A8) ImageFormat(image, UNCOMPRESSED_R8G8B8A8);
|
if (image->format == UNCOMPRESSED_GRAYSCALE)
|
||||||
|
|
||||||
// Apply alpha mask to alpha channel
|
|
||||||
for (int i = 0, k = 3; (i < mask.width*mask.height) || (i < image->width*image->height); i++, k += 4)
|
|
||||||
{
|
{
|
||||||
((unsigned char *)image->data)[k] = ((unsigned char *)mask.data)[i];
|
ImageFormat(image, UNCOMPRESSED_GRAY_ALPHA);
|
||||||
|
|
||||||
|
// Apply alpha mask to alpha channel
|
||||||
|
for (int i = 0, k = 1; (i < mask.width*mask.height) || (i < image->width*image->height); i++, k += 2)
|
||||||
|
{
|
||||||
|
((unsigned char *)image->data)[k] = ((unsigned char *)mask.data)[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Convert image to RGBA
|
||||||
|
if (image->format != UNCOMPRESSED_R8G8B8A8) ImageFormat(image, UNCOMPRESSED_R8G8B8A8);
|
||||||
|
|
||||||
|
// Apply alpha mask to alpha channel
|
||||||
|
for (int i = 0, k = 3; (i < mask.width*mask.height) || (i < image->width*image->height); i++, k += 4)
|
||||||
|
{
|
||||||
|
((unsigned char *)image->data)[k] = ((unsigned char *)mask.data)[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UnloadImage(mask);
|
UnloadImage(mask);
|
||||||
@ -1118,7 +1225,7 @@ Image ImageText(const char *text, int fontSize, Color color)
|
|||||||
if (fontSize < defaultFontSize) fontSize = defaultFontSize;
|
if (fontSize < defaultFontSize) fontSize = defaultFontSize;
|
||||||
int spacing = fontSize/defaultFontSize;
|
int spacing = fontSize/defaultFontSize;
|
||||||
|
|
||||||
Image imText = ImageTextEx(GetDefaultFont(), text, fontSize, spacing, color);
|
Image imText = ImageTextEx(GetDefaultFont(), text, (float)fontSize, spacing, color);
|
||||||
|
|
||||||
return imText;
|
return imText;
|
||||||
}
|
}
|
||||||
@ -1134,7 +1241,7 @@ Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing
|
|||||||
// NOTE: GetTextureData() not available in OpenGL ES
|
// NOTE: GetTextureData() not available in OpenGL ES
|
||||||
Image imFont = GetTextureData(font.texture);
|
Image imFont = GetTextureData(font.texture);
|
||||||
|
|
||||||
ImageFormat(&imFont, UNCOMPRESSED_R8G8B8A8); // Required for color tint
|
ImageFormat(&imFont, UNCOMPRESSED_R8G8B8A8); // Convert to 32 bit for color tint
|
||||||
ImageColorTint(&imFont, tint); // Apply color tint to font
|
ImageColorTint(&imFont, tint); // Apply color tint to font
|
||||||
|
|
||||||
Color *fontPixels = GetImageData(imFont);
|
Color *fontPixels = GetImageData(imFont);
|
||||||
@ -1183,7 +1290,7 @@ Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing
|
|||||||
void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color)
|
void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color)
|
||||||
{
|
{
|
||||||
// NOTE: For default font, sapcing is set to desired font size / default font size (10)
|
// NOTE: For default font, sapcing is set to desired font size / default font size (10)
|
||||||
ImageDrawTextEx(dst, position, GetDefaultFont(), text, fontSize, fontSize/10, color);
|
ImageDrawTextEx(dst, position, GetDefaultFont(), text, (float)fontSize, fontSize/10, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw text (custom sprite font) within an image (destination)
|
// Draw text (custom sprite font) within an image (destination)
|
||||||
@ -1317,7 +1424,7 @@ void ImageColorContrast(Image *image, float contrast)
|
|||||||
if (contrast < -100) contrast = -100;
|
if (contrast < -100) contrast = -100;
|
||||||
if (contrast > 100) contrast = 100;
|
if (contrast > 100) contrast = 100;
|
||||||
|
|
||||||
contrast = (100.0 + contrast)/100.0;
|
contrast = (100.0f + contrast)/100.0f;
|
||||||
contrast *= contrast;
|
contrast *= contrast;
|
||||||
|
|
||||||
Color *pixels = GetImageData(*image);
|
Color *pixels = GetImageData(*image);
|
||||||
@ -1326,7 +1433,7 @@ void ImageColorContrast(Image *image, float contrast)
|
|||||||
{
|
{
|
||||||
for (int x = 0; x < image->width; x++)
|
for (int x = 0; x < image->width; x++)
|
||||||
{
|
{
|
||||||
float pR = (float)pixels[y*image->width + x].r/255.0;
|
float pR = (float)pixels[y*image->width + x].r/255.0f;
|
||||||
pR -= 0.5;
|
pR -= 0.5;
|
||||||
pR *= contrast;
|
pR *= contrast;
|
||||||
pR += 0.5;
|
pR += 0.5;
|
||||||
@ -1334,7 +1441,7 @@ void ImageColorContrast(Image *image, float contrast)
|
|||||||
if (pR < 0) pR = 0;
|
if (pR < 0) pR = 0;
|
||||||
if (pR > 255) pR = 255;
|
if (pR > 255) pR = 255;
|
||||||
|
|
||||||
float pG = (float)pixels[y*image->width + x].g/255.0;
|
float pG = (float)pixels[y*image->width + x].g/255.0f;
|
||||||
pG -= 0.5;
|
pG -= 0.5;
|
||||||
pG *= contrast;
|
pG *= contrast;
|
||||||
pG += 0.5;
|
pG += 0.5;
|
||||||
@ -1342,7 +1449,7 @@ void ImageColorContrast(Image *image, float contrast)
|
|||||||
if (pG < 0) pG = 0;
|
if (pG < 0) pG = 0;
|
||||||
if (pG > 255) pG = 255;
|
if (pG > 255) pG = 255;
|
||||||
|
|
||||||
float pB = (float)pixels[y*image->width + x].b/255.0;
|
float pB = (float)pixels[y*image->width + x].b/255.0f;
|
||||||
pB -= 0.5;
|
pB -= 0.5;
|
||||||
pB *= contrast;
|
pB *= contrast;
|
||||||
pB += 0.5;
|
pB += 0.5;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* tinfl - zlib DEFLATE algorithm decompression lib
|
* tinfl - zlib DEFLATE algorithm decompression lib
|
||||||
* stb_image_write - PNG writting functions
|
* stb_image_write - PNG writting functions
|
||||||
*
|
*
|
||||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||||
* will the authors be held liable for any damages arising from the use of this software.
|
* will the authors be held liable for any damages arising from the use of this software.
|
||||||
|
Loading…
Reference in New Issue
Block a user