mirror of
https://github.com/raysan5/raylib.git
synced 2025-09-05 19:08:13 +00:00
Merge branch 'master' of https://github.com/raysan5/raylib
This commit is contained in:
@@ -145,7 +145,6 @@ These are older raylib bindings that are more than 2 versions old or have not be
|
||||
| [clj-raylib](https://github.com/lsevero/clj-raylib) | 3.0 | [Clojure](https://clojure.org) |
|
||||
| [QuickJS-raylib](https://github.com/sntg-p/QuickJS-raylib) | 3.0 | [QuickJS](https://bellard.org/quickjs) |
|
||||
| [raylib-duktape](https://github.com/RobLoach/raylib-duktape) | 2.6 | [JavaScript (Duktape)](https://en.wikipedia.org/wiki/JavaScript) |
|
||||
| [raylib-v7](https://github.com/Rabios/raylib-v7) | 3.5 | [JavaScript (v7)](https://en.wikipedia.org/wiki/JavaScript) |
|
||||
| [raylib-chaiscript](https://github.com/RobLoach/raylib-chaiscript) | 2.6 | [ChaiScript](http://chaiscript.com) |
|
||||
| [raylib-squirrel](https://github.com/RobLoach/raylib-squirrel) | 2.5 | [Squirrel](http://www.squirrel-lang.org) |
|
||||
| [racket-raylib-2d](https://github.com/arvyy/racket-raylib-2d) | 2.5 | [Racket](https://racket-lang.org) |
|
||||
|
@@ -639,6 +639,7 @@ SHADERS = \
|
||||
shaders/shaders_mesh_instancing \
|
||||
shaders/shaders_model_shader \
|
||||
shaders/shaders_multi_sample2d \
|
||||
shaders/shaders_normalmap \
|
||||
shaders/shaders_palette_switch \
|
||||
shaders/shaders_postprocessing \
|
||||
shaders/shaders_raymarching \
|
||||
|
@@ -639,6 +639,7 @@ SHADERS = \
|
||||
shaders/shaders_mesh_instancing \
|
||||
shaders/shaders_model_shader \
|
||||
shaders/shaders_multi_sample2d \
|
||||
shaders/shaders_normalmap \
|
||||
shaders/shaders_palette_switch \
|
||||
shaders/shaders_postprocessing \
|
||||
shaders/shaders_raymarching \
|
||||
|
64
examples/shaders/resources/shaders/glsl100/normalmap.fs
Normal file
64
examples/shaders/resources/shaders/glsl100/normalmap.fs
Normal file
@@ -0,0 +1,64 @@
|
||||
#version 100
|
||||
|
||||
precision mediump float;
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec3 fragPosition;
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec3 fragNormal; //used for when normal mapping is toggled off
|
||||
varying vec4 fragColor;
|
||||
varying mat3 TBN;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform sampler2D normalMap;
|
||||
uniform vec4 colDiffuse;
|
||||
uniform vec3 viewPos;
|
||||
|
||||
// NOTE: Add your custom variables here
|
||||
|
||||
uniform vec3 lightPos;
|
||||
uniform bool useNormalMap;
|
||||
uniform float specularExponent;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 texelColor = texture(texture0, vec2(fragTexCoord.x, fragTexCoord.y));
|
||||
vec3 specular = vec3(0.0);
|
||||
vec3 viewDir = normalize(viewPos - fragPosition);
|
||||
vec3 lightDir = normalize(lightPos - fragPosition);
|
||||
|
||||
vec3 normal;
|
||||
if (useNormalMap)
|
||||
{
|
||||
normal = texture(normalMap, vec2(fragTexCoord.x, fragTexCoord.y)).rgb;
|
||||
|
||||
//Transform normal values to the range -1.0 ... 1.0
|
||||
normal = normalize(normal * 2.0 - 1.0);
|
||||
|
||||
//Transform the normal from tangent-space to world-space for lighting calculation
|
||||
normal = normalize(normal * TBN);
|
||||
}
|
||||
else
|
||||
{
|
||||
normal = normalize(fragNormal);
|
||||
}
|
||||
|
||||
vec4 tint = colDiffuse * fragColor;
|
||||
|
||||
vec3 lightColor = vec3(1.0, 1.0, 1.0);
|
||||
float NdotL = max(dot(normal, lightDir), 0.0);
|
||||
vec3 lightDot = lightColor * NdotL;
|
||||
|
||||
float specCo = 0.0;
|
||||
|
||||
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent); // 16 refers to shine
|
||||
|
||||
specular += specCo;
|
||||
|
||||
finalColor = (texelColor * ((tint + vec4(specular, 1.0)) * vec4(lightDot, 1.0)));
|
||||
finalColor += texelColor * (vec4(1.0, 1.0, 1.0, 1.0) / 40.0) * tint;
|
||||
|
||||
// Gamma correction
|
||||
gl_FragColor = pow(finalColor, vec4(1.0 / 2.2));
|
||||
}
|
76
examples/shaders/resources/shaders/glsl100/normalmap.vs
Normal file
76
examples/shaders/resources/shaders/glsl100/normalmap.vs
Normal file
@@ -0,0 +1,76 @@
|
||||
#version 100
|
||||
|
||||
// Input vertex attributes
|
||||
attribute vec3 vertexPosition;
|
||||
attribute vec2 vertexTexCoord;
|
||||
attribute vec3 vertexNormal;
|
||||
attribute vec4 vertexTangent;
|
||||
attribute vec4 vertexColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform mat4 mvp;
|
||||
uniform mat4 matModel;
|
||||
|
||||
// Output vertex attributes (to fragment shader)
|
||||
varying vec3 fragPosition;
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec3 fragNormal; //used for when normal mapping is toggled off
|
||||
varying vec4 fragColor;
|
||||
varying mat3 TBN;
|
||||
|
||||
// NOTE: Add your custom variables here
|
||||
|
||||
// https://github.com/glslify/glsl-inverse
|
||||
mat3 inverse(mat3 m)
|
||||
{
|
||||
float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];
|
||||
float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];
|
||||
float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];
|
||||
|
||||
float b01 = a22 * a11 - a12 * a21;
|
||||
float b11 = -a22 * a10 + a12 * a20;
|
||||
float b21 = a21 * a10 - a11 * a20;
|
||||
|
||||
float det = a00 * b01 + a01 * b11 + a02 * b21;
|
||||
|
||||
return mat3(b01, (-a22 * a01 + a02 * a21), (a12 * a01 - a02 * a11),
|
||||
b11, (a22 * a00 - a02 * a20), (-a12 * a00 + a02 * a10),
|
||||
b21, (-a21 * a00 + a01 * a20), (a11 * a00 - a01 * a10)) / det;
|
||||
}
|
||||
|
||||
// https://github.com/glslify/glsl-transpose
|
||||
mat3 transpose(mat3 m)
|
||||
{
|
||||
return mat3(m[0][0], m[1][0], m[2][0],
|
||||
m[0][1], m[1][1], m[2][1],
|
||||
m[0][2], m[1][2], m[2][2]);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// Compute binormal from vertex normal and tangent. W component is the tangent handedness
|
||||
vec3 vertexBinormal = cross(vertexNormal, vertexTangent.xyz) * vertexTangent.w;
|
||||
|
||||
// Compute fragment normal based on normal transformations
|
||||
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
|
||||
|
||||
// Compute fragment position based on model transformations
|
||||
fragPosition = vec3(matModel * vec4(vertexPosition, 1.0));
|
||||
|
||||
//Create TBN matrix for transforming the normal map values from tangent-space to world-space
|
||||
fragNormal = normalize(normalMatrix * vertexNormal);
|
||||
|
||||
vec3 fragTangent = normalize(normalMatrix * vertexTangent.xyz);
|
||||
fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal) * fragNormal);
|
||||
|
||||
vec3 fragBinormal = normalize(normalMatrix * vertexBinormal);
|
||||
fragBinormal = cross(fragNormal, fragTangent);
|
||||
|
||||
TBN = transpose(mat3(fragTangent, fragBinormal, fragNormal));
|
||||
|
||||
fragColor = vertexColor;
|
||||
|
||||
fragTexCoord = vertexTexCoord;
|
||||
|
||||
gl_Position = mvp * vec4(vertexPosition, 1.0);
|
||||
}
|
62
examples/shaders/resources/shaders/glsl120/normalmap.fs
Normal file
62
examples/shaders/resources/shaders/glsl120/normalmap.fs
Normal file
@@ -0,0 +1,62 @@
|
||||
#version 120
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec3 fragPosition;
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec3 fragNormal; //used for when normal mapping is toggled off
|
||||
varying vec4 fragColor;
|
||||
varying mat3 TBN;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform sampler2D normalMap;
|
||||
uniform vec4 colDiffuse;
|
||||
uniform vec3 viewPos;
|
||||
|
||||
// NOTE: Add your custom variables here
|
||||
|
||||
uniform vec3 lightPos;
|
||||
uniform bool useNormalMap;
|
||||
uniform float specularExponent;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 texelColor = texture(texture0, vec2(fragTexCoord.x, fragTexCoord.y));
|
||||
vec3 specular = vec3(0.0);
|
||||
vec3 viewDir = normalize(viewPos - fragPosition);
|
||||
vec3 lightDir = normalize(lightPos - fragPosition);
|
||||
|
||||
vec3 normal;
|
||||
if (useNormalMap)
|
||||
{
|
||||
normal = texture(normalMap, vec2(fragTexCoord.x, fragTexCoord.y)).rgb;
|
||||
|
||||
//Transform normal values to the range -1.0 ... 1.0
|
||||
normal = normalize(normal * 2.0 - 1.0);
|
||||
|
||||
//Transform the normal from tangent-space to world-space for lighting calculation
|
||||
normal = normalize(normal * TBN);
|
||||
}
|
||||
else
|
||||
{
|
||||
normal = normalize(fragNormal);
|
||||
}
|
||||
|
||||
vec4 tint = colDiffuse * fragColor;
|
||||
|
||||
vec3 lightColor = vec3(1.0, 1.0, 1.0);
|
||||
float NdotL = max(dot(normal, lightDir), 0.0);
|
||||
vec3 lightDot = lightColor * NdotL;
|
||||
|
||||
float specCo = 0.0;
|
||||
|
||||
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent); // 16 refers to shine
|
||||
|
||||
specular += specCo;
|
||||
|
||||
finalColor = (texelColor * ((tint + vec4(specular, 1.0)) * vec4(lightDot, 1.0)));
|
||||
finalColor += texelColor * (vec4(1.0, 1.0, 1.0, 1.0) / 40.0) * tint;
|
||||
|
||||
// Gamma correction
|
||||
gl_FragColor = pow(finalColor, vec4(1.0 / 2.2));
|
||||
}
|
76
examples/shaders/resources/shaders/glsl120/normalmap.vs
Normal file
76
examples/shaders/resources/shaders/glsl120/normalmap.vs
Normal file
@@ -0,0 +1,76 @@
|
||||
#version 120
|
||||
|
||||
// Input vertex attributes
|
||||
attribute vec3 vertexPosition;
|
||||
attribute vec2 vertexTexCoord;
|
||||
attribute vec3 vertexNormal;
|
||||
attribute vec4 vertexTangent;
|
||||
attribute vec4 vertexColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform mat4 mvp;
|
||||
uniform mat4 matModel;
|
||||
|
||||
// Output vertex attributes (to fragment shader)
|
||||
varying vec3 fragPosition;
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec3 fragNormal; //used for when normal mapping is toggled off
|
||||
varying vec4 fragColor;
|
||||
varying mat3 TBN;
|
||||
|
||||
// NOTE: Add your custom variables here
|
||||
|
||||
// https://github.com/glslify/glsl-inverse
|
||||
mat3 inverse(mat3 m)
|
||||
{
|
||||
float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];
|
||||
float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];
|
||||
float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];
|
||||
|
||||
float b01 = a22 * a11 - a12 * a21;
|
||||
float b11 = -a22 * a10 + a12 * a20;
|
||||
float b21 = a21 * a10 - a11 * a20;
|
||||
|
||||
float det = a00 * b01 + a01 * b11 + a02 * b21;
|
||||
|
||||
return mat3(b01, (-a22 * a01 + a02 * a21), (a12 * a01 - a02 * a11),
|
||||
b11, (a22 * a00 - a02 * a20), (-a12 * a00 + a02 * a10),
|
||||
b21, (-a21 * a00 + a01 * a20), (a11 * a00 - a01 * a10)) / det;
|
||||
}
|
||||
|
||||
// https://github.com/glslify/glsl-transpose
|
||||
mat3 transpose(mat3 m)
|
||||
{
|
||||
return mat3(m[0][0], m[1][0], m[2][0],
|
||||
m[0][1], m[1][1], m[2][1],
|
||||
m[0][2], m[1][2], m[2][2]);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// Compute binormal from vertex normal and tangent. W component is the tangent handedness
|
||||
vec3 vertexBinormal = cross(vertexNormal, vertexTangent.xyz) * vertexTangent.w;
|
||||
|
||||
// Compute fragment normal based on normal transformations
|
||||
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
|
||||
|
||||
// Compute fragment position based on model transformations
|
||||
fragPosition = vec3(matModel * vec4(vertexPosition, 1.0));
|
||||
|
||||
//Create TBN matrix for transforming the normal map values from tangent-space to world-space
|
||||
fragNormal = normalize(normalMatrix * vertexNormal);
|
||||
|
||||
vec3 fragTangent = normalize(normalMatrix * vertexTangent.xyz);
|
||||
fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal) * fragNormal);
|
||||
|
||||
vec3 fragBinormal = normalize(normalMatrix * vertexBinormal);
|
||||
fragBinormal = cross(fragNormal, fragTangent);
|
||||
|
||||
TBN = transpose(mat3(fragTangent, fragBinormal, fragNormal));
|
||||
|
||||
fragColor = vertexColor;
|
||||
|
||||
fragTexCoord = vertexTexCoord;
|
||||
|
||||
gl_Position = mvp * vec4(vertexPosition, 1.0);
|
||||
}
|
67
examples/shaders/resources/shaders/glsl330/normalmap.fs
Normal file
67
examples/shaders/resources/shaders/glsl330/normalmap.fs
Normal file
@@ -0,0 +1,67 @@
|
||||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec3 fragPosition;
|
||||
in vec2 fragTexCoord;
|
||||
in vec3 fragNormal; //used for when normal mapping is toggled off
|
||||
in vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform sampler2D normalMap;
|
||||
uniform vec4 colDiffuse;
|
||||
|
||||
uniform vec3 viewPos;
|
||||
uniform vec4 tintColor;
|
||||
|
||||
uniform vec3 lightPos;
|
||||
uniform bool useNormalMap;
|
||||
uniform float specularExponent;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
in mat3 TBN;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 texelColor = texture(texture0, vec2(fragTexCoord.x, fragTexCoord.y));
|
||||
vec3 specular = vec3(0.0);
|
||||
vec3 viewDir = normalize(viewPos - fragPosition);
|
||||
vec3 lightDir = normalize(lightPos - fragPosition);
|
||||
|
||||
vec3 normal;
|
||||
if (useNormalMap)
|
||||
{
|
||||
normal = texture(normalMap, vec2(fragTexCoord.x, fragTexCoord.y)).rgb;
|
||||
|
||||
//Transform normal values to the range -1.0 ... 1.0
|
||||
normal = normalize(normal * 2.0 - 1.0);
|
||||
|
||||
//Transform the normal from tangent-space to world-space for lighting calculation
|
||||
normal = normalize(normal * TBN);
|
||||
}
|
||||
else
|
||||
{
|
||||
normal = normalize(fragNormal);
|
||||
}
|
||||
|
||||
vec4 tint = colDiffuse * fragColor;
|
||||
|
||||
vec3 lightColor = vec3(1.0, 1.0, 1.0);
|
||||
float NdotL = max(dot(normal, lightDir), 0.0);
|
||||
vec3 lightDot = lightColor * NdotL;
|
||||
|
||||
float specCo = 0.0;
|
||||
|
||||
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent); // 16 refers to shine
|
||||
|
||||
specular += specCo;
|
||||
|
||||
finalColor = (texelColor * ((tint + vec4(specular, 1.0)) * vec4(lightDot, 1.0)));
|
||||
finalColor += texelColor * (vec4(1.0, 1.0, 1.0, 1.0) / 40.0) * tint;
|
||||
|
||||
// Gamma correction
|
||||
finalColor = pow(finalColor, vec4(1.0 / 2.2));
|
||||
//finalColor = vec4(normal, 1.0);
|
||||
}
|
48
examples/shaders/resources/shaders/glsl330/normalmap.vs
Normal file
48
examples/shaders/resources/shaders/glsl330/normalmap.vs
Normal file
@@ -0,0 +1,48 @@
|
||||
#version 330
|
||||
|
||||
// Input vertex attributes
|
||||
in vec3 vertexPosition;
|
||||
in vec2 vertexTexCoord;
|
||||
in vec3 vertexNormal;
|
||||
in vec4 vertexTangent;
|
||||
in vec4 vertexColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform mat4 mvp;
|
||||
uniform mat4 matModel;
|
||||
|
||||
// Output vertex attributes (to fragment shader)
|
||||
out vec3 fragPosition;
|
||||
out vec2 fragTexCoord;
|
||||
out vec3 fragNormal; //used for when normal mapping is toggled off
|
||||
out vec4 fragColor;
|
||||
out mat3 TBN;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Compute binormal from vertex normal and tangent. W component is the tangent handedness
|
||||
vec3 vertexBinormal = cross(vertexNormal, vertexTangent.xyz) * vertexTangent.w;
|
||||
|
||||
// Compute fragment normal based on normal transformations
|
||||
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
|
||||
|
||||
// Compute fragment position based on model transformations
|
||||
fragPosition = vec3(matModel * vec4(vertexPosition, 1.0));
|
||||
|
||||
//Create TBN matrix for transforming the normal map values from tangent-space to world-space
|
||||
fragNormal = normalize(normalMatrix * vertexNormal);
|
||||
|
||||
vec3 fragTangent = normalize(normalMatrix * vertexTangent.xyz);
|
||||
fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal) * fragNormal);
|
||||
|
||||
vec3 fragBinormal = normalize(normalMatrix * vertexBinormal);
|
||||
fragBinormal = cross(fragNormal, fragTangent);
|
||||
|
||||
TBN = transpose(mat3(fragTangent, fragBinormal, fragNormal));
|
||||
|
||||
fragColor = vertexColor;
|
||||
|
||||
fragTexCoord = vertexTexCoord;
|
||||
|
||||
gl_Position = mvp * vec4(vertexPosition, 1.0);
|
||||
}
|
BIN
examples/shaders/resources/tiles_diffuse.png
Normal file
BIN
examples/shaders/resources/tiles_diffuse.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 528 KiB |
BIN
examples/shaders/resources/tiles_normal.png
Normal file
BIN
examples/shaders/resources/tiles_normal.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 663 KiB |
170
examples/shaders/shaders_normalmap.c
Normal file
170
examples/shaders/shaders_normalmap.c
Normal file
@@ -0,0 +1,170 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shaders] example - normalmap
|
||||
*
|
||||
* Example complexity rating: [★★★★] 4/4
|
||||
*
|
||||
* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
|
||||
* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version.
|
||||
*
|
||||
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
||||
*
|
||||
* Example contributed by Jeremy Montgomery (@Sir_Irk) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2025-2025 Jeremy Montgomery (@Sir_Irk) and Ramon Santamaria (@raysan5)
|
||||
*k
|
||||
********************************************************************************************/
|
||||
|
||||
#include <raylib.h>
|
||||
#include <raymath.h>
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#define GLSL_VERSION 330
|
||||
#else // PLATFORM_ANDROID, PLATFORM_WEB
|
||||
#define GLSL_VERSION 100
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
||||
InitWindow(800, 450, "Normal Map");
|
||||
|
||||
Camera camera = {0};
|
||||
camera.position = (Vector3){0.0f, 2.0f, -4.0f};
|
||||
camera.target = (Vector3){0.0f, 0.0f, 0.0f};
|
||||
camera.up = (Vector3){0.0f, 1.0f, 0.0f};
|
||||
camera.fovy = 45.0f;
|
||||
camera.projection = CAMERA_PERSPECTIVE;
|
||||
|
||||
// Load basic normal map lighting shader
|
||||
Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/normalmap.vs", GLSL_VERSION),
|
||||
TextFormat("resources/shaders/glsl%i/normalmap.fs", GLSL_VERSION));
|
||||
|
||||
// Get some required shader locations
|
||||
shader.locs[SHADER_LOC_MAP_NORMAL] = GetShaderLocation(shader, "normalMap");
|
||||
shader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(shader, "viewPos");
|
||||
// NOTE: "matModel" location name is automatically assigned on shader loading,
|
||||
// no need to get the location again if using that uniform name
|
||||
// shader.locs[SHADER_LOC_MATRIX_MODEL] = GetShaderLocation(shader, "matModel");
|
||||
|
||||
// This example uses just 1 point light.
|
||||
Vector3 lightPosition = {0.0f, 1.0f, 0.0f};
|
||||
int lightPosLoc = GetShaderLocation(shader, "lightPos");
|
||||
|
||||
// Load a plane model that has proper normals and tangents
|
||||
Model plane = LoadModel("resources/models/plane.glb");
|
||||
|
||||
// Set the plane model's shader and texture maps
|
||||
plane.materials[0].shader = shader;
|
||||
plane.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = LoadTexture("resources/tiles_diffuse.png");
|
||||
plane.materials[0].maps[MATERIAL_MAP_NORMAL].texture = LoadTexture("resources/tiles_normal.png");
|
||||
|
||||
// Generate Mipmaps and use TRILINEAR filtering to help with texture aliasing
|
||||
GenTextureMipmaps(&plane.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture);
|
||||
GenTextureMipmaps(&plane.materials[0].maps[MATERIAL_MAP_NORMAL].texture);
|
||||
|
||||
SetTextureFilter(plane.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture, TEXTURE_FILTER_TRILINEAR);
|
||||
SetTextureFilter(plane.materials[0].maps[MATERIAL_MAP_NORMAL].texture, TEXTURE_FILTER_TRILINEAR);
|
||||
|
||||
// Specular exponent AKA shininess of the material.
|
||||
float specularExponent = 8.0f;
|
||||
int specularExponentLoc = GetShaderLocation(shader, "specularExponent");
|
||||
|
||||
// Allow toggling the normal map on and off for comparison purposes
|
||||
int useNormalMap = 1;
|
||||
int useNormalMapLoc = GetShaderLocation(shader, "useNormalMap");
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Move the light around on the X and Z axis using WASD keys
|
||||
Vector3 direction = {0};
|
||||
if (IsKeyDown(KEY_W)) direction = Vector3Add(direction, (Vector3){0.0f, 0.0f, 1.0f});
|
||||
if (IsKeyDown(KEY_S)) direction = Vector3Add(direction, (Vector3){0.0f, 0.0f, -1.0f});
|
||||
if (IsKeyDown(KEY_D)) direction = Vector3Add(direction, (Vector3){-1.0f, 0.0f, 0.0f});
|
||||
if (IsKeyDown(KEY_A)) direction = Vector3Add(direction, (Vector3){1.0f, 0.0f, 0.0f});
|
||||
|
||||
direction = Vector3Normalize(direction);
|
||||
lightPosition = Vector3Add(lightPosition, Vector3Scale(direction, GetFrameTime() * 3.0f));
|
||||
|
||||
// Increase/Decrease the specular exponent(shininess)
|
||||
if (IsKeyDown(KEY_UP)) specularExponent = Clamp(specularExponent + 40.0f * GetFrameTime(), 2.0f, 128.0f);
|
||||
if (IsKeyDown(KEY_DOWN)) specularExponent = Clamp(specularExponent - 40.0f * GetFrameTime(), 2.0f, 128.0f);
|
||||
|
||||
// Toggle normal map on and off
|
||||
if (IsKeyPressed(KEY_N)) useNormalMap = !useNormalMap;
|
||||
|
||||
// Spin plane model at a constant rate
|
||||
plane.transform = MatrixRotateY(GetTime() * 0.5f);
|
||||
|
||||
// Update shader values
|
||||
float lightPos[3] = {lightPosition.x, lightPosition.y, lightPosition.z};
|
||||
SetShaderValue(shader, lightPosLoc, lightPos, SHADER_UNIFORM_VEC3);
|
||||
|
||||
float camPos[3] = {camera.position.x, camera.position.y, camera.position.z};
|
||||
SetShaderValue(shader, shader.locs[SHADER_LOC_VECTOR_VIEW], camPos, SHADER_UNIFORM_VEC3);
|
||||
|
||||
SetShaderValue(shader, specularExponentLoc, &specularExponent, SHADER_UNIFORM_FLOAT);
|
||||
|
||||
SetShaderValue(shader, useNormalMapLoc, &useNormalMap, SHADER_UNIFORM_INT);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode3D(camera);
|
||||
|
||||
BeginShaderMode(shader);
|
||||
|
||||
DrawModel(plane, Vector3Zero(), 2.0f, WHITE);
|
||||
|
||||
EndShaderMode();
|
||||
|
||||
//Draw sphere to show light position
|
||||
DrawSphereWires(lightPosition, 0.2f, 8, 8, ORANGE);
|
||||
|
||||
EndMode3D();
|
||||
|
||||
Color textColor = (useNormalMap) ? DARKGREEN : RED;
|
||||
const char *toggleStr = (useNormalMap) ? "On" : "Off";
|
||||
DrawText(TextFormat("Use key [N] to toggle normal map: %s", toggleStr), 10, 30, 20, textColor);
|
||||
|
||||
int yOffset = 24;
|
||||
DrawText("Use keys [W][A][S][D] to move the light", 10, 30 + yOffset * 1, 20, BLACK);
|
||||
DrawText("Use keys [Up][Down] to change specular exponent", 10, 30 + yOffset * 2, 20, BLACK);
|
||||
DrawText(TextFormat("Specular Exponent: %.2f", specularExponent), 10, 30 + yOffset * 3, 20, BLUE);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//--------------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadShader(shader);
|
||||
UnloadModel(plane);
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
BIN
examples/shaders/shaders_normalmap.png
Normal file
BIN
examples/shaders/shaders_normalmap.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 262 KiB |
4
src/external/jar_mod.h
vendored
4
src/external/jar_mod.h
vendored
@@ -1130,7 +1130,7 @@ static bool jar_mod_load( jar_mod_context_t * modctx, void * mod_data, int mod_d
|
||||
{
|
||||
if( modctx )
|
||||
{
|
||||
memcopy(&(modctx->song.title),modmemory,1084);
|
||||
memcopy(&(modctx->song), modmemory, 1084);
|
||||
|
||||
i = 0;
|
||||
modctx->number_of_channels = 0;
|
||||
@@ -1593,4 +1593,4 @@ void jar_mod_seek_start(jar_mod_context_t * ctx)
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#endif //end of header file
|
||||
#endif //end of header file
|
||||
|
@@ -278,6 +278,7 @@ int main(int argc, char *argv[])
|
||||
else if (strcmp(argv[1], "rename") == 0)
|
||||
{
|
||||
if (argc == 2) LOG("WARNING: No filename provided to be renamed\n");
|
||||
else if (argc == 3) LOG("WARNING: No new filename provided to be renamed\n");
|
||||
else if (argc > 4) LOG("WARNING: Too many arguments provided\n");
|
||||
else
|
||||
{
|
||||
@@ -285,11 +286,29 @@ int main(int argc, char *argv[])
|
||||
char *exColInfo = LoadFileText(exCollectionFilePath);
|
||||
if (TextFindIndex(exColInfo, argv[2]) != -1) // Example in the collection
|
||||
{
|
||||
strcpy(exName, argv[2]); // Register example name
|
||||
strncpy(exCategory, exName, TextFindIndex(exName, "_"));
|
||||
strcpy(exRename, argv[3]);
|
||||
strncpy(exRecategory, exRename, TextFindIndex(exRename, "_"));
|
||||
opCode = OP_RENAME;
|
||||
// Security checks for new file name to verify category is included
|
||||
int newCatIndex = TextFindIndex(argv[3], "_");
|
||||
if (newCatIndex > 3)
|
||||
{
|
||||
char cat[12] = { 0 };
|
||||
strncpy(cat, argv[3], newCatIndex);
|
||||
bool newCatFound = false;
|
||||
for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES; i++)
|
||||
{
|
||||
if (TextIsEqual(cat, exCategories[i])) { newCatFound = true; break; }
|
||||
}
|
||||
|
||||
if (newCatFound)
|
||||
{
|
||||
strcpy(exName, argv[2]); // Register example name
|
||||
strncpy(exCategory, exName, TextFindIndex(exName, "_"));
|
||||
strcpy(exRename, argv[3]);
|
||||
strncpy(exRecategory, exRename, TextFindIndex(exRename, "_"));
|
||||
opCode = OP_RENAME;
|
||||
}
|
||||
else LOG("WARNING: Example new category is not valid\n");
|
||||
}
|
||||
else LOG("WARNING: Example new name does not include category\n");
|
||||
}
|
||||
else LOG("WARNING: RENAME: Example not available in the collection\n");
|
||||
UnloadFileText(exColInfo);
|
||||
|
Reference in New Issue
Block a user