Hello! I wrote a small engine, and decided to test it on different graphics cards. And here is what turned out to be unexpected: on Nvidia and Intel everything works well on Linux and Windows, but on AMD - it gives error 1282 (GL_INVALID_OPERATION) when trying to call glDrawElements. Below are code snippets and links to the full one.
void drawModelDM(const Model &model, ShaderProgram *program, const glm::mat4 &mat = glm::mat4(1.0f)) {
glBindVertexArray(model.shape->vaos[0]);
if (model.shape->bonesPerVertex != 0) {
for (int i = 0; i < model.shape->bones.size(); i++) {
program->set(program->getLocation(AlgineNames::ShadowShader::Bones) + i, model.shape->bones[i].finalTransformation);
}
}
program->set(AlgineNames::ShadowShader::BoneAttribsPerVertex, (int)(model.shape->bonesPerVertex / 4 + (model.shape->bonesPerVertex % 4 == 0 ? 0 : 1)));
program->set(AlgineNames::ShadowShader::TransformationMatrix, mat * model.m_transform);
for (size_t i = 0; i < model.shape->meshes.size(); i++) {
int err = glGetError();
if (err != 0)
std::cout << "Before glDrawElements DM: " << err << "\n";
glDrawElements(GL_TRIANGLES, model.shape->meshes[i].count, GL_UNSIGNED_INT, reinterpret_cast<void*>(model.shape->meshes[i].start * sizeof(uint))); // OK
err = glGetError();
if (err != 0)
std::cout << "After glDrawElements DM: " << err << "\n";
}
}
/**
* Draws model
*/
void drawModel(const Model &model) {
glBindVertexArray(model.shape->vaos[1]);
if (model.shape->bonesPerVertex != 0) {
for (int i = 0; i < model.shape->bones.size(); i++) {
colorShader->set(colorShader->getLocation(AlgineNames::ColorShader::Bones) + i, model.shape->bones[i].finalTransformation);
}
}
colorShader->set(AlgineNames::ColorShader::BoneAttribsPerVertex, (int)(model.shape->bonesPerVertex / 4 + (model.shape->bonesPerVertex % 4 == 0 ? 0 : 1)));
modelMatrix = &model.m_transform;
updateMatrices();
for (size_t i = 0; i < model.shape->meshes.size(); i++) {
texture2DAB(0, model.shape->meshes[i].mat.ambientTexture);
texture2DAB(1, model.shape->meshes[i].mat.diffuseTexture);
texture2DAB(2, model.shape->meshes[i].mat.specularTexture);
texture2DAB(3, model.shape->meshes[i].mat.normalTexture);
texture2DAB(4, model.shape->meshes[i].mat.reflectionTexture);
texture2DAB(5, model.shape->meshes[i].mat.jitterTexture);
colorShader->set(AlgineNames::ColorShader::Material::AmbientStrength, model.shape->meshes[i].mat.ambientStrength);
colorShader->set(AlgineNames::ColorShader::Material::DiffuseStrength, model.shape->meshes[i].mat.diffuseStrength);
colorShader->set(AlgineNames::ColorShader::Material::SpecularStrength, model.shape->meshes[i].mat.specularStrength);
colorShader->set(AlgineNames::ColorShader::Material::Shininess, model.shape->meshes[i].mat.shininess);
int err = glGetError();
if (err != 0)
std::cout << "Before glDrawElements: " << err << "\n";
glDrawElements(GL_TRIANGLES, model.shape->meshes[i].count, GL_UNSIGNED_INT, reinterpret_cast<void*>(model.shape->meshes[i].start * sizeof(uint))); // ERROR: 1282
err = glGetError();
if (err != 0)
std::cout << "After glDrawElements: " << err
<< "\nCount: " << model.shape->meshes[i].count
<< "\nStart: " << model.shape->meshes[i].start
<< "\nVAO: " << model.shape->vaos[1] << "\n";
}
}
/**
* Renders to depth cubemap
*/
void renderToDepthCubemap(const uint index) {
pointLamps[index].begin();
pointLamps[index].updateMatrix();
lightDataSetter.setShadowShaderPos(pointLamps[index]);
lightDataSetter.setShadowShaderMatrices(pointLamps[index]);
glClear(GL_DEPTH_BUFFER_BIT);
// drawing models
for (size_t i = 0; i < MODELS_COUNT; i++)
drawModelDM(models[i], pointShadowShader);
// drawing lamps
for (GLuint i = 0; i < pointLampsCount; i++) {
if (i == index) continue;
drawModelDM(*pointLamps[i].mptr, pointShadowShader);
}
pointLamps[index].end();
}
/**
* Renders to depth map
*/
void renderToDepthMap(uint index) {
dirLamps[index].begin();
glClear(GL_DEPTH_BUFFER_BIT);
// drawing models
for (size_t i = 0; i < MODELS_COUNT; i++)
drawModelDM(models[i], dirShadowShader, dirLamps[index].m_lightSpace);
// drawing lamps
for (GLuint i = 0; i < dirLampsCount; i++) {
if (i == index) continue;
drawModelDM(*dirLamps[i].mptr, dirShadowShader, dirLamps[index].m_lightSpace);
}
dirLamps[index].end();
}
/**
* Color rendering
*/
uint colorAttachment02[3] = { GL_COLOR_ATTACHMENT0, GL_NONE, GL_COLOR_ATTACHMENT2 };
uint colorAttachment0123[4] = {
GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3
};
void render() {
renderer.mainPass(displayFb->getId());
// view port to window size
glViewport(0, 0, winWidth, winHeight);
glDrawBuffers(4, colorAttachment0123);
colorShader->use();
// sending lamps parameters to fragment shader
sendLampsData();
// drawing
for (size_t i = 0; i < MODELS_COUNT; i++)
drawModel(models[i]);
for (size_t i = 0; i < pointLampsCount + dirLampsCount; i++)
drawModel(lamps[i]);
// [...]
}
void display() {
// animate
for (usize i = 0; i < MODELS_COUNT; i++)
if (models[i].shape->bonesPerVertex != 0)
models[i].animator->animate(glfwGetTime());
// shadow rendering
// point lights
pointShadowShader->use();
for (uint i = 0; i < pointLampsCount; i++) {
lightDataSetter.setShadowShaderFarPlane(pointLamps[i]);
renderToDepthCubemap(i);
}
// dir lights
dirShadowShader->use();
for (uint i = 0; i < dirLampsCount; i++)
renderToDepthMap(i);
ssrShader->use();
ssrShader->set(AlgineNames::SSRShader::ProjectionMatrix, camera.getProjectionMatrix());
ssrShader->set(AlgineNames::SSRShader::ViewMatrix, camera.getViewMatrix());
/* --- color rendering --- */
glClear(GL_DEPTH_BUFFER_BIT); // color will cleared by quad rendering
render();
glUseProgram(0);
}
Everything is perfectly drawn in the depth map, but not in the "color map"... And such a problem is ONLY on AMD.
Full code: https://github.com/congard/algine/blob/master/src/main.cpp#L802
Shaders: vertex shader, fragment shader
Repository link: https://github.com/congard/algine
Please help... I've already spent about 5 hours trying to figure out what I'm doing wrong