2021-09-19 18:06:41 +00:00
|
|
|
/*##############################################################################
|
|
|
|
## Author: Shaun Reed ##
|
2022-03-06 16:54:05 +00:00
|
|
|
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
|
2021-09-19 18:06:41 +00:00
|
|
|
## About: Classes for managing objects and data within a scene ##
|
|
|
|
## ##
|
|
|
|
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
|
|
|
##############################################################################*/
|
|
|
|
|
|
|
|
#include <camera3d.h>
|
2022-11-24 22:26:53 +00:00
|
|
|
#include <examplescene.h>
|
2021-09-19 18:06:41 +00:00
|
|
|
#include <meshrenderer.h>
|
|
|
|
#include <model.h>
|
2022-07-31 22:50:02 +00:00
|
|
|
#include <resourcemanager.h>
|
2022-11-26 18:24:38 +00:00
|
|
|
#include <scene.h>
|
2022-08-07 17:12:12 +00:00
|
|
|
#include <texture.h>
|
2021-09-19 18:06:41 +00:00
|
|
|
|
2022-08-07 17:12:12 +00:00
|
|
|
using namespace Qtk;
|
2021-09-19 18:06:41 +00:00
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
* Constructors, Destructors
|
|
|
|
******************************************************************************/
|
|
|
|
|
2022-11-24 22:26:53 +00:00
|
|
|
ExampleScene::ExampleScene() {
|
2022-11-26 18:24:38 +00:00
|
|
|
getCamera().getTransform().setTranslation(0.0f, 0.0f, 20.0f);
|
|
|
|
getCamera().getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
|
2021-09-19 18:06:41 +00:00
|
|
|
}
|
|
|
|
|
2022-11-24 22:26:53 +00:00
|
|
|
ExampleScene::~ExampleScene() {
|
2021-09-19 18:06:41 +00:00
|
|
|
delete mTestPhong;
|
|
|
|
delete mTestSpecular;
|
|
|
|
delete mTestDiffuse;
|
|
|
|
delete mTestAmbient;
|
2022-11-24 22:26:53 +00:00
|
|
|
for(auto & mesh : mMeshes) {
|
|
|
|
delete mesh;
|
|
|
|
}
|
|
|
|
for(auto & model : mModels) {
|
|
|
|
delete model;
|
|
|
|
}
|
2022-08-07 17:12:12 +00:00
|
|
|
delete mSkybox;
|
2021-09-19 18:06:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
* Public Member Functions
|
|
|
|
******************************************************************************/
|
|
|
|
|
2022-11-24 22:26:53 +00:00
|
|
|
void ExampleScene::init() {
|
2022-11-26 18:24:38 +00:00
|
|
|
// Add a skybox to the scene using default cube map images and settings.
|
|
|
|
setSkybox(new Qtk::Skybox("Skybox"));
|
2022-08-07 17:12:12 +00:00
|
|
|
|
2022-11-26 18:24:38 +00:00
|
|
|
/* Create a red cube with a mini master chief on top. */
|
|
|
|
auto myCube = new MeshRenderer("My cube", Cube(Qtk::QTK_DRAW_ELEMENTS));
|
|
|
|
myCube->setColor(RED);
|
|
|
|
mMeshes.push_back(myCube);
|
|
|
|
|
|
|
|
auto mySpartan = new Model("My spartan", ":/models/spartan/spartan.obj");
|
|
|
|
mySpartan->getTransform().setTranslation(0.0f, 0.5f, 0.0f);
|
|
|
|
mySpartan->getTransform().setScale(0.5f);
|
|
|
|
mModels.push_back(mySpartan);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Create simple shapes using MeshRenderer class and data in mesh.h
|
|
|
|
|
|
|
|
mMeshes.push_back(
|
|
|
|
new Qtk::MeshRenderer("rightTriangle", Triangle(QTK_DRAW_ELEMENTS)));
|
|
|
|
mMeshes.back()->getTransform().setTranslation(-5.0f, 0.0f, -2.0f);
|
|
|
|
|
|
|
|
mMeshes.push_back(
|
|
|
|
new Qtk::MeshRenderer("centerCube", Cube(QTK_DRAW_ELEMENTS)));
|
|
|
|
mMeshes.back()->getTransform().setTranslation(-7.0f, 0.0f, -2.0f);
|
|
|
|
|
|
|
|
mMeshes.push_back(
|
|
|
|
new Qtk::MeshRenderer("leftTriangle", Triangle(QTK_DRAW_ELEMENTS)));
|
|
|
|
mMeshes.back()->getTransform().setTranslation(-9.0f, 0.0f, -2.0f);
|
|
|
|
mMeshes.back()->setDrawType(GL_LINE_LOOP);
|
|
|
|
|
|
|
|
mMeshes.push_back(
|
|
|
|
new Qtk::MeshRenderer("topTriangle", Triangle(QTK_DRAW_ELEMENTS)));
|
|
|
|
mMeshes.back()->getTransform().setTranslation(-7.0f, 2.0f, -2.0f);
|
|
|
|
mMeshes.back()->getTransform().scale(0.25f);
|
|
|
|
|
|
|
|
mMeshes.push_back(
|
|
|
|
new Qtk::MeshRenderer("bottomTriangle", Triangle(QTK_DRAW_ELEMENTS)));
|
|
|
|
mMeshes.back()->getTransform().setTranslation(-7.0f, -2.0f, -2.0f);
|
|
|
|
mMeshes.back()->getTransform().scale(0.25f);
|
|
|
|
mMeshes.back()->setDrawType(GL_LINE_LOOP);
|
|
|
|
mMeshes.back()->setColor(GREEN);
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// 3D Model loading
|
|
|
|
|
|
|
|
mModels.push_back(
|
|
|
|
new Qtk::Model("backpack", ":/models/backpack/backpack.obj"));
|
|
|
|
// Sometimes model textures need flipped in certain directions
|
|
|
|
mModels.back()->flipTexture("diffuse.jpg", false, true);
|
|
|
|
mModels.back()->getTransform().setTranslation(0.0f, 0.0f, -10.0f);
|
|
|
|
|
|
|
|
mModels.push_back(new Qtk::Model("bird", ":/models/bird/bird.obj"));
|
|
|
|
mModels.back()->getTransform().setTranslation(2.0f, 2.0f, -10.0f);
|
|
|
|
// Sometimes the models are very large
|
|
|
|
mModels.back()->getTransform().scale(0.0025f);
|
|
|
|
mModels.back()->getTransform().rotate(-110.0f, 0.0f, 1.0f, 0.0f);
|
|
|
|
|
|
|
|
mModels.push_back(new Qtk::Model("lion", ":/models/lion/lion.obj"));
|
|
|
|
mModels.back()->getTransform().setTranslation(-3.0f, -1.0f, -10.0f);
|
|
|
|
mModels.back()->getTransform().scale(0.15f);
|
|
|
|
|
|
|
|
mModels.push_back(
|
|
|
|
new Qtk::Model("alien", ":/models/alien-hominid/alien.obj"));
|
|
|
|
mModels.back()->getTransform().setTranslation(2.0f, -1.0f, -5.0f);
|
|
|
|
mModels.back()->getTransform().scale(0.15f);
|
|
|
|
|
|
|
|
mModels.push_back(new Qtk::Model("scythe", ":/models/scythe/scythe.obj"));
|
|
|
|
mModels.back()->getTransform().setTranslation(-6.0f, 0.0f, -10.0f);
|
|
|
|
mModels.back()->getTransform().rotate(-90.0f, 1.0f, 0.0f, 0.0f);
|
|
|
|
mModels.back()->getTransform().rotate(90.0f, 0.0f, 1.0f, 0.0f);
|
|
|
|
|
|
|
|
mModels.push_back(
|
|
|
|
new Qtk::Model("masterChief", ":/models/spartan/spartan.obj"));
|
|
|
|
mModels.back()->getTransform().setTranslation(-1.5f, 0.5f, -2.0f);
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// Simple cube lighting examples.
|
|
|
|
|
|
|
|
/* Phong lighting example on a basic cube. */
|
2022-08-07 17:12:12 +00:00
|
|
|
mTestPhong = new Qtk::MeshRenderer("phong", Qtk::Cube());
|
2022-11-26 18:24:38 +00:00
|
|
|
mTestPhong->getTransform().setTranslation(3.0f, 0.0f, -2.0f);
|
|
|
|
// NOTE: You no longer need to manually bind shader program to set uniforms.
|
|
|
|
// + You can still bind it if you want to for performance reasons.
|
|
|
|
// + Qtk will only bind / release if the shader program is not already bound.
|
2021-09-19 18:06:41 +00:00
|
|
|
mTestPhong->setShaders(":/solid-phong.vert", ":/solid-phong.frag");
|
2022-11-24 22:26:53 +00:00
|
|
|
|
2022-11-26 18:24:38 +00:00
|
|
|
// For example this would technically not be efficient, because each one of
|
|
|
|
// these calls will bind, set, release. We could instead bind, set N uniforms,
|
|
|
|
// and release when we are finished.
|
2022-11-24 22:26:53 +00:00
|
|
|
// mTestPhong->bindShaders();
|
2021-09-19 18:06:41 +00:00
|
|
|
mTestPhong->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
|
|
|
|
mTestPhong->setUniform("uLightColor", QVector3D(1.0f, 1.0f, 1.0f));
|
|
|
|
mTestPhong->setUniform("uAmbientStrength", 0.2f);
|
|
|
|
mTestPhong->setUniform("uSpecularStrength", 0.50f);
|
|
|
|
mTestPhong->setUniform("uSpecularShine", 256);
|
2022-11-24 22:26:53 +00:00
|
|
|
// mTestPhong->releaseShaders();
|
2022-11-26 18:24:38 +00:00
|
|
|
mTestPhong->reallocateNormals(mTestPhong->getNormals());
|
|
|
|
// NOTE: This is only an example and I won't worry about this kind of
|
|
|
|
// efficiency while initializing the following objects.
|
2021-09-19 18:06:41 +00:00
|
|
|
|
2022-11-26 18:24:38 +00:00
|
|
|
// Phong lighting example light source. This is just for visual reference.
|
|
|
|
// + We refer to the position of this object in draw() to update lighting.
|
|
|
|
mMeshes.push_back(
|
|
|
|
new Qtk::MeshRenderer("phongLight", Triangle(QTK_DRAW_ELEMENTS)));
|
|
|
|
mMeshes.back()->getTransform().setTranslation(3.0f, 2.0f, -2.0f);
|
|
|
|
mMeshes.back()->getTransform().scale(0.25f);
|
|
|
|
|
|
|
|
/* Example of a cube with no lighting applied */
|
|
|
|
mMeshes.push_back(new Qtk::MeshRenderer("noLight", Cube(QTK_DRAW_ELEMENTS)));
|
|
|
|
mMeshes.back()->getTransform().setTranslation(5.0f, 0.0f, -2.0f);
|
|
|
|
mMeshes.back()->setShaders(
|
|
|
|
":/solid-perspective.vert", ":/solid-perspective.frag");
|
|
|
|
mMeshes.back()->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
|
|
|
|
// No light source needed for this lighting technique
|
|
|
|
|
|
|
|
/* Initialize Ambient example cube */
|
2022-08-07 17:12:12 +00:00
|
|
|
mTestAmbient = new Qtk::MeshRenderer("ambient", Cube());
|
2022-11-26 18:24:38 +00:00
|
|
|
mTestAmbient->getTransform().setTranslation(7.0f, 0.0f, -2.0f);
|
2021-09-19 18:06:41 +00:00
|
|
|
mTestAmbient->setShaders(":/solid-ambient.vert", ":/solid-ambient.frag");
|
2022-11-26 18:24:38 +00:00
|
|
|
// Changing these uniform values will alter lighting effects.
|
2021-09-19 18:06:41 +00:00
|
|
|
mTestAmbient->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
|
|
|
|
mTestAmbient->setUniform("uLightColor", QVector3D(1.0f, 1.0f, 1.0f));
|
|
|
|
mTestAmbient->setUniform("uAmbientStrength", 0.2f);
|
2022-11-24 22:26:53 +00:00
|
|
|
mTestAmbient->reallocateNormals(mTestAmbient->getNormals());
|
2022-11-26 18:24:38 +00:00
|
|
|
// No light source needed for this lighting technique
|
2021-09-19 18:06:41 +00:00
|
|
|
|
2022-11-26 18:24:38 +00:00
|
|
|
/* Initialize Diffuse example cube */
|
2022-08-07 17:12:12 +00:00
|
|
|
mTestDiffuse = new Qtk::MeshRenderer("diffuse", Cube());
|
2022-11-26 18:24:38 +00:00
|
|
|
mTestDiffuse->getTransform().setTranslation(9.0f, 0.0f, -2.0f);
|
2021-09-19 18:06:41 +00:00
|
|
|
mTestDiffuse->setShaders(":/solid-diffuse.vert", ":/solid-diffuse.frag");
|
|
|
|
mTestDiffuse->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
|
|
|
|
mTestDiffuse->setUniform("uLightColor", QVector3D(1.0f, 1.0f, 1.0f));
|
|
|
|
mTestDiffuse->setUniform("uAmbientStrength", 0.2f);
|
2022-11-24 22:26:53 +00:00
|
|
|
mTestDiffuse->reallocateNormals(mTestDiffuse->getNormals());
|
2021-09-19 18:06:41 +00:00
|
|
|
|
2022-11-26 18:24:38 +00:00
|
|
|
// Diffuse lighting example light source. This is just for visual reference.
|
|
|
|
mMeshes.push_back(
|
|
|
|
new Qtk::MeshRenderer("diffuseLight", Triangle(QTK_DRAW_ELEMENTS)));
|
|
|
|
mMeshes.back()->getTransform().setTranslation(9.0f, 2.0f, -2.0f);
|
|
|
|
mMeshes.back()->getTransform().scale(0.25f);
|
|
|
|
|
|
|
|
/* Initialize Specular example cube */
|
2022-08-07 17:12:12 +00:00
|
|
|
mTestSpecular = new Qtk::MeshRenderer("specular", Cube());
|
2022-11-26 18:24:38 +00:00
|
|
|
mTestSpecular->getTransform().setTranslation(11.0f, 0.0f, -2.0f);
|
2021-09-19 18:06:41 +00:00
|
|
|
mTestSpecular->setShaders(":/solid-specular.vert", ":/solid-specular.frag");
|
|
|
|
mTestSpecular->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
|
|
|
|
mTestSpecular->setUniform("uLightColor", QVector3D(1.0f, 1.0f, 1.0f));
|
|
|
|
mTestSpecular->setUniform("uAmbientStrength", 0.2f);
|
|
|
|
mTestSpecular->setUniform("uSpecularStrength", 0.50f);
|
|
|
|
mTestSpecular->setUniform("uSpecularShine", 256);
|
2022-11-24 22:26:53 +00:00
|
|
|
mTestSpecular->reallocateNormals(mTestSpecular->getNormals());
|
2021-09-19 18:06:41 +00:00
|
|
|
|
2022-11-26 18:24:38 +00:00
|
|
|
// Specular lighting example light source. This is just for visual reference.
|
|
|
|
mMeshes.push_back(
|
|
|
|
new Qtk::MeshRenderer("specularLight", Triangle(QTK_DRAW_ELEMENTS)));
|
|
|
|
mMeshes.back()->getTransform().setTranslation(11.0f, 2.0f, -2.0f);
|
|
|
|
mMeshes.back()->getTransform().scale(0.25f);
|
2021-09-19 18:06:41 +00:00
|
|
|
|
|
|
|
|
2022-11-26 18:24:38 +00:00
|
|
|
/* Test basic cube with phong.vert and phong.frag shaders */
|
|
|
|
mMeshes.push_back(new Qtk::MeshRenderer("testPhong", Cube(QTK_DRAW_ARRAYS)));
|
|
|
|
mMeshes.back()->getTransform().setTranslation(5.0f, 0.0f, 10.0f);
|
|
|
|
mMeshes.back()->setShaders(":/phong.vert", ":/phong.frag");
|
|
|
|
// WARNING: Set color before reallocating normals.
|
|
|
|
mMeshes.back()->setColor(QVector3D(0.0f, 0.25f, 0.0f));
|
|
|
|
mMeshes.back()->reallocateNormals(mMeshes.back()->getNormals());
|
2021-09-19 18:06:41 +00:00
|
|
|
|
2022-11-26 18:24:38 +00:00
|
|
|
mMeshes.back()->setUniform("uMaterial.ambient", QVector3D(0.0f, 0.3f, 0.0f));
|
|
|
|
mMeshes.back()->setUniform("uMaterial.diffuse", QVector3D(0.0f, 0.2f, 0.0f));
|
|
|
|
mMeshes.back()->setUniform("uMaterial.specular", QVector3D(1.0f, 1.0f, 1.0f));
|
|
|
|
mMeshes.back()->setUniform("uMaterial.ambientStrength", 1.0f);
|
|
|
|
mMeshes.back()->setUniform("uMaterial.diffuseStrength", 1.0f);
|
|
|
|
mMeshes.back()->setUniform("uMaterial.specularStrength", 1.0f);
|
|
|
|
mMeshes.back()->setUniform("uMaterial.shine", 64.0f);
|
|
|
|
mMeshes.back()->setUniform("uLight.ambient", QVector3D(0.25f, 0.2f, 0.075f));
|
|
|
|
mMeshes.back()->setUniform("uLight.diffuse", QVector3D(0.75f, 0.6f, 0.22f));
|
|
|
|
mMeshes.back()->setUniform("uLight.specular", QVector3D(0.62f, 0.55f, 0.37f));
|
|
|
|
mMeshes.back()->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
|
2021-09-19 18:06:41 +00:00
|
|
|
|
2022-11-26 18:24:38 +00:00
|
|
|
// Light source for testPhong cube
|
|
|
|
mMeshes.push_back(
|
|
|
|
new Qtk::MeshRenderer("testLight", Triangle(QTK_DRAW_ELEMENTS)));
|
|
|
|
mMeshes.back()->getTransform().setTranslation(5.0f, 1.25f, 10.0f);
|
|
|
|
mMeshes.back()->getTransform().scale(0.25f);
|
|
|
|
mMeshes.back()->setDrawType(GL_LINE_LOOP);
|
|
|
|
mMeshes.back()->setColor(RED);
|
2021-09-19 18:06:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
//
|
2022-11-26 18:24:38 +00:00
|
|
|
// Building more complex objects for showing examples of lighting techniques
|
2021-09-19 18:06:41 +00:00
|
|
|
|
2022-11-26 18:24:38 +00:00
|
|
|
/* Test alien Model with phong lighting and specular mapping. */
|
2022-11-24 22:26:53 +00:00
|
|
|
mModels.push_back(new Qtk::Model(
|
|
|
|
"alienTest", ":/models/alien-hominid/alien.obj", ":/model-specular.vert",
|
|
|
|
":/model-specular.frag"));
|
2022-11-26 18:24:38 +00:00
|
|
|
mModels.back()->getTransform().setTranslation(3.0f, -1.0f, 10.0f);
|
|
|
|
mModels.back()->getTransform().scale(0.15f);
|
2021-09-19 18:06:41 +00:00
|
|
|
mModels.back()->setUniform("uMaterial.ambient", QVector3D(1.0f, 1.0f, 1.0f));
|
|
|
|
mModels.back()->setUniform("uMaterial.diffuse", QVector3D(1.0f, 1.0f, 1.0f));
|
|
|
|
mModels.back()->setUniform("uMaterial.specular", QVector3D(1.0f, 1.0f, 1.0f));
|
|
|
|
mModels.back()->setUniform("uMaterial.ambientStrength", 0.8f);
|
|
|
|
mModels.back()->setUniform("uMaterial.diffuseStrength", 0.8f);
|
|
|
|
mModels.back()->setUniform("uMaterial.specularStrength", 1.0f);
|
|
|
|
mModels.back()->setUniform("uMaterial.shine", 32.0f);
|
|
|
|
|
|
|
|
mModels.back()->setUniform("uLight.ambient", QVector3D(1.0f, 1.0f, 1.0f));
|
|
|
|
mModels.back()->setUniform("uLight.diffuse", QVector3D(1.0f, 1.0f, 1.0f));
|
|
|
|
mModels.back()->setUniform("uLight.specular", QVector3D(1.0f, 1.0f, 1.0f));
|
|
|
|
|
2022-11-26 18:24:38 +00:00
|
|
|
// Light source for alienTest object.
|
|
|
|
mMeshes.push_back(new Qtk::MeshRenderer(
|
|
|
|
"alienTestLight", Triangle(Qtk::QTK_DRAW_ELEMENTS)));
|
|
|
|
mMeshes.back()->getTransform().setTranslation(4.0f, 1.5f, 10.0f);
|
|
|
|
mMeshes.back()->getTransform().scale(0.25f);
|
2021-09-19 18:06:41 +00:00
|
|
|
// This function changes values we have allocated in a buffer, so init() after
|
|
|
|
mMeshes.back()->setColor(GREEN);
|
|
|
|
|
2022-11-26 18:24:38 +00:00
|
|
|
/* Test spartan Model with phong lighting, specular and normal mapping. */
|
2022-11-24 22:26:53 +00:00
|
|
|
mModels.push_back(new Qtk::Model(
|
|
|
|
"spartanTest", ":/models/spartan/spartan.obj", ":/model-normals.vert",
|
|
|
|
":/model-normals.frag"));
|
2022-11-26 18:24:38 +00:00
|
|
|
mModels.back()->getTransform().setTranslation(0.0f, -1.0f, 10.0f);
|
|
|
|
mModels.back()->getTransform().scale(2.0f);
|
2021-09-19 18:06:41 +00:00
|
|
|
mModels.back()->setUniform("uMaterial.ambient", QVector3D(1.0f, 1.0f, 1.0f));
|
|
|
|
mModels.back()->setUniform("uMaterial.diffuse", QVector3D(1.0f, 1.0f, 1.0f));
|
|
|
|
mModels.back()->setUniform("uMaterial.specular", QVector3D(1.0f, 1.0f, 1.0f));
|
|
|
|
mModels.back()->setUniform("uMaterial.ambientStrength", 1.0f);
|
|
|
|
mModels.back()->setUniform("uMaterial.diffuseStrength", 1.0f);
|
|
|
|
mModels.back()->setUniform("uMaterial.specularStrength", 1.0f);
|
|
|
|
mModels.back()->setUniform("uMaterial.shine", 128.0f);
|
|
|
|
mModels.back()->setUniform("uLight.ambient", QVector3D(1.0f, 1.0f, 1.0f));
|
|
|
|
mModels.back()->setUniform("uLight.diffuse", QVector3D(1.0f, 1.0f, 1.0f));
|
|
|
|
mModels.back()->setUniform("uLight.specular", QVector3D(1.0f, 1.0f, 1.0f));
|
|
|
|
|
2022-11-26 18:24:38 +00:00
|
|
|
// Light source for spartanTest object.
|
2021-09-19 18:06:41 +00:00
|
|
|
mMeshes.push_back(
|
2022-11-26 18:24:38 +00:00
|
|
|
new Qtk::MeshRenderer("spartanTestLight", Triangle(QTK_DRAW_ELEMENTS)));
|
|
|
|
mMeshes.back()->getTransform().setTranslation(1.0f, 1.5f, 10.0f);
|
|
|
|
mMeshes.back()->getTransform().scale(0.25f);
|
2021-09-19 18:06:41 +00:00
|
|
|
// This function changes values we have allocated in a buffer, so init() after
|
|
|
|
mMeshes.back()->setColor(GREEN);
|
|
|
|
|
|
|
|
|
|
|
|
//
|
2022-11-26 18:24:38 +00:00
|
|
|
// Test drawing simple geometry with various OpenGL drawing modes
|
2021-09-19 18:06:41 +00:00
|
|
|
|
|
|
|
// RGB Normals cube to show normals are correct with QTK_DRAW_ARRAYS
|
|
|
|
mMeshes.push_back(
|
2022-08-07 17:12:12 +00:00
|
|
|
new Qtk::MeshRenderer("rgbNormalsCubeArraysTest", Cube(QTK_DRAW_ARRAYS)));
|
2022-11-26 18:24:38 +00:00
|
|
|
mMeshes.back()->getTransform().setTranslation(5.0f, 0.0f, 4.0f);
|
2021-09-19 18:06:41 +00:00
|
|
|
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
|
2022-11-24 22:26:53 +00:00
|
|
|
mMeshes.back()->reallocateNormals(mMeshes.back()->getNormals());
|
2021-09-19 18:06:41 +00:00
|
|
|
|
|
|
|
// RGB Normals cube to show normals are correct with QTK_DRAW_ELEMENTS_NORMALS
|
2022-11-24 22:26:53 +00:00
|
|
|
mMeshes.push_back(new Qtk::MeshRenderer(
|
|
|
|
"rgbNormalsCubeElementsTest", Cube(QTK_DRAW_ELEMENTS_NORMALS)));
|
2022-11-26 18:24:38 +00:00
|
|
|
mMeshes.back()->getTransform().setTranslation(5.0f, 0.0f, 2.0f);
|
2021-09-19 18:06:41 +00:00
|
|
|
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
|
2022-11-24 22:26:53 +00:00
|
|
|
mMeshes.back()->reallocateNormals(mMeshes.back()->getNormals());
|
|
|
|
|
|
|
|
Texture crateTexture;
|
|
|
|
crateTexture.setTexture(":/crate.png");
|
|
|
|
Cube cube;
|
|
|
|
auto * m = new MeshRenderer("Test Crate", Cube(QTK_DRAW_ARRAYS));
|
2022-11-26 18:24:38 +00:00
|
|
|
m->getTransform().setTranslation(0, 0, 13);
|
2022-11-24 22:26:53 +00:00
|
|
|
m->setShaders(":/texture2d.vert", ":/texture2d.frag");
|
|
|
|
m->setTexture(crateTexture);
|
|
|
|
m->setUniform("uTexture", 0);
|
|
|
|
m->reallocateTexCoords(cube.getTexCoords());
|
|
|
|
mMeshes.push_back(m);
|
2021-09-19 18:06:41 +00:00
|
|
|
|
|
|
|
// Texturing a cube using texture coordinates and glDrawArrays
|
2022-11-24 22:26:53 +00:00
|
|
|
// + Texturing with UVs using glDrawElements requires
|
|
|
|
// QTK_DRAW_ELEMENTS_NORMALS
|
2021-09-19 18:06:41 +00:00
|
|
|
// + UVs required duplicating element position data from QTK_DRAW_ELEMENTS
|
|
|
|
// + This is because the same position must use different UV coordinates
|
|
|
|
mMeshes.push_back(
|
2022-08-07 17:12:12 +00:00
|
|
|
new Qtk::MeshRenderer("uvCubeArraysTest", Cube(QTK_DRAW_ARRAYS)));
|
2022-11-26 18:24:38 +00:00
|
|
|
mMeshes.back()->getTransform().setTranslation(-3.0f, 0.0f, -2.0f);
|
2021-09-19 18:06:41 +00:00
|
|
|
mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag");
|
2022-11-24 22:26:53 +00:00
|
|
|
mMeshes.back()->setTexture(crateTexture);
|
2021-09-19 18:06:41 +00:00
|
|
|
mMeshes.back()->setUniform("uTexture", 0);
|
2022-11-24 22:26:53 +00:00
|
|
|
mMeshes.back()->reallocateTexCoords(mMeshes.back()->getTexCoords());
|
2021-09-19 18:06:41 +00:00
|
|
|
|
|
|
|
// Test drawing a cube with texture coordinates using glDrawElements
|
2022-11-24 22:26:53 +00:00
|
|
|
mMeshes.push_back(new Qtk::MeshRenderer(
|
|
|
|
"uvCubeElementsTest", Cube(QTK_DRAW_ELEMENTS_NORMALS)));
|
2022-11-26 18:24:38 +00:00
|
|
|
mMeshes.back()->getTransform().setTranslation(-1.7f, 0.0f, -2.0f);
|
2022-11-24 22:26:53 +00:00
|
|
|
mMeshes.back()->setTexture(":/crate.png");
|
2021-09-19 18:06:41 +00:00
|
|
|
mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag");
|
2022-11-24 22:26:53 +00:00
|
|
|
mMeshes.back()->bindShaders();
|
|
|
|
mMeshes.back()->setUniform("uTexture", 0);
|
|
|
|
mMeshes.back()->reallocateNormals(mMeshes.back()->getNormals());
|
|
|
|
mMeshes.back()->reallocateTexCoords(mMeshes.back()->getTexCoords(), 3);
|
|
|
|
mMeshes.back()->releaseShaders();
|
2022-11-26 18:24:38 +00:00
|
|
|
mMeshes.back()->getTransform().rotate(45.0f, 0.0f, 1.0f, 0.0f);
|
2021-09-19 18:06:41 +00:00
|
|
|
|
|
|
|
// Texturing a cube using a cube map
|
|
|
|
// + Cube map texturing works with both QTK_DRAW_ARRAYS and QTK_DRAW_ELEMENTS
|
|
|
|
mMeshes.push_back(
|
2022-08-07 17:12:12 +00:00
|
|
|
new Qtk::MeshRenderer("testCubeMap", Cube(QTK_DRAW_ELEMENTS)));
|
2022-11-26 18:24:38 +00:00
|
|
|
mMeshes.back()->getTransform().setTranslation(-3.0f, 1.0f, -2.0f);
|
|
|
|
mMeshes.back()->getTransform().setRotation(45.0f, 0.0f, 1.0f, 0.0f);
|
2022-11-24 22:26:53 +00:00
|
|
|
mMeshes.back()->setShaders(
|
|
|
|
":/texture-cubemap.vert", ":/texture-cubemap.frag");
|
|
|
|
mMeshes.back()->setCubeMap(":/crate.png");
|
2021-09-19 18:06:41 +00:00
|
|
|
mMeshes.back()->setUniform("uTexture", 0);
|
2022-11-24 22:26:53 +00:00
|
|
|
mMeshes.back()->reallocateTexCoords(mMeshes.back()->getTexCoords());
|
2021-09-19 18:06:41 +00:00
|
|
|
|
|
|
|
// Create a cube with custom shaders
|
|
|
|
// + Apply RGB normals shader and spin the cube for a neat effect
|
|
|
|
mMeshes.push_back(
|
2022-08-07 17:12:12 +00:00
|
|
|
new Qtk::MeshRenderer("rgbNormalsCube", Cube(QTK_DRAW_ARRAYS)));
|
2022-11-26 18:24:38 +00:00
|
|
|
mMeshes.back()->getTransform().setTranslation(5.0f, 2.0f, -2.0f);
|
2021-09-19 18:06:41 +00:00
|
|
|
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
|
2022-11-24 22:26:53 +00:00
|
|
|
mMeshes.back()->reallocateNormals(mMeshes.back()->getNormals());
|
2021-09-19 18:06:41 +00:00
|
|
|
|
|
|
|
// RGB Normals triangle to show normals are correct with QTK_DRAW_ARRAYS
|
2022-11-24 22:26:53 +00:00
|
|
|
mMeshes.push_back(new Qtk::MeshRenderer(
|
|
|
|
"rgbTriangleArraysTest", Triangle(QTK_DRAW_ARRAYS)));
|
2022-11-26 18:24:38 +00:00
|
|
|
mMeshes.back()->getTransform().setTranslation(7.0f, 0.0f, 2.0f);
|
2021-09-19 18:06:41 +00:00
|
|
|
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
|
2022-11-24 22:26:53 +00:00
|
|
|
mMeshes.back()->reallocateNormals(mMeshes.back()->getNormals());
|
2021-09-19 18:06:41 +00:00
|
|
|
|
|
|
|
// RGB Normals triangle to show normals are correct with QTK_DRAW_ELEMENTS
|
2022-11-24 22:26:53 +00:00
|
|
|
mMeshes.push_back(new Qtk::MeshRenderer(
|
|
|
|
"rgbTriangleElementsTest", Triangle(QTK_DRAW_ELEMENTS_NORMALS)));
|
2022-11-26 18:24:38 +00:00
|
|
|
mMeshes.back()->getTransform().setTranslation(7.0f, 0.0f, 4.0f);
|
2021-09-19 18:06:41 +00:00
|
|
|
mMeshes.back()->setShaders(":/rgb-normals.vert", ":/rgb-normals.frag");
|
2022-11-24 22:26:53 +00:00
|
|
|
mMeshes.back()->reallocateNormals(mMeshes.back()->getNormals());
|
2021-09-19 18:06:41 +00:00
|
|
|
|
|
|
|
// Test drawing triangle with glDrawArrays with texture coordinates
|
|
|
|
mMeshes.push_back(
|
2022-08-07 17:12:12 +00:00
|
|
|
new Qtk::MeshRenderer("testTriangleArraysUV", Triangle(QTK_DRAW_ARRAYS)));
|
2022-11-26 18:24:38 +00:00
|
|
|
mMeshes.back()->getTransform().setTranslation(-3.0f, 2.0f, -2.0f);
|
2021-09-19 18:06:41 +00:00
|
|
|
mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag");
|
|
|
|
|
2022-11-24 22:26:53 +00:00
|
|
|
mMeshes.back()->setTexture(":/crate.png");
|
2021-09-19 18:06:41 +00:00
|
|
|
mMeshes.back()->setUniform("uTexture", 0);
|
2022-11-24 22:26:53 +00:00
|
|
|
mMeshes.back()->reallocateTexCoords(mMeshes.back()->getTexCoords());
|
2021-09-19 18:06:41 +00:00
|
|
|
|
|
|
|
// Test drawing triangle with glDrawElements with texture coordinates
|
2022-11-24 22:26:53 +00:00
|
|
|
mMeshes.push_back(new Qtk::MeshRenderer(
|
|
|
|
"testTriangleElementsUV", Triangle(QTK_DRAW_ELEMENTS_NORMALS)));
|
2022-11-26 18:24:38 +00:00
|
|
|
mMeshes.back()->getTransform().setTranslation(-2.5f, 0.0f, -1.0f);
|
2021-09-19 18:06:41 +00:00
|
|
|
mMeshes.back()->setShaders(":/texture2d.vert", ":/texture2d.frag");
|
2022-11-24 22:26:53 +00:00
|
|
|
mMeshes.back()->setTexture(":/crate.png");
|
2021-09-19 18:06:41 +00:00
|
|
|
mMeshes.back()->setUniform("uTexture", 0);
|
2022-11-24 22:26:53 +00:00
|
|
|
mMeshes.back()->reallocateTexCoords(mMeshes.back()->getTexCoords());
|
2021-09-19 18:06:41 +00:00
|
|
|
}
|
|
|
|
|
2022-11-24 22:26:53 +00:00
|
|
|
void ExampleScene::draw() {
|
2022-11-26 18:24:38 +00:00
|
|
|
// WARNING: We must call the base class draw() function first.
|
|
|
|
// + This will handle rendering core scene components like the Skybox.
|
2022-08-14 21:02:50 +00:00
|
|
|
Scene::draw();
|
2021-09-19 18:06:41 +00:00
|
|
|
|
2022-11-24 22:26:53 +00:00
|
|
|
for(const auto & model : mModels) {
|
|
|
|
model->draw();
|
|
|
|
}
|
|
|
|
|
|
|
|
for(const auto & mesh : mMeshes) {
|
|
|
|
mesh->draw();
|
|
|
|
}
|
|
|
|
|
|
|
|
mTestPhong->bindShaders();
|
|
|
|
mTestPhong->setUniform(
|
|
|
|
"uModelInverseTransposed",
|
2022-11-26 18:24:38 +00:00
|
|
|
mTestPhong->getTransform().toMatrix().normalMatrix());
|
2021-09-19 18:06:41 +00:00
|
|
|
mTestPhong->setUniform(
|
|
|
|
"uLightPosition",
|
2022-11-26 18:24:38 +00:00
|
|
|
MeshRenderer::getInstance("phongLight")->getTransform().getTranslation());
|
2022-11-24 22:26:53 +00:00
|
|
|
mTestPhong->setUniform(
|
2022-11-26 18:24:38 +00:00
|
|
|
"uCameraPosition",
|
|
|
|
ExampleScene::getCamera().getTransform().getTranslation());
|
2022-11-24 22:26:53 +00:00
|
|
|
mTestPhong->releaseShaders();
|
2021-09-19 18:06:41 +00:00
|
|
|
mTestPhong->draw();
|
|
|
|
|
2022-11-24 22:26:53 +00:00
|
|
|
mTestAmbient->bindShaders();
|
|
|
|
mTestAmbient->setUniform(
|
2022-11-26 18:24:38 +00:00
|
|
|
"uCameraPosition",
|
|
|
|
ExampleScene::getCamera().getTransform().getTranslation());
|
2022-11-24 22:26:53 +00:00
|
|
|
mTestAmbient->releaseShaders();
|
2021-09-19 18:06:41 +00:00
|
|
|
mTestAmbient->draw();
|
|
|
|
|
2022-11-24 22:26:53 +00:00
|
|
|
mTestDiffuse->bindShaders();
|
|
|
|
mTestDiffuse->setUniform(
|
|
|
|
"uModelInverseTransposed",
|
2022-11-26 18:24:38 +00:00
|
|
|
mTestDiffuse->getTransform().toMatrix().normalMatrix());
|
2021-09-19 18:06:41 +00:00
|
|
|
mTestDiffuse->setUniform(
|
2022-11-26 18:24:38 +00:00
|
|
|
"uLightPosition", MeshRenderer::getInstance("diffuseLight")
|
|
|
|
->getTransform()
|
|
|
|
.getTranslation());
|
2022-11-24 22:26:53 +00:00
|
|
|
mTestDiffuse->setUniform(
|
2022-11-26 18:24:38 +00:00
|
|
|
"uCameraPosition",
|
|
|
|
ExampleScene::getCamera().getTransform().getTranslation());
|
2022-11-24 22:26:53 +00:00
|
|
|
mTestDiffuse->releaseShaders();
|
2021-09-19 18:06:41 +00:00
|
|
|
mTestDiffuse->draw();
|
|
|
|
|
2022-11-24 22:26:53 +00:00
|
|
|
mTestSpecular->bindShaders();
|
2021-09-19 18:06:41 +00:00
|
|
|
mTestSpecular->setUniform(
|
|
|
|
"uModelInverseTransposed",
|
2022-11-26 18:24:38 +00:00
|
|
|
mTestSpecular->getTransform().toMatrix().normalMatrix());
|
2021-09-19 18:06:41 +00:00
|
|
|
mTestSpecular->setUniform(
|
2022-11-26 18:24:38 +00:00
|
|
|
"uLightPosition", MeshRenderer::getInstance("specularLight")
|
|
|
|
->getTransform()
|
|
|
|
.getTranslation());
|
2022-11-24 22:26:53 +00:00
|
|
|
mTestSpecular->setUniform(
|
2022-11-26 18:24:38 +00:00
|
|
|
"uCameraPosition",
|
|
|
|
ExampleScene::getCamera().getTransform().getTranslation());
|
2022-11-24 22:26:53 +00:00
|
|
|
mTestSpecular->releaseShaders();
|
2021-09-19 18:06:41 +00:00
|
|
|
mTestSpecular->draw();
|
|
|
|
}
|
|
|
|
|
2022-11-24 22:26:53 +00:00
|
|
|
void ExampleScene::update() {
|
2022-11-26 18:24:38 +00:00
|
|
|
auto mySpartan = Model::getInstance("My spartan");
|
|
|
|
mySpartan->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f);
|
|
|
|
|
|
|
|
auto myCube = MeshRenderer::getInstance("My cube");
|
|
|
|
myCube->getTransform().rotate(-0.75f, 0.0f, 1.0f, 0.0f);
|
|
|
|
|
|
|
|
auto position = MeshRenderer::getInstance("alienTestLight")
|
|
|
|
->getTransform()
|
|
|
|
.getTranslation();
|
2022-11-24 22:26:53 +00:00
|
|
|
auto alien = Model::getInstance("alienTest");
|
|
|
|
alien->setUniform("uLight.position", position);
|
|
|
|
alien->setUniform(
|
2022-11-26 18:24:38 +00:00
|
|
|
"uCameraPosition",
|
|
|
|
ExampleScene::getCamera().getTransform().getTranslation());
|
|
|
|
auto posMatrix = alien->getTransform().toMatrix();
|
2022-11-24 22:26:53 +00:00
|
|
|
alien->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
|
|
|
|
alien->setUniform("uMVP.model", posMatrix);
|
2022-11-26 18:24:38 +00:00
|
|
|
alien->setUniform("uMVP.view", ExampleScene::getCamera().toMatrix());
|
|
|
|
alien->setUniform("uMVP.projection", ExampleScene::getProjectionMatrix());
|
|
|
|
alien->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f);
|
2022-11-24 22:26:53 +00:00
|
|
|
|
|
|
|
position = MeshRenderer::getInstance("spartanTestLight")
|
2022-11-26 18:24:38 +00:00
|
|
|
->getTransform()
|
|
|
|
.getTranslation();
|
2022-11-24 22:26:53 +00:00
|
|
|
auto spartan = Model::getInstance("spartanTest");
|
|
|
|
spartan->setUniform("uLight.position", position);
|
|
|
|
spartan->setUniform(
|
2022-11-26 18:24:38 +00:00
|
|
|
"uCameraPosition",
|
|
|
|
ExampleScene::getCamera().getTransform().getTranslation());
|
|
|
|
posMatrix = spartan->getTransform().toMatrix();
|
2022-11-24 22:26:53 +00:00
|
|
|
spartan->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
|
|
|
|
spartan->setUniform("uMVP.model", posMatrix);
|
2022-11-26 18:24:38 +00:00
|
|
|
spartan->setUniform("uMVP.view", ExampleScene::getCamera().toMatrix());
|
|
|
|
spartan->setUniform("uMVP.projection", ExampleScene::getProjectionMatrix());
|
|
|
|
spartan->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f);
|
2022-11-24 22:26:53 +00:00
|
|
|
|
|
|
|
auto phong = MeshRenderer::getInstance("testPhong");
|
2022-11-26 18:24:38 +00:00
|
|
|
phong->getTransform().rotate(0.75f, 1.0f, 0.5f, 0.0f);
|
2022-11-24 22:26:53 +00:00
|
|
|
phong->bindShaders();
|
|
|
|
position =
|
2022-11-26 18:24:38 +00:00
|
|
|
MeshRenderer::getInstance("testLight")->getTransform().getTranslation();
|
2022-11-24 22:26:53 +00:00
|
|
|
phong->setUniform("uLight.position", position);
|
|
|
|
phong->setUniform(
|
2022-11-26 18:24:38 +00:00
|
|
|
"uCameraPosition",
|
|
|
|
ExampleScene::getCamera().getTransform().getTranslation());
|
|
|
|
posMatrix = phong->getTransform().toMatrix();
|
2022-11-24 22:26:53 +00:00
|
|
|
phong->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
|
|
|
|
phong->setUniform("uMVP.model", posMatrix);
|
2022-11-26 18:24:38 +00:00
|
|
|
phong->setUniform("uMVP.view", ExampleScene::getCamera().toMatrix());
|
|
|
|
phong->setUniform("uMVP.projection", ExampleScene::getProjectionMatrix());
|
2022-11-24 22:26:53 +00:00
|
|
|
phong->releaseShaders();
|
2021-09-19 18:06:41 +00:00
|
|
|
|
|
|
|
// Rotate lighting example cubes
|
2022-11-26 18:24:38 +00:00
|
|
|
mTestPhong->getTransform().rotate(0.75f, 0.5f, 0.3f, 0.2f);
|
|
|
|
MeshRenderer::getInstance("noLight")->getTransform().rotate(
|
2021-09-19 18:06:41 +00:00
|
|
|
0.75f, 0.5f, 0.3f, 0.2f);
|
2022-11-26 18:24:38 +00:00
|
|
|
mTestAmbient->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);
|
2021-09-19 18:06:41 +00:00
|
|
|
|
|
|
|
// Examples of various translations and rotations
|
|
|
|
|
|
|
|
// Rotate in multiple directions simultaneously
|
2022-11-24 22:26:53 +00:00
|
|
|
MeshRenderer::getInstance("rgbNormalsCube")
|
2022-11-26 18:24:38 +00:00
|
|
|
->getTransform()
|
|
|
|
.rotate(0.75f, 0.2f, 0.4f, 0.6f);
|
2021-09-19 18:06:41 +00:00
|
|
|
|
|
|
|
// Pitch forward and roll sideways
|
2022-11-24 22:26:53 +00:00
|
|
|
MeshRenderer::getInstance("leftTriangle")
|
2022-11-26 18:24:38 +00:00
|
|
|
->getTransform()
|
|
|
|
.rotate(0.75f, 1.0f, 0.0f, 0.0f);
|
2022-11-24 22:26:53 +00:00
|
|
|
MeshRenderer::getInstance("rightTriangle")
|
2022-11-26 18:24:38 +00:00
|
|
|
->getTransform()
|
|
|
|
.rotate(0.75f, 0.0f, 0.0f, 1.0f);
|
2021-09-19 18:06:41 +00:00
|
|
|
|
|
|
|
// Move between two positions over time
|
|
|
|
static float translateX = 0.025f;
|
2022-11-24 22:26:53 +00:00
|
|
|
float limit = -9.0f; // Origin position.x - 2.0f
|
2022-11-26 18:24:38 +00:00
|
|
|
float posX = MeshRenderer::getInstance("topTriangle")
|
|
|
|
->getTransform()
|
|
|
|
.getTranslation()
|
|
|
|
.x();
|
2022-11-24 22:26:53 +00:00
|
|
|
if(posX < limit || posX > limit + 4.0f) {
|
2021-09-19 18:06:41 +00:00
|
|
|
translateX = -translateX;
|
|
|
|
}
|
2022-11-24 22:26:53 +00:00
|
|
|
MeshRenderer::getInstance("topTriangle")
|
2022-11-26 18:24:38 +00:00
|
|
|
->getTransform()
|
|
|
|
.translate(translateX, 0.0f, 0.0f);
|
2022-11-24 22:26:53 +00:00
|
|
|
MeshRenderer::getInstance("bottomTriangle")
|
2022-11-26 18:24:38 +00:00
|
|
|
->getTransform()
|
|
|
|
.translate(-translateX, 0.0f, 0.0f);
|
2021-09-19 18:06:41 +00:00
|
|
|
// And lets rotate the triangles in two directions at once
|
2022-11-24 22:26:53 +00:00
|
|
|
MeshRenderer::getInstance("topTriangle")
|
2022-11-26 18:24:38 +00:00
|
|
|
->getTransform()
|
|
|
|
.rotate(0.75f, 0.2f, 0.0f, 0.4f);
|
2022-11-24 22:26:53 +00:00
|
|
|
MeshRenderer::getInstance("bottomTriangle")
|
2022-11-26 18:24:38 +00:00
|
|
|
->getTransform()
|
|
|
|
.rotate(0.75f, 0.0f, 0.2f, 0.4f);
|
2021-09-19 18:06:41 +00:00
|
|
|
// And make the bottom triangle green, instead of RGB
|
|
|
|
|
|
|
|
// Rotate center cube in several directions simultaneously
|
|
|
|
// + Not subject to gimbal lock since we are using quaternions :)
|
2022-11-24 22:26:53 +00:00
|
|
|
MeshRenderer::getInstance("centerCube")
|
2022-11-26 18:24:38 +00:00
|
|
|
->getTransform()
|
|
|
|
.rotate(0.75f, 0.2f, 0.4f, 0.6f);
|
2021-09-19 18:06:41 +00:00
|
|
|
}
|