Description
- I tested it on latest raylib version from master branch
- I checked there is no similar issue already reported
(#2211 is related but isn't the same sort of issue). - My code has no errors or misuse of raylib
Issue description
In my original project, I was trying to draw instanced copies of a particular mesh, and then use that same mesh to draw a non-instanced version of it with the default material. However, something about the DrawMeshInstanced(...) call seemed to corrupt the state of the renderer and made the non-instanced version not draw correctly.
This only occurs when the vertex shader of the instanced material does not declare the attributes for vertex normal and color, which can be demonstrated by replacing the example's shader with "based_lighting_instanced.vs" from the raylib examples.
Although this can be seen as a misconfiguration on the user's end, this error does not occur when instancing is not involved. Even so, an error in the instanced vertex shader should not affect rendering using the default shader as well.
Environment
Linux, Pop! OS (Ubuntu & Gnome desktop), OpenGL 4.6.0 NVIDIA 510.73.05, NVIDIA GeForce GTX 1650, NVIDIA proprietary driver version 510.73.05
Issue Screenshot
Result of the code example below:
Result of the code example, with the DrawMeshInstanced(...) line removed.
Expected result (Achieved by replacing "base_instanced_stripped.vs" with "base_lighting_instanced.vs")
Code Example
#include "raylib.h"
#include "raymath.h"
#include <stdlib.h>
#include <math.h>
#define MAX_INSTANCES 10
int main(void)
{
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - mesh instancing");
SetTargetFPS(60);
Camera camera = { 0 };
camera.position = (Vector3){ -25.0f, 25.0f, -25.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;
SetCameraMode(camera, CAMERA_ORBITAL);
Mesh cube = GenMeshCube(1.0f, 1.0f, 1.0f);
Matrix *transforms = RL_MALLOC(MAX_INSTANCES*sizeof(Matrix));
for (int i = 0; i < MAX_INSTANCES; i++) {
transforms[i] = MatrixTranslate(0.0f, -10.0f, 0.0f);
}
//Load a shader that's missing attributes for vertex color and normals.
Shader shader = LoadShader("resources/shaders/glsl330/base_instanced_stripped.vs",
"resources/shaders/glsl330/base.fs");
shader.locs[SHADER_LOC_MATRIX_MVP] = GetShaderLocation(shader, "mvp");
shader.locs[SHADER_LOC_MATRIX_MODEL] = GetShaderLocationAttrib(shader, "instanceTransform");
//Instanced material
Material instancedMaterial = LoadMaterialDefault();
instancedMaterial.shader = shader;
instancedMaterial.maps[MATERIAL_MAP_DIFFUSE].color = RED;
//Non instanced material
Material normalMaterial = LoadMaterialDefault();
normalMaterial.maps[MATERIAL_MAP_DIFFUSE].color = BLUE;
while (!WindowShouldClose())
{
UpdateCamera(&camera);
BeginDrawing();
ClearBackground(RAYWHITE);
BeginMode3D(camera);
//The cubes drawn before and after the instanced draw call are not rendered unless the instanced draw call is removed.
DrawMesh(cube, normalMaterial, MatrixTranslate(-2.0f, 0.0f, 0.0f));
DrawMeshInstanced(cube, instancedMaterial, transforms, MAX_INSTANCES);
DrawMesh(cube, normalMaterial, MatrixTranslate(2.0f, 0.0f, 0.0f));
EndMode3D();
EndDrawing();
}
RL_FREE(transforms);
CloseWindow();
return 0;
}
Shader code for "base_instanced_stripped.vs":
#version 330
in vec3 vertexPosition;
in vec2 vertexTexCoord;
in mat4 instanceTransform;
uniform mat4 mvp;
uniform mat4 matNormal;
out vec3 fragPosition;
out vec2 fragTexCoord;
void main()
{
mat4 mvpi = mvp*instanceTransform;
fragPosition = vec3(mvpi*vec4(vertexPosition, 1.0));
fragTexCoord = vertexTexCoord;
gl_Position = mvpi*vec4(vertexPosition, 1.0);
}
Other shaders mentioned are from the raylib examples repository.