tutorial 04

This commit is contained in:
h4570
2022-08-22 23:23:51 +02:00
parent 4fa65fc535
commit d469e78747
26 changed files with 400 additions and 96 deletions
@@ -44,6 +44,8 @@ class Tutorial03 : public Game {
* - Minecraft (this one)
* - Static (for static 3D objects)
* - Dynamic (for dynamic 3D objects)
*
* You can create your own VU1 programs and create your custom pipelines!
*/
MinecraftPipeline mcpip;
+44
View File
@@ -0,0 +1,44 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tyra>
namespace Tyra {
class Camera {
public:
Camera(Pad* pad);
~Camera();
Vec4 lookAt;
Vec4 position;
/**
* Result variable of unit circle calculation
* This is needed for rotation about the camera lookAt
* https://www.geogebra.org/m/cNEtsbvC
*/
Vec4 unitCircle;
CameraInfo3D getCameraInfo() { return CameraInfo3D(&position, &lookAt); }
void update();
private:
void updatePosition();
void updateLookAt();
Pad* pad;
float circleRotation, circleLength, speed, lookAtHeight;
};
} // namespace Tyra
+10 -1
View File
@@ -12,6 +12,7 @@
#include <tyra>
#include <memory.h>
#include "./camera.hpp"
namespace Tyra {
@@ -28,8 +29,16 @@ class Tutorial04 : public Game {
Engine* engine;
std::unique_ptr<StaticMesh> mesh;
Camera camera;
/** 3D pipeline used for rendering static meshes */
StaticPipeline stapip;
/** Options for static pipeline */
StaPipOptions renderOptions;
/** Mesh with de_dust2 */
std::unique_ptr<StaticMesh> mesh;
};
} // namespace Tyra
+85
View File
@@ -0,0 +1,85 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "camera.hpp"
namespace Tyra {
Camera::Camera(Pad* t_pad)
: lookAt(0.0F),
position(-2000.0F, 0.0F, -6000.0F),
pad(t_pad),
circleRotation(-5.0F),
circleLength(30.0F),
speed(20.0F),
lookAtHeight(-4.0F) {}
Camera::~Camera() {}
void Camera::update() {
updatePosition();
updateLookAt();
}
/**
* Move camera position via left joystick
*/
void Camera::updatePosition() {
const auto& leftJoy = pad->getLeftJoyPad();
auto direction = Vec4(unitCircle).getNormalized() * speed;
if (leftJoy.v <= 100) {
position.x += direction.x;
position.z += direction.z;
} else if (leftJoy.v >= 200) {
position.x += -direction.x;
position.z += -direction.z;
}
if (leftJoy.h <= 100) {
position.x += direction.z;
position.z += -direction.x;
} else if (leftJoy.h >= 200) {
position.x += -direction.z;
position.z += direction.x;
}
/** Camera height */
position.y = 700.0F;
}
/**
* Move camera lookAt position via right joystick
*/
void Camera::updateLookAt() {
const float rotationOffset = 0.045F;
const float heightOffset = 2.0F;
const auto& rightJoy = pad->getRightJoyPad();
if (rightJoy.h <= 100) {
circleRotation -= rotationOffset;
} else if (rightJoy.h >= 200) {
circleRotation += rotationOffset;
}
if (rightJoy.v <= 100) {
lookAtHeight -= heightOffset;
} else if (rightJoy.v >= 200) {
lookAtHeight += heightOffset;
}
unitCircle.x = Math::sin(circleRotation) * circleLength;
unitCircle.y = lookAtHeight;
unitCircle.z = Math::cos(circleRotation) * circleLength;
lookAt = unitCircle + position;
}
} // namespace Tyra
+45 -6
View File
@@ -13,25 +13,64 @@
namespace Tyra {
Tutorial04::Tutorial04(Engine* t_engine) : engine(t_engine) {}
Tutorial04::Tutorial04(Engine* t_engine)
: engine(t_engine), camera(&t_engine->pad) {}
Tutorial04::~Tutorial04() {
engine->renderer.getTextureRepository().freeByMesh(mesh.get());
}
void Tutorial04::init() { loadMesh(); }
void Tutorial04::init() {
stapip.setRenderer(&engine->renderer.core);
loadMesh();
}
void Tutorial04::loop() {}
void Tutorial04::loop() {
/** Update camera's lookAt and position */
camera.update();
engine->renderer.beginFrame(camera.getCameraInfo());
{
/** Upload static pipeline's VU1 programs */
engine->renderer.renderer3D.usePipeline(stapip);
/**
* Render de_dust2.
*
* As you see there are clipping issues (visual glitches).
* If you want to know how to fix it, please
* watch video tutorial.
*/
stapip.render(mesh.get(), renderOptions);
}
engine->renderer.endFrame();
}
void Tutorial04::loadMesh() {
ObjLoader loader;
ObjLoaderOptions options;
options.flipUVs = true;
options.scale = 200.0F;
auto data = loader.load(FileUtils::fromCwd("de_dust2/de_dust2.obj"), options);
/**
* Load mesh data
* Texture names are the material names "usemtl <material name>"
*/
auto data =
ObjLoader::load(FileUtils::fromCwd("de_dust2/de_dust2.obj"), options);
/** Create mesh with loaded data */
mesh = std::make_unique<StaticMesh>(data.get());
/**
* Disable frustum culling in render options,
* because it not make sense to perform
* frustum check on entire map (which will be always visible)
*/
renderOptions.frustumCulling = Tyra::PipelineFrustumCulling_None;
/**
* Function which load all textures into texture repository,
* based on material names.
*/
engine->renderer.getTextureRepository().addByMesh(
mesh.get(), FileUtils::fromCwd("de_dust2/"), "png");
}