Add lighting system -IN PROGRESS-
Improved materials
This commit is contained in:
parent
af890cf210
commit
dcf5f45f68
12
src/models.c
12
src/models.c
@ -732,6 +732,18 @@ Material LoadDefaultMaterial(void)
|
|||||||
return material;
|
return material;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load standard material (uses standard models shader)
|
||||||
|
// NOTE: Standard shader supports multiple maps and lights
|
||||||
|
Material LoadStandardMaterial(void)
|
||||||
|
{
|
||||||
|
Material material = LoadDefaultMaterial();
|
||||||
|
|
||||||
|
//material.shader = GetStandardShader();
|
||||||
|
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unload material from memory
|
||||||
void UnloadMaterial(Material material)
|
void UnloadMaterial(Material material)
|
||||||
{
|
{
|
||||||
rlDeleteTextures(material.texDiffuse.id);
|
rlDeleteTextures(material.texDiffuse.id);
|
||||||
|
30
src/raylib.h
30
src/raylib.h
@ -422,13 +422,38 @@ typedef struct Material {
|
|||||||
float normalDepth; // Normal map depth
|
float normalDepth; // Normal map depth
|
||||||
} Material;
|
} Material;
|
||||||
|
|
||||||
// 3d Model type
|
// Model type
|
||||||
typedef struct Model {
|
typedef struct Model {
|
||||||
Mesh mesh; // Vertex data buffers (RAM and VRAM)
|
Mesh mesh; // Vertex data buffers (RAM and VRAM)
|
||||||
Matrix transform; // Local transform matrix
|
Matrix transform; // Local transform matrix
|
||||||
Material material; // Shader and textures data
|
Material material; // Shader and textures data
|
||||||
} Model;
|
} Model;
|
||||||
|
|
||||||
|
// Light type
|
||||||
|
// TODO: Review contained data to support different light types and features
|
||||||
|
typedef struct LightData {
|
||||||
|
int id;
|
||||||
|
int type; // LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT
|
||||||
|
bool enabled;
|
||||||
|
|
||||||
|
Vector3 position;
|
||||||
|
Vector3 direction; // Used on LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction)
|
||||||
|
float attenuation; // Lost of light intensity with distance (use radius?)
|
||||||
|
|
||||||
|
Color diffuse; // Use Vector3 diffuse (including intensities)?
|
||||||
|
float intensity;
|
||||||
|
|
||||||
|
Color specular;
|
||||||
|
//float specFactor; // Specular intensity ?
|
||||||
|
|
||||||
|
//Color ambient; // Required?
|
||||||
|
|
||||||
|
float coneAngle; // SpotLight
|
||||||
|
} LightData, *Light;
|
||||||
|
|
||||||
|
// Light types
|
||||||
|
typedef enum { LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT } LightType;
|
||||||
|
|
||||||
// Ray type (useful for raycast)
|
// Ray type (useful for raycast)
|
||||||
typedef struct Ray {
|
typedef struct Ray {
|
||||||
Vector3 position;
|
Vector3 position;
|
||||||
@ -849,6 +874,9 @@ void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // S
|
|||||||
|
|
||||||
void SetBlendMode(int mode); // Set blending mode (alpha, additive, multiplied)
|
void SetBlendMode(int mode); // Set blending mode (alpha, additive, multiplied)
|
||||||
|
|
||||||
|
Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool
|
||||||
|
void DestroyLight(Light light); // Destroy a light and take it out of the list
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Physics System Functions (Module: physac)
|
// Physics System Functions (Module: physac)
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
167
src/rlgl.c
167
src/rlgl.c
@ -71,6 +71,8 @@
|
|||||||
#define MAX_DRAWS_BY_TEXTURE 256 // Draws are organized by texture changes
|
#define MAX_DRAWS_BY_TEXTURE 256 // Draws are organized by texture changes
|
||||||
#define TEMP_VERTEX_BUFFER_SIZE 4096 // Temporal Vertex Buffer (required for vertex-transformations)
|
#define TEMP_VERTEX_BUFFER_SIZE 4096 // Temporal Vertex Buffer (required for vertex-transformations)
|
||||||
// NOTE: Every vertex are 3 floats (12 bytes)
|
// NOTE: Every vertex are 3 floats (12 bytes)
|
||||||
|
|
||||||
|
#define MAX_LIGHTS 8 // Max lights supported by standard shader
|
||||||
|
|
||||||
#ifndef GL_SHADING_LANGUAGE_VERSION
|
#ifndef GL_SHADING_LANGUAGE_VERSION
|
||||||
#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
|
#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
|
||||||
@ -199,6 +201,10 @@ 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
|
||||||
|
|
||||||
|
// Lighting data
|
||||||
|
static Light lights[MAX_LIGHTS]; // Lights pool
|
||||||
|
static int lightsCount; // Counts current enabled physic objects
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Compressed textures support flags
|
// Compressed textures support flags
|
||||||
@ -227,6 +233,7 @@ static void LoadCompressedTexture(unsigned char *data, int width, int height, in
|
|||||||
static unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr); // Load custom shader strings and return program id
|
static unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr); // Load custom shader strings and return program id
|
||||||
|
|
||||||
static Shader LoadDefaultShader(void); // Load default shader (just vertex positioning and texture coloring)
|
static Shader LoadDefaultShader(void); // Load default shader (just vertex positioning and texture coloring)
|
||||||
|
static Shader LoadStandardShader(void); // Load standard shader (support materials and lighting)
|
||||||
static void LoadDefaultShaderLocations(Shader *shader); // Bind default shader locations (attributes and uniforms)
|
static void LoadDefaultShaderLocations(Shader *shader); // Bind default shader locations (attributes and uniforms)
|
||||||
static void UnloadDefaultShader(void); // Unload default shader
|
static void UnloadDefaultShader(void); // Unload default shader
|
||||||
|
|
||||||
@ -235,6 +242,8 @@ static void UpdateDefaultBuffers(void); // Update default internal buffers (
|
|||||||
static void DrawDefaultBuffers(void); // Draw default internal buffers vertex data
|
static void DrawDefaultBuffers(void); // Draw default internal buffers vertex data
|
||||||
static void UnloadDefaultBuffers(void); // Unload default internal buffers vertex data from CPU and GPU
|
static void UnloadDefaultBuffers(void); // Unload default internal buffers vertex data from CPU and GPU
|
||||||
|
|
||||||
|
static void SetShaderLights(Shader shader); // Sets shader uniform values for lights array
|
||||||
|
|
||||||
static char *ReadTextFile(const char *fileName);
|
static char *ReadTextFile(const char *fileName);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1749,11 +1758,19 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
|
|||||||
// Send combined model-view-projection matrix to shader
|
// Send combined model-view-projection matrix to shader
|
||||||
glUniformMatrix4fv(material.shader.mvpLoc, 1, false, MatrixToFloat(matMVP));
|
glUniformMatrix4fv(material.shader.mvpLoc, 1, false, MatrixToFloat(matMVP));
|
||||||
|
|
||||||
// Apply color tinting (material.colDiffuse)
|
// Setup shader uniforms for material related data
|
||||||
// NOTE: Just update one uniform on fragment shader
|
// TODO: Check if using standard shader to get location points
|
||||||
float vColor[4] = { (float)material.colDiffuse.r/255, (float)material.colDiffuse.g/255, (float)material.colDiffuse.b/255, (float)material.colDiffuse.a/255 };
|
|
||||||
glUniform4fv(material.shader.tintColorLoc, 1, vColor);
|
// Upload to shader material.colDiffuse
|
||||||
|
float vColorDiffuse[4] = { (float)material.colDiffuse.r/255, (float)material.colDiffuse.g/255, (float)material.colDiffuse.b/255, (float)material.colDiffuse.a/255 };
|
||||||
|
glUniform4fv(material.shader.tintColorLoc, 1, vColorDiffuse);
|
||||||
|
|
||||||
|
// TODO: Upload to shader material.colAmbient
|
||||||
|
// glUniform4f(???, (float)material.colAmbient.r/255, (float)material.colAmbient.g/255, (float)material.colAmbient.b/255, (float)material.colAmbient.a/255);
|
||||||
|
|
||||||
|
// TODO: Upload to shader material.colSpecular
|
||||||
|
// glUniform4f(???, (float)material.colSpecular.r/255, (float)material.colSpecular.g/255, (float)material.colSpecular.b/255, (float)material.colSpecular.a/255);
|
||||||
|
|
||||||
// Set shader textures (diffuse, normal, specular)
|
// Set shader textures (diffuse, normal, specular)
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, material.texDiffuse.id);
|
glBindTexture(GL_TEXTURE_2D, material.texDiffuse.id);
|
||||||
@ -1764,6 +1781,9 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
|
|||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_2D, material.texNormal.id);
|
glBindTexture(GL_TEXTURE_2D, material.texNormal.id);
|
||||||
glUniform1i(material.shader.mapNormalLoc, 1); // Texture fits in active texture unit 1
|
glUniform1i(material.shader.mapNormalLoc, 1); // Texture fits in active texture unit 1
|
||||||
|
|
||||||
|
// TODO: Upload to shader normalDepth
|
||||||
|
//glUniform1f(???, material.normalDepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((material.texSpecular.id != 0) && (material.shader.mapSpecularLoc != -1))
|
if ((material.texSpecular.id != 0) && (material.shader.mapSpecularLoc != -1))
|
||||||
@ -1771,7 +1791,13 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
|
|||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
glBindTexture(GL_TEXTURE_2D, material.texSpecular.id);
|
glBindTexture(GL_TEXTURE_2D, material.texSpecular.id);
|
||||||
glUniform1i(material.shader.mapSpecularLoc, 2); // Texture fits in active texture unit 2
|
glUniform1i(material.shader.mapSpecularLoc, 2); // Texture fits in active texture unit 2
|
||||||
|
|
||||||
|
// TODO: Upload to shader glossiness
|
||||||
|
//glUniform1f(???, material.glossiness);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup shader uniforms for lights
|
||||||
|
SetShaderLights(material.shader);
|
||||||
|
|
||||||
if (vaoSupported)
|
if (vaoSupported)
|
||||||
{
|
{
|
||||||
@ -2198,6 +2224,55 @@ void SetBlendMode(int mode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a new light, initialize it and add to pool
|
||||||
|
// TODO: Review creation parameters (only generic ones)
|
||||||
|
Light CreateLight(int type, Vector3 position, Color diffuse)
|
||||||
|
{
|
||||||
|
// Allocate dynamic memory
|
||||||
|
Light light = (Light)malloc(sizeof(LightData));
|
||||||
|
|
||||||
|
// Initialize light values with generic values
|
||||||
|
light->id = lightsCount;
|
||||||
|
light->type = type;
|
||||||
|
light->enabled = true;
|
||||||
|
|
||||||
|
light->position = position;
|
||||||
|
light->direction = (Vector3){ 0.0f, 0.0f, 0.0f };
|
||||||
|
light->intensity = 1.0f;
|
||||||
|
light->diffuse = diffuse;
|
||||||
|
light->specular = WHITE;
|
||||||
|
|
||||||
|
// Add new light to the array
|
||||||
|
lights[lightsCount] = light;
|
||||||
|
|
||||||
|
// Increase enabled lights count
|
||||||
|
lightsCount++;
|
||||||
|
|
||||||
|
return light;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destroy a light and take it out of the list
|
||||||
|
void DestroyLight(Light light)
|
||||||
|
{
|
||||||
|
// Free dynamic memory allocation
|
||||||
|
free(lights[light->id]);
|
||||||
|
|
||||||
|
// Remove *obj from the pointers array
|
||||||
|
for (int i = light->id; i < lightsCount; i++)
|
||||||
|
{
|
||||||
|
// Resort all the following pointers of the array
|
||||||
|
if ((i + 1) < lightsCount)
|
||||||
|
{
|
||||||
|
lights[i] = lights[i + 1];
|
||||||
|
lights[i]->id = lights[i + 1]->id;
|
||||||
|
}
|
||||||
|
else free(lights[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrease enabled physic objects count
|
||||||
|
lightsCount--;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module specific Functions Definition
|
// Module specific Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
@ -2415,6 +2490,32 @@ static Shader LoadDefaultShader(void)
|
|||||||
return shader;
|
return shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load standard shader
|
||||||
|
// NOTE: This shader supports:
|
||||||
|
// - Up to 3 different maps: diffuse, normal, specular
|
||||||
|
// - Material properties: colDiffuse, colAmbient, colSpecular, glossiness, normalDepth
|
||||||
|
// - Up to 8 lights: Point, Directional or Spot
|
||||||
|
static Shader LoadStandardShader(void)
|
||||||
|
{
|
||||||
|
Shader shader;
|
||||||
|
|
||||||
|
char *vShaderStr;
|
||||||
|
char *fShaderStr;
|
||||||
|
|
||||||
|
// TODO: Implement standard uber-shader, supporting all features (GLSL 100 / GLSL 330)
|
||||||
|
|
||||||
|
// NOTE: Shader could be quite extensive so it could be implemented in external files (standard.vs/standard.fs)
|
||||||
|
|
||||||
|
shader.id = LoadShaderProgram(vShaderStr, fShaderStr);
|
||||||
|
|
||||||
|
if (shader.id != 0) TraceLog(INFO, "[SHDR ID %i] Standard shader loaded successfully", shader.id);
|
||||||
|
else TraceLog(WARNING, "[SHDR ID %i] Standard shader could not be loaded", shader.id);
|
||||||
|
|
||||||
|
if (shader.id != 0) LoadDefaultShaderLocations(&shader); // TODO: Review locations fetching
|
||||||
|
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
// Get location handlers to for shader attributes and uniforms
|
// Get location handlers to for shader attributes and uniforms
|
||||||
// NOTE: If any location is not found, loc point becomes -1
|
// NOTE: If any location is not found, loc point becomes -1
|
||||||
static void LoadDefaultShaderLocations(Shader *shader)
|
static void LoadDefaultShaderLocations(Shader *shader)
|
||||||
@ -2900,6 +3001,62 @@ static void UnloadDefaultBuffers(void)
|
|||||||
free(quads.indices);
|
free(quads.indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sets shader uniform values for lights array
|
||||||
|
// NOTE: It would be far easier with shader UBOs but are not supported on OpenGL ES 2.0f
|
||||||
|
// TODO: Review memcpy() and parameters pass
|
||||||
|
static void SetShaderLights(Shader shader)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
// NOTE: Standard Shader must include the following data:
|
||||||
|
|
||||||
|
// Shader Light struct
|
||||||
|
struct Light {
|
||||||
|
vec3 position;
|
||||||
|
vec3 direction;
|
||||||
|
|
||||||
|
vec3 diffuse;
|
||||||
|
float intensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int maxLights = 8;
|
||||||
|
uniform int lightsCount; // Number of lights
|
||||||
|
uniform Light lights[maxLights];
|
||||||
|
*/
|
||||||
|
|
||||||
|
int locPoint;
|
||||||
|
char locName[32] = "lights[x].position\0";
|
||||||
|
|
||||||
|
glUseProgram(shader.id);
|
||||||
|
|
||||||
|
locPoint = glGetUniformLocation(shader.id, "lightsCount");
|
||||||
|
glUniform1i(locPoint, lightsCount);
|
||||||
|
|
||||||
|
for (int i = 0; i < lightsCount; i++)
|
||||||
|
{
|
||||||
|
locName[7] = '0' + i;
|
||||||
|
|
||||||
|
memcpy(&locName[10], "position\0", strlen("position\0"));
|
||||||
|
locPoint = glGetUniformLocation(shader.id, locName);
|
||||||
|
glUniform3f(locPoint, lights[i]->position.x, lights[i]->position.y, lights[i]->position.z);
|
||||||
|
|
||||||
|
memcpy(&locName[10], "direction\0", strlen("direction\0"));
|
||||||
|
locPoint = glGetUniformLocation(shader.id, locName);
|
||||||
|
glUniform3f(locPoint, lights[i]->direction.x, lights[i]->direction.y, lights[i]->direction.z);
|
||||||
|
|
||||||
|
memcpy(&locName[10], "diffuse\0", strlen("diffuse\0"));
|
||||||
|
locPoint = glGetUniformLocation(shader.id, locName);
|
||||||
|
glUniform4f(locPoint, (float)lights[i]->diffuse.r/255, (float)lights[i]->diffuse.g/255, (float)lights[i]->diffuse.b/255, (float)lights[i]->diffuse.a/255 );
|
||||||
|
|
||||||
|
memcpy(&locName[10], "intensity\0", strlen("intensity\0"));
|
||||||
|
locPoint = glGetUniformLocation(shader.id, locName);
|
||||||
|
glUniform1f(locPoint, lights[i]->intensity);
|
||||||
|
|
||||||
|
// TODO: Pass to the shader any other required data from LightData struct
|
||||||
|
}
|
||||||
|
|
||||||
|
glUseProgram(0);
|
||||||
|
}
|
||||||
|
|
||||||
// Read text data from file
|
// Read text data from file
|
||||||
// NOTE: text chars array should be freed manually
|
// NOTE: text chars array should be freed manually
|
||||||
static char *ReadTextFile(const char *fileName)
|
static char *ReadTextFile(const char *fileName)
|
||||||
|
25
src/rlgl.h
25
src/rlgl.h
@ -209,6 +209,28 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
|
|||||||
float glossiness;
|
float glossiness;
|
||||||
float normalDepth;
|
float normalDepth;
|
||||||
} Material;
|
} Material;
|
||||||
|
|
||||||
|
// Light type
|
||||||
|
// TODO: Review contained data to support different light types and features
|
||||||
|
typedef struct LightData {
|
||||||
|
int id;
|
||||||
|
int type; // LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT
|
||||||
|
bool enabled;
|
||||||
|
|
||||||
|
Vector3 position;
|
||||||
|
Vector3 direction; // Used on LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction)
|
||||||
|
float attenuation; // Lost of light intensity with distance (use radius?)
|
||||||
|
|
||||||
|
Color diffuse; // Use Vector3 diffuse (including intensities)?
|
||||||
|
float intensity;
|
||||||
|
|
||||||
|
Color specular;
|
||||||
|
//float specFactor; // Specular intensity ?
|
||||||
|
|
||||||
|
//Color ambient; // Required?
|
||||||
|
|
||||||
|
float coneAngle; // SpotLight
|
||||||
|
} LightData, *Light;
|
||||||
|
|
||||||
// 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;
|
||||||
@ -311,6 +333,9 @@ void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // S
|
|||||||
void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4)
|
void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4)
|
||||||
|
|
||||||
void SetBlendMode(int mode); // Set blending mode (alpha, additive, multiplied)
|
void SetBlendMode(int mode); // Set blending mode (alpha, additive, multiplied)
|
||||||
|
|
||||||
|
Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool
|
||||||
|
void DestroyLight(Light light); // Destroy a light and take it out of the list
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
Loading…
Reference in New Issue
Block a user