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;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
rlDeleteTextures(material.texDiffuse.id);
|
||||
|
30
src/raylib.h
30
src/raylib.h
@ -422,13 +422,38 @@ typedef struct Material {
|
||||
float normalDepth; // Normal map depth
|
||||
} Material;
|
||||
|
||||
// 3d Model type
|
||||
// Model type
|
||||
typedef struct Model {
|
||||
Mesh mesh; // Vertex data buffers (RAM and VRAM)
|
||||
Matrix transform; // Local transform matrix
|
||||
Material material; // Shader and textures data
|
||||
} 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)
|
||||
typedef struct Ray {
|
||||
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)
|
||||
|
||||
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)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
165
src/rlgl.c
165
src/rlgl.c
@ -72,6 +72,8 @@
|
||||
#define TEMP_VERTEX_BUFFER_SIZE 4096 // Temporal Vertex Buffer (required for vertex-transformations)
|
||||
// NOTE: Every vertex are 3 floats (12 bytes)
|
||||
|
||||
#define MAX_LIGHTS 8 // Max lights supported by standard shader
|
||||
|
||||
#ifndef GL_SHADING_LANGUAGE_VERSION
|
||||
#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
|
||||
#endif
|
||||
@ -199,6 +201,10 @@ static bool texCompETC1Supported = false; // ETC1 texture compression support
|
||||
static bool texCompETC2Supported = false; // ETC2/EAC texture compression support
|
||||
static bool texCompPVRTSupported = false; // PVR 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
|
||||
|
||||
// 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 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 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 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);
|
||||
#endif
|
||||
|
||||
@ -1749,10 +1758,18 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
|
||||
// Send combined model-view-projection matrix to shader
|
||||
glUniformMatrix4fv(material.shader.mvpLoc, 1, false, MatrixToFloat(matMVP));
|
||||
|
||||
// Apply color tinting (material.colDiffuse)
|
||||
// NOTE: Just update one uniform on fragment shader
|
||||
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);
|
||||
// Setup shader uniforms for material related data
|
||||
// TODO: Check if using standard shader to get location points
|
||||
|
||||
// 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)
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
@ -1764,6 +1781,9 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, material.texNormal.id);
|
||||
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))
|
||||
@ -1771,8 +1791,14 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, material.texSpecular.id);
|
||||
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)
|
||||
{
|
||||
glBindVertexArray(mesh.vaoId);
|
||||
@ -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
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -2415,6 +2490,32 @@ static Shader LoadDefaultShader(void)
|
||||
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
|
||||
// NOTE: If any location is not found, loc point becomes -1
|
||||
static void LoadDefaultShaderLocations(Shader *shader)
|
||||
@ -2900,6 +3001,62 @@ static void UnloadDefaultBuffers(void)
|
||||
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
|
||||
// NOTE: text chars array should be freed manually
|
||||
static char *ReadTextFile(const char *fileName)
|
||||
|
25
src/rlgl.h
25
src/rlgl.h
@ -210,6 +210,28 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
|
||||
float normalDepth;
|
||||
} 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)
|
||||
typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode;
|
||||
#endif
|
||||
@ -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 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
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
Loading…
Reference in New Issue
Block a user