implement feature
This commit is contained in:
parent
61af8e7631
commit
3013d45de1
|
|
@ -116,6 +116,7 @@
|
||||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: 3
|
#define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: 3
|
||||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: 4
|
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: 4
|
||||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: 5
|
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: 5
|
||||||
|
#define RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCE "instanceTransform" // Bound by default to shader location: 6
|
||||||
|
|
||||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix
|
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix
|
||||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix
|
#define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix
|
||||||
|
|
|
||||||
|
|
@ -371,6 +371,7 @@ typedef struct MaterialMap {
|
||||||
// Material, includes shader and maps
|
// Material, includes shader and maps
|
||||||
typedef struct Material {
|
typedef struct Material {
|
||||||
Shader shader; // Material shader
|
Shader shader; // Material shader
|
||||||
|
Shader shaderInstanced; // Material shader
|
||||||
MaterialMap *maps; // Material maps array (MAX_MATERIAL_MAPS)
|
MaterialMap *maps; // Material maps array (MAX_MATERIAL_MAPS)
|
||||||
float params[4]; // Material generic parameters (if required)
|
float params[4]; // Material generic parameters (if required)
|
||||||
} Material;
|
} Material;
|
||||||
|
|
@ -753,6 +754,7 @@ typedef enum {
|
||||||
SHADER_LOC_VERTEX_NORMAL, // Shader location: vertex attribute: normal
|
SHADER_LOC_VERTEX_NORMAL, // Shader location: vertex attribute: normal
|
||||||
SHADER_LOC_VERTEX_TANGENT, // Shader location: vertex attribute: tangent
|
SHADER_LOC_VERTEX_TANGENT, // Shader location: vertex attribute: tangent
|
||||||
SHADER_LOC_VERTEX_COLOR, // Shader location: vertex attribute: color
|
SHADER_LOC_VERTEX_COLOR, // Shader location: vertex attribute: color
|
||||||
|
SHADER_LOC_VERTEX_INSTANCE, // Shader location: vertex attribute: instance (transform)
|
||||||
SHADER_LOC_MATRIX_MVP, // Shader location: matrix uniform: model-view-projection
|
SHADER_LOC_MATRIX_MVP, // Shader location: matrix uniform: model-view-projection
|
||||||
SHADER_LOC_MATRIX_VIEW, // Shader location: matrix uniform: view (camera transform)
|
SHADER_LOC_MATRIX_VIEW, // Shader location: matrix uniform: view (camera transform)
|
||||||
SHADER_LOC_MATRIX_PROJECTION, // Shader location: matrix uniform: projection
|
SHADER_LOC_MATRIX_PROJECTION, // Shader location: matrix uniform: projection
|
||||||
|
|
|
||||||
|
|
@ -896,6 +896,7 @@ Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode)
|
||||||
shader.locs[SHADER_LOC_VERTEX_NORMAL] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL);
|
shader.locs[SHADER_LOC_VERTEX_NORMAL] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL);
|
||||||
shader.locs[SHADER_LOC_VERTEX_TANGENT] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT);
|
shader.locs[SHADER_LOC_VERTEX_TANGENT] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT);
|
||||||
shader.locs[SHADER_LOC_VERTEX_COLOR] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR);
|
shader.locs[SHADER_LOC_VERTEX_COLOR] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR);
|
||||||
|
shader.locs[SHADER_LOC_VERTEX_INSTANCE] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCE);
|
||||||
|
|
||||||
// Get handles to GLSL uniform locations (vertex shader)
|
// Get handles to GLSL uniform locations (vertex shader)
|
||||||
shader.locs[SHADER_LOC_MATRIX_MVP] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_UNIFORM_NAME_MVP);
|
shader.locs[SHADER_LOC_MATRIX_MVP] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_UNIFORM_NAME_MVP);
|
||||||
|
|
@ -931,6 +932,7 @@ bool IsShaderReady(Shader shader)
|
||||||
// shader.locs[SHADER_LOC_VERTEX_NORMAL]
|
// shader.locs[SHADER_LOC_VERTEX_NORMAL]
|
||||||
// shader.locs[SHADER_LOC_VERTEX_TANGENT]
|
// shader.locs[SHADER_LOC_VERTEX_TANGENT]
|
||||||
// shader.locs[SHADER_LOC_VERTEX_COLOR] // Set by default internal shader
|
// shader.locs[SHADER_LOC_VERTEX_COLOR] // Set by default internal shader
|
||||||
|
// shader.locs[SHADER_LOC_VERTEX_INSTANCE] // Set by default internal shader instanced
|
||||||
|
|
||||||
// Vertex shader uniform locations (default)
|
// Vertex shader uniform locations (default)
|
||||||
// shader.locs[SHADER_LOC_MATRIX_MVP] // Set by default internal shader
|
// shader.locs[SHADER_LOC_MATRIX_MVP] // Set by default internal shader
|
||||||
|
|
|
||||||
161
src/rlgl.h
161
src/rlgl.h
|
|
@ -467,6 +467,7 @@ typedef enum {
|
||||||
RL_SHADER_LOC_VERTEX_NORMAL, // Shader location: vertex attribute: normal
|
RL_SHADER_LOC_VERTEX_NORMAL, // Shader location: vertex attribute: normal
|
||||||
RL_SHADER_LOC_VERTEX_TANGENT, // Shader location: vertex attribute: tangent
|
RL_SHADER_LOC_VERTEX_TANGENT, // Shader location: vertex attribute: tangent
|
||||||
RL_SHADER_LOC_VERTEX_COLOR, // Shader location: vertex attribute: color
|
RL_SHADER_LOC_VERTEX_COLOR, // Shader location: vertex attribute: color
|
||||||
|
RL_SHADER_LOC_VERTEX_INSTANCE, // Shader location: vertex attribute: instance (transform)
|
||||||
RL_SHADER_LOC_MATRIX_MVP, // Shader location: matrix uniform: model-view-projection
|
RL_SHADER_LOC_MATRIX_MVP, // Shader location: matrix uniform: model-view-projection
|
||||||
RL_SHADER_LOC_MATRIX_VIEW, // Shader location: matrix uniform: view (camera transform)
|
RL_SHADER_LOC_MATRIX_VIEW, // Shader location: matrix uniform: view (camera transform)
|
||||||
RL_SHADER_LOC_MATRIX_PROJECTION, // Shader location: matrix uniform: projection
|
RL_SHADER_LOC_MATRIX_PROJECTION, // Shader location: matrix uniform: projection
|
||||||
|
|
@ -664,6 +665,8 @@ RLAPI int rlGetFramebufferHeight(void); // Get default framebuff
|
||||||
RLAPI unsigned int rlGetTextureIdDefault(void); // Get default texture id
|
RLAPI unsigned int rlGetTextureIdDefault(void); // Get default texture id
|
||||||
RLAPI unsigned int rlGetShaderIdDefault(void); // Get default shader id
|
RLAPI unsigned int rlGetShaderIdDefault(void); // Get default shader id
|
||||||
RLAPI int *rlGetShaderLocsDefault(void); // Get default shader locations
|
RLAPI int *rlGetShaderLocsDefault(void); // Get default shader locations
|
||||||
|
RLAPI unsigned int rlGetShaderInstancedIdDefault(void); // Get default shader instanced id
|
||||||
|
RLAPI int *rlGetShaderInstancedLocsDefault(void); // Get default shader instanced locations
|
||||||
|
|
||||||
// Render batch management
|
// Render batch management
|
||||||
// NOTE: rlgl provides a default render batch to behave like OpenGL 1.1 immediate mode
|
// NOTE: rlgl provides a default render batch to behave like OpenGL 1.1 immediate mode
|
||||||
|
|
@ -978,6 +981,10 @@ typedef struct rlglData {
|
||||||
unsigned int defaultFShaderId; // Default fragment shader id (used by default shader program)
|
unsigned int defaultFShaderId; // Default fragment shader id (used by default shader program)
|
||||||
unsigned int defaultShaderId; // Default shader program id, supports vertex color and diffuse texture
|
unsigned int defaultShaderId; // Default shader program id, supports vertex color and diffuse texture
|
||||||
int *defaultShaderLocs; // Default shader locations pointer to be used on rendering
|
int *defaultShaderLocs; // Default shader locations pointer to be used on rendering
|
||||||
|
unsigned int defaultVShaderInstancedId; // Default vertex shader instanced id (used by default shader instanced program)
|
||||||
|
unsigned int defaultFShaderInstancedId; // Default fragment shader instanced id (used by default shader instanced program)
|
||||||
|
unsigned int defaultShaderInstancedId; // Default shader instanced program id, supports vertex color and diffuse texture
|
||||||
|
int *defaultShaderInstancedLocs; // Default shader instanced locations pointer to be used on rendering
|
||||||
unsigned int currentShaderId; // Current shader id to be used on rendering (by default, defaultShaderId)
|
unsigned int currentShaderId; // Current shader id to be used on rendering (by default, defaultShaderId)
|
||||||
int *currentShaderLocs; // Current shader locations pointer to be used on rendering (by default, defaultShaderLocs)
|
int *currentShaderLocs; // Current shader locations pointer to be used on rendering (by default, defaultShaderLocs)
|
||||||
|
|
||||||
|
|
@ -1055,6 +1062,8 @@ static PFNGLVERTEXATTRIBDIVISOREXTPROC glVertexAttribDivisor = NULL;
|
||||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
static void rlLoadShaderDefault(void); // Load default shader
|
static void rlLoadShaderDefault(void); // Load default shader
|
||||||
static void rlUnloadShaderDefault(void); // Unload default shader
|
static void rlUnloadShaderDefault(void); // Unload default shader
|
||||||
|
static void rlLoadShaderInstancedDefault(void); // Load default shaderInstanced
|
||||||
|
static void rlUnloadShaderInstancedDefault(void); // Unload default shaderInstanced
|
||||||
#if defined(RLGL_SHOW_GL_DETAILS_INFO)
|
#if defined(RLGL_SHOW_GL_DETAILS_INFO)
|
||||||
static char *rlGetCompressedFormatName(int format); // Get compressed format official GL identifier name
|
static char *rlGetCompressedFormatName(int format); // Get compressed format official GL identifier name
|
||||||
#endif // RLGL_SHOW_GL_DETAILS_INFO
|
#endif // RLGL_SHOW_GL_DETAILS_INFO
|
||||||
|
|
@ -2093,6 +2102,7 @@ void rlglInit(int width, int height)
|
||||||
// Init default Shader (customized for GL 3.3 and ES2)
|
// Init default Shader (customized for GL 3.3 and ES2)
|
||||||
// Loaded: RLGL.State.defaultShaderId + RLGL.State.defaultShaderLocs
|
// Loaded: RLGL.State.defaultShaderId + RLGL.State.defaultShaderLocs
|
||||||
rlLoadShaderDefault();
|
rlLoadShaderDefault();
|
||||||
|
rlLoadShaderInstancedDefault();
|
||||||
RLGL.State.currentShaderId = RLGL.State.defaultShaderId;
|
RLGL.State.currentShaderId = RLGL.State.defaultShaderId;
|
||||||
RLGL.State.currentShaderLocs = RLGL.State.defaultShaderLocs;
|
RLGL.State.currentShaderLocs = RLGL.State.defaultShaderLocs;
|
||||||
|
|
||||||
|
|
@ -2159,6 +2169,7 @@ void rlglClose(void)
|
||||||
rlUnloadRenderBatch(RLGL.defaultBatch);
|
rlUnloadRenderBatch(RLGL.defaultBatch);
|
||||||
|
|
||||||
rlUnloadShaderDefault(); // Unload default shader
|
rlUnloadShaderDefault(); // Unload default shader
|
||||||
|
rlUnloadShaderInstancedDefault(); // Unload default shader
|
||||||
|
|
||||||
glDeleteTextures(1, &RLGL.State.defaultTextureId); // Unload default texture
|
glDeleteTextures(1, &RLGL.State.defaultTextureId); // Unload default texture
|
||||||
TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Default texture unloaded successfully", RLGL.State.defaultTextureId);
|
TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Default texture unloaded successfully", RLGL.State.defaultTextureId);
|
||||||
|
|
@ -2524,6 +2535,26 @@ int *rlGetShaderLocsDefault(void)
|
||||||
return locs;
|
return locs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get default shader instanced id
|
||||||
|
unsigned int rlGetShaderInstancedIdDefault(void)
|
||||||
|
{
|
||||||
|
unsigned int id = 0;
|
||||||
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
|
id = RLGL.State.defaultShaderInstancedId;
|
||||||
|
#endif
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get default shader instanced locs
|
||||||
|
int *rlGetShaderInstancedLocsDefault(void)
|
||||||
|
{
|
||||||
|
int *locs = NULL;
|
||||||
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
|
locs = RLGL.State.defaultShaderInstancedLocs;
|
||||||
|
#endif
|
||||||
|
return locs;
|
||||||
|
}
|
||||||
|
|
||||||
// Render batch management
|
// Render batch management
|
||||||
//------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------
|
||||||
// Load render batch
|
// Load render batch
|
||||||
|
|
@ -4662,6 +4693,136 @@ static void rlUnloadShaderDefault(void)
|
||||||
TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Default shader unloaded successfully", RLGL.State.defaultShaderId);
|
TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Default shader unloaded successfully", RLGL.State.defaultShaderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load default instanced shader (just vertex positioning and texture coloring)
|
||||||
|
static void rlLoadShaderInstancedDefault(void)
|
||||||
|
{
|
||||||
|
RLGL.State.defaultShaderInstancedLocs = (int *)RL_CALLOC(RL_MAX_SHADER_LOCATIONS, sizeof(int));
|
||||||
|
|
||||||
|
// NOTE: All locations must be reseted to -1 (no location)
|
||||||
|
for (int i = 0; i < RL_MAX_SHADER_LOCATIONS; i++) RLGL.State.defaultShaderInstancedLocs[i] = -1;
|
||||||
|
|
||||||
|
// Vertex shader directly defined, no external file required
|
||||||
|
const char *defaultVShaderInstancedCode =
|
||||||
|
#if defined(GRAPHICS_API_OPENGL_21)
|
||||||
|
"#version 120 \n"
|
||||||
|
"attribute vec3 vertexPosition; \n"
|
||||||
|
"attribute vec2 vertexTexCoord; \n"
|
||||||
|
"attribute vec4 vertexColor; \n"
|
||||||
|
"attribute mat4 instanceTransform; \n"
|
||||||
|
"varying vec2 fragTexCoord; \n"
|
||||||
|
"varying vec4 fragColor; \n"
|
||||||
|
#elif defined(GRAPHICS_API_OPENGL_33)
|
||||||
|
"#version 330 \n"
|
||||||
|
"in vec3 vertexPosition; \n"
|
||||||
|
"in vec2 vertexTexCoord; \n"
|
||||||
|
"in vec4 vertexColor; \n"
|
||||||
|
"in mat4 instanceTransform; \n"
|
||||||
|
"out vec2 fragTexCoord; \n"
|
||||||
|
"out vec4 fragColor; \n"
|
||||||
|
#endif
|
||||||
|
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
|
"#version 100 \n"
|
||||||
|
"precision mediump float; \n" // Precision required for OpenGL ES2 (WebGL) (on some browsers)
|
||||||
|
"attribute vec3 vertexPosition; \n"
|
||||||
|
"attribute vec2 vertexTexCoord; \n"
|
||||||
|
"attribute vec4 vertexColor; \n"
|
||||||
|
"attribute mat4 instanceTransform; \n"
|
||||||
|
"varying vec2 fragTexCoord; \n"
|
||||||
|
"varying vec4 fragColor; \n"
|
||||||
|
#endif
|
||||||
|
"uniform mat4 mvp; \n"
|
||||||
|
"void main() \n"
|
||||||
|
"{ \n"
|
||||||
|
" fragTexCoord = vertexTexCoord; \n"
|
||||||
|
" fragColor = vertexColor; \n"
|
||||||
|
" gl_Position = mvp*instanceTransform*vec4(vertexPosition, 1.0); \n"
|
||||||
|
"} \n";
|
||||||
|
|
||||||
|
// Fragment shader directly defined, no external file required
|
||||||
|
const char *defaultFShaderInstancedCode =
|
||||||
|
#if defined(GRAPHICS_API_OPENGL_21)
|
||||||
|
"#version 120 \n"
|
||||||
|
"varying vec2 fragTexCoord; \n"
|
||||||
|
"varying vec4 fragColor; \n"
|
||||||
|
"uniform sampler2D texture0; \n"
|
||||||
|
"uniform vec4 colDiffuse; \n"
|
||||||
|
"void main() \n"
|
||||||
|
"{ \n"
|
||||||
|
" vec4 texelColor = texture2D(texture0, fragTexCoord); \n"
|
||||||
|
" gl_FragColor = texelColor*colDiffuse*fragColor; \n"
|
||||||
|
"} \n";
|
||||||
|
#elif defined(GRAPHICS_API_OPENGL_33)
|
||||||
|
"#version 330 \n"
|
||||||
|
"in vec2 fragTexCoord; \n"
|
||||||
|
"in vec4 fragColor; \n"
|
||||||
|
"out vec4 finalColor; \n"
|
||||||
|
"uniform sampler2D texture0; \n"
|
||||||
|
"uniform vec4 colDiffuse; \n"
|
||||||
|
"void main() \n"
|
||||||
|
"{ \n"
|
||||||
|
" vec4 texelColor = texture(texture0, fragTexCoord); \n"
|
||||||
|
" finalColor = texelColor*colDiffuse*fragColor; \n"
|
||||||
|
"} \n";
|
||||||
|
#endif
|
||||||
|
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
|
"#version 100 \n"
|
||||||
|
"precision mediump float; \n" // Precision required for OpenGL ES2 (WebGL)
|
||||||
|
"varying vec2 fragTexCoord; \n"
|
||||||
|
"varying vec4 fragColor; \n"
|
||||||
|
"uniform sampler2D texture0; \n"
|
||||||
|
"uniform vec4 colDiffuse; \n"
|
||||||
|
"void main() \n"
|
||||||
|
"{ \n"
|
||||||
|
" vec4 texelColor = texture2D(texture0, fragTexCoord); \n"
|
||||||
|
" gl_FragColor = texelColor*colDiffuse*fragColor; \n"
|
||||||
|
"} \n";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// NOTE: Compiled vertex/fragment shaders are not deleted,
|
||||||
|
// they are kept for re-use as default shaders in case some shader loading fails
|
||||||
|
RLGL.State.defaultVShaderInstancedId = rlCompileShader(defaultVShaderInstancedCode, GL_VERTEX_SHADER); // Compile default vertex shader
|
||||||
|
RLGL.State.defaultFShaderInstancedId = rlCompileShader(defaultFShaderInstancedCode, GL_FRAGMENT_SHADER); // Compile default fragment shader
|
||||||
|
|
||||||
|
RLGL.State.defaultShaderInstancedId = rlLoadShaderProgram(RLGL.State.defaultVShaderInstancedId, RLGL.State.defaultFShaderInstancedId);
|
||||||
|
|
||||||
|
if (RLGL.State.defaultShaderInstancedId > 0)
|
||||||
|
{
|
||||||
|
TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Default instanced shader loaded successfully", RLGL.State.defaultShaderInstancedId);
|
||||||
|
|
||||||
|
// Set default shader locations: attributes locations
|
||||||
|
RLGL.State.defaultShaderInstancedLocs[RL_SHADER_LOC_VERTEX_POSITION] = glGetAttribLocation(RLGL.State.defaultShaderInstancedId, "vertexPosition");
|
||||||
|
RLGL.State.defaultShaderInstancedLocs[RL_SHADER_LOC_VERTEX_TEXCOORD01] = glGetAttribLocation(RLGL.State.defaultShaderInstancedId, "vertexTexCoord");
|
||||||
|
RLGL.State.defaultShaderInstancedLocs[RL_SHADER_LOC_VERTEX_COLOR] = glGetAttribLocation(RLGL.State.defaultShaderInstancedId, "vertexColor");
|
||||||
|
|
||||||
|
// For instanced rendering
|
||||||
|
RLGL.State.defaultShaderInstancedLocs[RL_SHADER_LOC_VERTEX_INSTANCE] = glGetAttribLocation(RLGL.State.defaultShaderInstancedId, "instanceTransform");
|
||||||
|
|
||||||
|
// Set default shader locations: uniform locations
|
||||||
|
RLGL.State.defaultShaderInstancedLocs[RL_SHADER_LOC_MATRIX_MVP] = glGetUniformLocation(RLGL.State.defaultShaderInstancedId, "mvp");
|
||||||
|
RLGL.State.defaultShaderInstancedLocs[RL_SHADER_LOC_COLOR_DIFFUSE] = glGetUniformLocation(RLGL.State.defaultShaderInstancedId, "colDiffuse");
|
||||||
|
RLGL.State.defaultShaderInstancedLocs[RL_SHADER_LOC_MAP_DIFFUSE] = glGetUniformLocation(RLGL.State.defaultShaderInstancedId, "texture0");
|
||||||
|
}
|
||||||
|
else TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to load default instanced shader", RLGL.State.defaultShaderInstancedId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unload default instanced shader
|
||||||
|
// NOTE: Unloads: RLGL.State.defaultShaderInstancedId, RLGL.State.defaultShaderInstancedLocs
|
||||||
|
static void rlUnloadShaderInstancedDefault(void)
|
||||||
|
{
|
||||||
|
glUseProgram(0);
|
||||||
|
|
||||||
|
glDetachShader(RLGL.State.defaultShaderInstancedId, RLGL.State.defaultVShaderInstancedId);
|
||||||
|
glDetachShader(RLGL.State.defaultShaderInstancedId, RLGL.State.defaultFShaderInstancedId);
|
||||||
|
glDeleteShader(RLGL.State.defaultVShaderInstancedId);
|
||||||
|
glDeleteShader(RLGL.State.defaultFShaderInstancedId);
|
||||||
|
|
||||||
|
glDeleteProgram(RLGL.State.defaultShaderInstancedId);
|
||||||
|
|
||||||
|
RL_FREE(RLGL.State.defaultShaderInstancedLocs);
|
||||||
|
|
||||||
|
TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Default instanced shader unloaded successfully", RLGL.State.defaultShaderInstancedId);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(RLGL_SHOW_GL_DETAILS_INFO)
|
#if defined(RLGL_SHOW_GL_DETAILS_INFO)
|
||||||
// Get compressed format official GL identifier name
|
// Get compressed format official GL identifier name
|
||||||
static char *rlGetCompressedFormatName(int format)
|
static char *rlGetCompressedFormatName(int format)
|
||||||
|
|
|
||||||
|
|
@ -1539,12 +1539,12 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i
|
||||||
unsigned int instancesVboId = 0;
|
unsigned int instancesVboId = 0;
|
||||||
|
|
||||||
// Bind shader program
|
// Bind shader program
|
||||||
rlEnableShader(material.shader.id);
|
rlEnableShader(material.shaderInstanced.id);
|
||||||
|
|
||||||
// Send required data to shader (matrices, values)
|
// Send required data to shader (matrices, values)
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
// Upload to shader material.colDiffuse
|
// Upload to shader material.colDiffuse
|
||||||
if (material.shader.locs[SHADER_LOC_COLOR_DIFFUSE] != -1)
|
if (material.shaderInstanced.locs[SHADER_LOC_COLOR_DIFFUSE] != -1)
|
||||||
{
|
{
|
||||||
float values[4] = {
|
float values[4] = {
|
||||||
(float)material.maps[MATERIAL_MAP_DIFFUSE].color.r/255.0f,
|
(float)material.maps[MATERIAL_MAP_DIFFUSE].color.r/255.0f,
|
||||||
|
|
@ -1553,11 +1553,11 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i
|
||||||
(float)material.maps[MATERIAL_MAP_DIFFUSE].color.a/255.0f
|
(float)material.maps[MATERIAL_MAP_DIFFUSE].color.a/255.0f
|
||||||
};
|
};
|
||||||
|
|
||||||
rlSetUniform(material.shader.locs[SHADER_LOC_COLOR_DIFFUSE], values, SHADER_UNIFORM_VEC4, 1);
|
rlSetUniform(material.shaderInstanced.locs[SHADER_LOC_COLOR_DIFFUSE], values, SHADER_UNIFORM_VEC4, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upload to shader material.colSpecular (if location available)
|
// Upload to shader material.colSpecular (if location available)
|
||||||
if (material.shader.locs[SHADER_LOC_COLOR_SPECULAR] != -1)
|
if (material.shaderInstanced.locs[SHADER_LOC_COLOR_SPECULAR] != -1)
|
||||||
{
|
{
|
||||||
float values[4] = {
|
float values[4] = {
|
||||||
(float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.r/255.0f,
|
(float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.r/255.0f,
|
||||||
|
|
@ -1566,7 +1566,7 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i
|
||||||
(float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.a/255.0f
|
(float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.a/255.0f
|
||||||
};
|
};
|
||||||
|
|
||||||
rlSetUniform(material.shader.locs[SHADER_LOC_COLOR_SPECULAR], values, SHADER_UNIFORM_VEC4, 1);
|
rlSetUniform(material.shaderInstanced.locs[SHADER_LOC_COLOR_SPECULAR], values, SHADER_UNIFORM_VEC4, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a copy of current matrices to work with,
|
// Get a copy of current matrices to work with,
|
||||||
|
|
@ -1580,8 +1580,11 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i
|
||||||
Matrix matProjection = rlGetMatrixProjection();
|
Matrix matProjection = rlGetMatrixProjection();
|
||||||
|
|
||||||
// Upload view and projection matrices (if locations available)
|
// Upload view and projection matrices (if locations available)
|
||||||
if (material.shader.locs[SHADER_LOC_MATRIX_VIEW] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_VIEW], matView);
|
if (material.shaderInstanced.locs[SHADER_LOC_MATRIX_VIEW] != -1) rlSetUniformMatrix(material.shaderInstanced.locs[SHADER_LOC_MATRIX_VIEW], matView);
|
||||||
if (material.shader.locs[SHADER_LOC_MATRIX_PROJECTION] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_PROJECTION], matProjection);
|
if (material.shaderInstanced.locs[SHADER_LOC_MATRIX_PROJECTION] != -1) rlSetUniformMatrix(material.shaderInstanced.locs[SHADER_LOC_MATRIX_PROJECTION], matProjection);
|
||||||
|
|
||||||
|
// Model transformation matrix is sent to shader uniform location: SHADER_LOC_MATRIX_MODEL (identity in case of instanced rendering)
|
||||||
|
rlSetUniformMatrix(material.shaderInstanced.locs[SHADER_LOC_MATRIX_MODEL], MatrixIdentity());
|
||||||
|
|
||||||
// Create instances buffer
|
// Create instances buffer
|
||||||
instanceTransforms = (float16 *)RL_MALLOC(instances*sizeof(float16));
|
instanceTransforms = (float16 *)RL_MALLOC(instances*sizeof(float16));
|
||||||
|
|
@ -1598,12 +1601,12 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i
|
||||||
// no faster, since we're transferring all the transform matrices anyway
|
// no faster, since we're transferring all the transform matrices anyway
|
||||||
instancesVboId = rlLoadVertexBuffer(instanceTransforms, instances*sizeof(float16), false);
|
instancesVboId = rlLoadVertexBuffer(instanceTransforms, instances*sizeof(float16), false);
|
||||||
|
|
||||||
// Instances transformation matrices are send to shader attribute location: SHADER_LOC_MATRIX_MODEL
|
// Instances transformation matrices are send to shader attribute location: SHADER_LOC_VERTEX_INSTANCE
|
||||||
for (unsigned int i = 0; i < 4; i++)
|
for (unsigned int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i);
|
rlEnableVertexAttribute(material.shaderInstanced.locs[SHADER_LOC_VERTEX_INSTANCE] + i);
|
||||||
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i, 4, RL_FLOAT, 0, sizeof(Matrix), (void *)(i*sizeof(Vector4)));
|
rlSetVertexAttribute(material.shaderInstanced.locs[SHADER_LOC_VERTEX_INSTANCE] + i, 4, RL_FLOAT, 0, sizeof(Matrix), (void *)(i*sizeof(Vector4)));
|
||||||
rlSetVertexAttributeDivisor(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i, 1);
|
rlSetVertexAttributeDivisor(material.shaderInstanced.locs[SHADER_LOC_VERTEX_INSTANCE] + i, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
rlDisableVertexBuffer();
|
rlDisableVertexBuffer();
|
||||||
|
|
@ -1614,7 +1617,7 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i
|
||||||
matModelView = MatrixMultiply(rlGetMatrixTransform(), matView);
|
matModelView = MatrixMultiply(rlGetMatrixTransform(), matView);
|
||||||
|
|
||||||
// Upload model normal matrix (if locations available)
|
// Upload model normal matrix (if locations available)
|
||||||
if (material.shader.locs[SHADER_LOC_MATRIX_NORMAL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_NORMAL], MatrixTranspose(MatrixInvert(matModel)));
|
if (material.shaderInstanced.locs[SHADER_LOC_MATRIX_NORMAL] != -1) rlSetUniformMatrix(material.shaderInstanced.locs[SHADER_LOC_MATRIX_NORMAL], MatrixTranspose(MatrixInvert(matModel)));
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
|
|
||||||
// Bind active texture maps (if available)
|
// Bind active texture maps (if available)
|
||||||
|
|
@ -1631,7 +1634,7 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i
|
||||||
(i == MATERIAL_MAP_CUBEMAP)) rlEnableTextureCubemap(material.maps[i].texture.id);
|
(i == MATERIAL_MAP_CUBEMAP)) rlEnableTextureCubemap(material.maps[i].texture.id);
|
||||||
else rlEnableTexture(material.maps[i].texture.id);
|
else rlEnableTexture(material.maps[i].texture.id);
|
||||||
|
|
||||||
rlSetUniform(material.shader.locs[SHADER_LOC_MAP_DIFFUSE + i], &i, SHADER_UNIFORM_INT, 1);
|
rlSetUniform(material.shaderInstanced.locs[SHADER_LOC_MAP_DIFFUSE + i], &i, SHADER_UNIFORM_INT, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1641,62 +1644,62 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i
|
||||||
{
|
{
|
||||||
// Bind mesh VBO data: vertex position (shader-location = 0)
|
// Bind mesh VBO data: vertex position (shader-location = 0)
|
||||||
rlEnableVertexBuffer(mesh.vboId[0]);
|
rlEnableVertexBuffer(mesh.vboId[0]);
|
||||||
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION], 3, RL_FLOAT, 0, 0, 0);
|
rlSetVertexAttribute(material.shaderInstanced.locs[SHADER_LOC_VERTEX_POSITION], 3, RL_FLOAT, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION]);
|
rlEnableVertexAttribute(material.shaderInstanced.locs[SHADER_LOC_VERTEX_POSITION]);
|
||||||
|
|
||||||
// Bind mesh VBO data: vertex texcoords (shader-location = 1)
|
// Bind mesh VBO data: vertex texcoords (shader-location = 1)
|
||||||
rlEnableVertexBuffer(mesh.vboId[1]);
|
rlEnableVertexBuffer(mesh.vboId[1]);
|
||||||
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01], 2, RL_FLOAT, 0, 0, 0);
|
rlSetVertexAttribute(material.shaderInstanced.locs[SHADER_LOC_VERTEX_TEXCOORD01], 2, RL_FLOAT, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01]);
|
rlEnableVertexAttribute(material.shaderInstanced.locs[SHADER_LOC_VERTEX_TEXCOORD01]);
|
||||||
|
|
||||||
if (material.shader.locs[SHADER_LOC_VERTEX_NORMAL] != -1)
|
if (material.shaderInstanced.locs[SHADER_LOC_VERTEX_NORMAL] != -1)
|
||||||
{
|
{
|
||||||
// Bind mesh VBO data: vertex normals (shader-location = 2)
|
// Bind mesh VBO data: vertex normals (shader-location = 2)
|
||||||
rlEnableVertexBuffer(mesh.vboId[2]);
|
rlEnableVertexBuffer(mesh.vboId[2]);
|
||||||
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_NORMAL], 3, RL_FLOAT, 0, 0, 0);
|
rlSetVertexAttribute(material.shaderInstanced.locs[SHADER_LOC_VERTEX_NORMAL], 3, RL_FLOAT, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_NORMAL]);
|
rlEnableVertexAttribute(material.shaderInstanced.locs[SHADER_LOC_VERTEX_NORMAL]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind mesh VBO data: vertex colors (shader-location = 3, if available)
|
// Bind mesh VBO data: vertex colors (shader-location = 3, if available)
|
||||||
if (material.shader.locs[SHADER_LOC_VERTEX_COLOR] != -1)
|
if (material.shaderInstanced.locs[SHADER_LOC_VERTEX_COLOR] != -1)
|
||||||
{
|
{
|
||||||
if (mesh.vboId[3] != 0)
|
if (mesh.vboId[3] != 0)
|
||||||
{
|
{
|
||||||
rlEnableVertexBuffer(mesh.vboId[3]);
|
rlEnableVertexBuffer(mesh.vboId[3]);
|
||||||
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR], 4, RL_UNSIGNED_BYTE, 1, 0, 0);
|
rlSetVertexAttribute(material.shaderInstanced.locs[SHADER_LOC_VERTEX_COLOR], 4, RL_UNSIGNED_BYTE, 1, 0, 0);
|
||||||
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR]);
|
rlEnableVertexAttribute(material.shaderInstanced.locs[SHADER_LOC_VERTEX_COLOR]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Set default value for unused attribute
|
// Set default value for unused attribute
|
||||||
// NOTE: Required when using default shader and no VAO support
|
// NOTE: Required when using default shader and no VAO support
|
||||||
float value[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
float value[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||||
rlSetVertexAttributeDefault(material.shader.locs[SHADER_LOC_VERTEX_COLOR], value, SHADER_ATTRIB_VEC4, 4);
|
rlSetVertexAttributeDefault(material.shaderInstanced.locs[SHADER_LOC_VERTEX_COLOR], value, SHADER_ATTRIB_VEC4, 4);
|
||||||
rlDisableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR]);
|
rlDisableVertexAttribute(material.shaderInstanced.locs[SHADER_LOC_VERTEX_COLOR]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind mesh VBO data: vertex tangents (shader-location = 4, if available)
|
// Bind mesh VBO data: vertex tangents (shader-location = 4, if available)
|
||||||
if (material.shader.locs[SHADER_LOC_VERTEX_TANGENT] != -1)
|
if (material.shaderInstanced.locs[SHADER_LOC_VERTEX_TANGENT] != -1)
|
||||||
{
|
{
|
||||||
rlEnableVertexBuffer(mesh.vboId[4]);
|
rlEnableVertexBuffer(mesh.vboId[4]);
|
||||||
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TANGENT], 4, RL_FLOAT, 0, 0, 0);
|
rlSetVertexAttribute(material.shaderInstanced.locs[SHADER_LOC_VERTEX_TANGENT], 4, RL_FLOAT, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TANGENT]);
|
rlEnableVertexAttribute(material.shaderInstanced.locs[SHADER_LOC_VERTEX_TANGENT]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind mesh VBO data: vertex texcoords2 (shader-location = 5, if available)
|
// Bind mesh VBO data: vertex texcoords2 (shader-location = 5, if available)
|
||||||
if (material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02] != -1)
|
if (material.shaderInstanced.locs[SHADER_LOC_VERTEX_TEXCOORD02] != -1)
|
||||||
{
|
{
|
||||||
rlEnableVertexBuffer(mesh.vboId[5]);
|
rlEnableVertexBuffer(mesh.vboId[5]);
|
||||||
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02], 2, RL_FLOAT, 0, 0, 0);
|
rlSetVertexAttribute(material.shaderInstanced.locs[SHADER_LOC_VERTEX_TEXCOORD02], 2, RL_FLOAT, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02]);
|
rlEnableVertexAttribute(material.shaderInstanced.locs[SHADER_LOC_VERTEX_TEXCOORD02]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mesh.indices != NULL) rlEnableVertexBufferElement(mesh.vboId[6]);
|
if (mesh.indices != NULL) rlEnableVertexBufferElement(mesh.vboId[6]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// WARNING: Disable vertex attribute color input if mesh can not provide that data (despite location being enabled in shader)
|
// WARNING: Disable vertex attribute color input if mesh can not provide that data (despite location being enabled in shader)
|
||||||
if (mesh.vboId[3] == 0) rlDisableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR]);
|
if (mesh.vboId[3] == 0) rlDisableVertexAttribute(material.shaderInstanced.locs[SHADER_LOC_VERTEX_COLOR]);
|
||||||
|
|
||||||
int eyeCount = 1;
|
int eyeCount = 1;
|
||||||
if (rlIsStereoRenderEnabled()) eyeCount = 2;
|
if (rlIsStereoRenderEnabled()) eyeCount = 2;
|
||||||
|
|
@ -1714,7 +1717,7 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send combined model-view-projection matrix to shader
|
// Send combined model-view-projection matrix to shader
|
||||||
rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_MVP], matModelViewProjection);
|
rlSetUniformMatrix(material.shaderInstanced.locs[SHADER_LOC_MATRIX_MVP], matModelViewProjection);
|
||||||
|
|
||||||
// Draw mesh instanced
|
// Draw mesh instanced
|
||||||
if (mesh.indices != NULL) rlDrawVertexArrayElementsInstanced(0, mesh.triangleCount*3, 0, instances);
|
if (mesh.indices != NULL) rlDrawVertexArrayElementsInstanced(0, mesh.triangleCount*3, 0, instances);
|
||||||
|
|
@ -1927,6 +1930,9 @@ Material LoadMaterialDefault(void)
|
||||||
material.shader.id = rlGetShaderIdDefault();
|
material.shader.id = rlGetShaderIdDefault();
|
||||||
material.shader.locs = rlGetShaderLocsDefault();
|
material.shader.locs = rlGetShaderLocsDefault();
|
||||||
|
|
||||||
|
material.shaderInstanced.id = rlGetShaderInstancedIdDefault();
|
||||||
|
material.shaderInstanced.locs = rlGetShaderInstancedLocsDefault();
|
||||||
|
|
||||||
// Using rlgl default texture (1x1 pixel, UNCOMPRESSED_R8G8B8A8, 1 mipmap)
|
// Using rlgl default texture (1x1 pixel, UNCOMPRESSED_R8G8B8A8, 1 mipmap)
|
||||||
material.maps[MATERIAL_MAP_DIFFUSE].texture = (Texture2D){ rlGetTextureIdDefault(), 1, 1, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 };
|
material.maps[MATERIAL_MAP_DIFFUSE].texture = (Texture2D){ rlGetTextureIdDefault(), 1, 1, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 };
|
||||||
//material.maps[MATERIAL_MAP_NORMAL].texture; // NOTE: By default, not set
|
//material.maps[MATERIAL_MAP_NORMAL].texture; // NOTE: By default, not set
|
||||||
|
|
@ -1941,8 +1947,9 @@ Material LoadMaterialDefault(void)
|
||||||
// Check if a material is ready
|
// Check if a material is ready
|
||||||
bool IsMaterialReady(Material material)
|
bool IsMaterialReady(Material material)
|
||||||
{
|
{
|
||||||
return ((material.maps != NULL) && // Validate material contain some map
|
return ((material.maps != NULL) && // Validate material contain some map
|
||||||
(material.shader.id > 0)); // Validate material shader is valid
|
(material.shader.id > 0) && // Validate material shader is valid
|
||||||
|
(material.shaderInstanced.id > 0)) ; // Validate material shader instanced is valid
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unload material from memory
|
// Unload material from memory
|
||||||
|
|
@ -1951,6 +1958,9 @@ void UnloadMaterial(Material material)
|
||||||
// Unload material shader (avoid unloading default shader, managed by raylib)
|
// Unload material shader (avoid unloading default shader, managed by raylib)
|
||||||
if (material.shader.id != rlGetShaderIdDefault()) UnloadShader(material.shader);
|
if (material.shader.id != rlGetShaderIdDefault()) UnloadShader(material.shader);
|
||||||
|
|
||||||
|
// Unload material shader (avoid unloading default shader, managed by raylib)
|
||||||
|
if (material.shaderInstanced.id != rlGetShaderInstancedIdDefault()) UnloadShader(material.shaderInstanced);
|
||||||
|
|
||||||
// Unload loaded texture maps (avoid unloading default texture, managed by raylib)
|
// Unload loaded texture maps (avoid unloading default texture, managed by raylib)
|
||||||
if (material.maps != NULL)
|
if (material.maps != NULL)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user