Fix segfaults in the example scene.

This commit is contained in:
Shaun Reed 2025-03-22 13:41:14 -04:00
parent fb9c320633
commit 58013ad571

View File

@ -426,6 +426,7 @@ void QtkScene::draw()
// WARNING: We must call the base class draw() function first. // WARNING: We must call the base class draw() function first.
// + This will handle rendering core scene components like the Skybox. // + This will handle rendering core scene components like the Skybox.
Scene::draw(); Scene::draw();
const QVector3D cameraPosition = getCamera().getTransform().getTranslation();
mTestPhong->bindShaders(); mTestPhong->bindShaders();
mTestPhong->setUniform("uModelInverseTransposed", mTestPhong->setUniform("uModelInverseTransposed",
@ -433,14 +434,12 @@ void QtkScene::draw()
mTestPhong->setUniform( mTestPhong->setUniform(
"uLightPosition", "uLightPosition",
MeshRenderer::getInstance("phongLight")->getTransform().getTranslation()); MeshRenderer::getInstance("phongLight")->getTransform().getTranslation());
mTestPhong->setUniform("uCameraPosition", mTestPhong->setUniform("uCameraPosition", cameraPosition);
QtkScene::getCamera().getTransform().getTranslation());
mTestPhong->releaseShaders(); mTestPhong->releaseShaders();
mTestPhong->draw(); mTestPhong->draw();
mTestAmbient->bindShaders(); mTestAmbient->bindShaders();
mTestAmbient->setUniform( mTestAmbient->setUniform("uCameraPosition", cameraPosition);
"uCameraPosition", QtkScene::getCamera().getTransform().getTranslation());
mTestAmbient->releaseShaders(); mTestAmbient->releaseShaders();
mTestAmbient->draw(); mTestAmbient->draw();
@ -452,8 +451,7 @@ void QtkScene::draw()
MeshRenderer::getInstance("diffuseLight") MeshRenderer::getInstance("diffuseLight")
->getTransform() ->getTransform()
.getTranslation()); .getTranslation());
mTestDiffuse->setUniform( mTestDiffuse->setUniform("uCameraPosition", cameraPosition);
"uCameraPosition", QtkScene::getCamera().getTransform().getTranslation());
mTestDiffuse->releaseShaders(); mTestDiffuse->releaseShaders();
mTestDiffuse->draw(); mTestDiffuse->draw();
@ -465,67 +463,82 @@ void QtkScene::draw()
MeshRenderer::getInstance("specularLight") MeshRenderer::getInstance("specularLight")
->getTransform() ->getTransform()
.getTranslation()); .getTranslation());
mTestSpecular->setUniform( mTestSpecular->setUniform("uCameraPosition", cameraPosition);
"uCameraPosition", QtkScene::getCamera().getTransform().getTranslation());
mTestSpecular->releaseShaders(); mTestSpecular->releaseShaders();
mTestSpecular->draw(); mTestSpecular->draw();
} }
void QtkScene::update() void QtkScene::update()
{ {
auto mySpartan = Model::getInstance("My spartan"); auto getModel = Model::getInstance;
mySpartan->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f); const QVector3D cameraPosition = getCamera().getTransform().getTranslation();
auto myCube = MeshRenderer::getInstance("My cube"); // Models may have failed to load, so we should check before accessing.
myCube->getTransform().rotate(-0.75f, 0.0f, 1.0f, 0.0f); if (auto mySpartan = getModel("My spartan"); mySpartan) {
mySpartan->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f);
}
auto position = MeshRenderer::getInstance("alienTestLight") if (auto myCube = getModel("My cube"); myCube) {
->getTransform() myCube->getTransform().rotate(-0.75f, 0.0f, 1.0f, 0.0f);
.getTranslation(); }
auto alien = Model::getInstance("alienTest");
alien->setUniform("uLight.position", position);
alien->setUniform("uCameraPosition",
QtkScene::getCamera().getTransform().getTranslation());
auto posMatrix = alien->getTransform().toMatrix();
alien->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
alien->setUniform("uMVP.model", posMatrix);
alien->setUniform("uMVP.view", QtkScene::getCamera().toMatrix());
alien->setUniform("uMVP.projection", QtkScene::getProjectionMatrix());
alien->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f);
position = MeshRenderer::getInstance("spartanTestLight") // Helper lambda to set the light position used by GLSL shaders on the model.
->getTransform() // TODO: This could be a helper function on the Model class.
.getTranslation(); auto setLightPosition = [](const std::string & lightName, Model * model) {
auto spartan = Model::getInstance("spartanTest"); if (auto light = Model::getInstance(lightName.c_str()); light) {
spartan->setUniform("uLight.position", position); QVector3D position = light->getTransform().getTranslation();
spartan->setUniform("uCameraPosition", model->setUniform("uLight.position", position);
QtkScene::getCamera().getTransform().getTranslation()); } else {
posMatrix = spartan->getTransform().toMatrix(); qDebug() << "[QtkScene] Failed to set light position: "
spartan->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix()); << lightName.c_str();
spartan->setUniform("uMVP.model", posMatrix); }
spartan->setUniform("uMVP.view", QtkScene::getCamera().toMatrix()); };
spartan->setUniform("uMVP.projection", QtkScene::getProjectionMatrix());
spartan->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f);
auto phong = MeshRenderer::getInstance("testPhong"); QMatrix4x4 posMatrix;
phong->getTransform().rotate(0.75f, 1.0f, 0.5f, 0.0f); if (auto alien = getModel("alienTest"); alien) {
phong->bindShaders(); setLightPosition("alienTestLight", alien);
position =
MeshRenderer::getInstance("testLight")->getTransform().getTranslation(); alien->setUniform("uCameraPosition", cameraPosition);
phong->setUniform("uLight.position", position); posMatrix = alien->getTransform().toMatrix();
phong->setUniform("uCameraPosition", alien->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
QtkScene::getCamera().getTransform().getTranslation()); alien->setUniform("uMVP.model", posMatrix);
posMatrix = phong->getTransform().toMatrix(); alien->setUniform("uMVP.view", QtkScene::getCamera().toMatrix());
phong->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix()); alien->setUniform("uMVP.projection", QtkScene::getProjectionMatrix());
phong->setUniform("uMVP.model", posMatrix); alien->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f);
phong->setUniform("uMVP.view", QtkScene::getCamera().toMatrix()); }
phong->setUniform("uMVP.projection", QtkScene::getProjectionMatrix());
phong->releaseShaders(); if (auto spartan = getModel("spartanTest"); spartan) {
setLightPosition("spartanTestLight", spartan);
spartan->setUniform("uCameraPosition", cameraPosition);
posMatrix = spartan->getTransform().toMatrix();
spartan->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
spartan->setUniform("uMVP.model", posMatrix);
spartan->setUniform("uMVP.view", QtkScene::getCamera().toMatrix());
spartan->setUniform("uMVP.projection", QtkScene::getProjectionMatrix());
spartan->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f);
}
if (auto phong = getModel("testPhong"); phong) {
setLightPosition("testLight", phong);
phong->getTransform().rotate(0.75f, 1.0f, 0.5f, 0.0f);
phong->bindShaders();
phong->setUniform("uCameraPosition", cameraPosition);
posMatrix = phong->getTransform().toMatrix();
phong->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
phong->setUniform("uMVP.model", posMatrix);
phong->setUniform("uMVP.view", QtkScene::getCamera().toMatrix());
phong->setUniform("uMVP.projection", QtkScene::getProjectionMatrix());
phong->releaseShaders();
}
// MeshRenderers are lower level opengl objects baked into the source code.
auto getMesh = MeshRenderer::getInstance;
// Rotate lighting example cubes // Rotate lighting example cubes
mTestPhong->getTransform().rotate(0.75f, 0.5f, 0.3f, 0.2f); mTestPhong->getTransform().rotate(0.75f, 0.5f, 0.3f, 0.2f);
MeshRenderer::getInstance("noLight")->getTransform().rotate( getMesh("noLight")->getTransform().rotate(0.75f, 0.5f, 0.3f, 0.2f);
0.75f, 0.5f, 0.3f, 0.2f);
mTestAmbient->getTransform().rotate(0.75f, 0.5f, 0.3f, 0.2f); mTestAmbient->getTransform().rotate(0.75f, 0.5f, 0.3f, 0.2f);
mTestDiffuse->getTransform().rotate(0.75f, 0.5f, 0.3f, 0.2f); mTestDiffuse->getTransform().rotate(0.75f, 0.5f, 0.3f, 0.2f);
mTestSpecular->getTransform().rotate(0.75f, 0.5f, 0.3f, 0.2f); mTestSpecular->getTransform().rotate(0.75f, 0.5f, 0.3f, 0.2f);
@ -533,46 +546,27 @@ void QtkScene::update()
// Examples of various translations and rotations // Examples of various translations and rotations
// Rotate in multiple directions simultaneously // Rotate in multiple directions simultaneously
MeshRenderer::getInstance("rgbNormalsCube") getMesh("rgbNormalsCube")->getTransform().rotate(0.75f, 0.2f, 0.4f, 0.6f);
->getTransform()
.rotate(0.75f, 0.2f, 0.4f, 0.6f);
// Pitch forward and roll sideways // Pitch forward and roll sideways
MeshRenderer::getInstance("leftTriangle") getMesh("leftTriangle")->getTransform().rotate(0.75f, 1.0f, 0.0f, 0.0f);
->getTransform() getMesh("rightTriangle")->getTransform().rotate(0.75f, 0.0f, 0.0f, 1.0f);
.rotate(0.75f, 1.0f, 0.0f, 0.0f);
MeshRenderer::getInstance("rightTriangle")
->getTransform()
.rotate(0.75f, 0.0f, 0.0f, 1.0f);
// Move between two positions over time // Move between two positions over time
static float translateX = 0.025f; static float translateX = 0.025f;
float limit = -9.0f; // Origin position.x - 2.0f float limit = -9.0f; // Origin position.x - 2.0f
float posX = MeshRenderer::getInstance("topTriangle") float posX = getMesh("topTriangle")->getTransform().getTranslation().x();
->getTransform()
.getTranslation()
.x();
if (posX < limit || posX > limit + 4.0f) { if (posX < limit || posX > limit + 4.0f) {
translateX = -translateX; translateX = -translateX;
} }
MeshRenderer::getInstance("topTriangle") getMesh("topTriangle")->getTransform().translate(translateX, 0.0f, 0.0f);
->getTransform() getMesh("bottomTriangle")->getTransform().translate(-translateX, 0.0f, 0.0f);
.translate(translateX, 0.0f, 0.0f);
MeshRenderer::getInstance("bottomTriangle")
->getTransform()
.translate(-translateX, 0.0f, 0.0f);
// And lets rotate the triangles in two directions at once // And lets rotate the triangles in two directions at once
MeshRenderer::getInstance("topTriangle") getMesh("topTriangle")->getTransform().rotate(0.75f, 0.2f, 0.0f, 0.4f);
->getTransform() getMesh("bottomTriangle")->getTransform().rotate(0.75f, 0.0f, 0.2f, 0.4f);
.rotate(0.75f, 0.2f, 0.0f, 0.4f);
MeshRenderer::getInstance("bottomTriangle")
->getTransform()
.rotate(0.75f, 0.0f, 0.2f, 0.4f);
// And make the bottom triangle green, instead of RGB // And make the bottom triangle green, instead of RGB
// Rotate center cube in several directions simultaneously // Rotate center cube in several directions simultaneously
// + Not subject to gimbal lock since we are using quaternions :) // + Not subject to gimbal lock since we are using quaternions :)
MeshRenderer::getInstance("centerCube") getMesh("centerCube")->getTransform().rotate(0.75f, 0.2f, 0.4f, 0.6f);
->getTransform()
.rotate(0.75f, 0.2f, 0.4f, 0.6f);
} }