tutorial 1 and 2
This commit is contained in:
+5
-5
@@ -1,9 +1,5 @@
|
|||||||
------------ Tyra's v2.0 roadmap to publish on GitHub ------------
|
------------ Tyra's v2.0 roadmap to publish on GitHub ------------
|
||||||
|
|
||||||
- [General] CI in Github via docker image
|
|
||||||
|
|
||||||
- [Tutorials] 1. Hello world! - explain init(), loop() and what should be inside them (every tutorial should be well commented!)
|
|
||||||
|
|
||||||
- [Tutorials] 2. 2D - explain beginFrame(), endFrame()
|
- [Tutorials] 2. 2D - explain beginFrame(), endFrame()
|
||||||
|
|
||||||
- [Tutorials] 3. Minecraft cube - explain this pipeline, and explain that there are many 3D pipelines
|
- [Tutorials] 3. Minecraft cube - explain this pipeline, and explain that there are many 3D pipelines
|
||||||
@@ -15,12 +11,15 @@ abstract 3D object class, and what it have (animation etc)
|
|||||||
explain that this is lower-level abstract rendering, it have the all the features as Mesh rendering,
|
explain that this is lower-level abstract rendering, it have the all the features as Mesh rendering,
|
||||||
because Mesh rendering uses only core.render()
|
because Mesh rendering uses only core.render()
|
||||||
|
|
||||||
- [Tutorials] 6. Animation in Mesh rendering rendering, explain the API
|
- [Tutorials] 6. Animation in Mesh rendering, explain the API
|
||||||
|
|
||||||
- [Tutorials] 7. Directional lights in Mesh rendering
|
- [Tutorials] 7. Directional lights in Mesh rendering
|
||||||
|
|
||||||
- [Tutorials] 8. Render skybox, and show that stdPipOptions.noClipChecks must be set to false, to turn on clip algorithms (prevent glitches)
|
- [Tutorials] 8. Render skybox, and show that stdPipOptions.noClipChecks must be set to false, to turn on clip algorithms (prevent glitches)
|
||||||
|
|
||||||
|
- own game
|
||||||
|
- usb
|
||||||
|
|
||||||
- [General] Check all left TODOs -> Github issues
|
- [General] Check all left TODOs -> Github issues
|
||||||
|
|
||||||
- [General] Readme Credits: clipping, obj loader
|
- [General] Readme Credits: clipping, obj loader
|
||||||
@@ -28,6 +27,7 @@ because Mesh rendering uses only core.render()
|
|||||||
------------ Github issues for Tyra v2 ------------
|
------------ Github issues for Tyra v2 ------------
|
||||||
- [Demo] porzadek z konstruktorami bbox
|
- [Demo] porzadek z konstruktorami bbox
|
||||||
- [renderer] fog
|
- [renderer] fog
|
||||||
|
- [General] CI in Github via docker image
|
||||||
- [renderer] bbox parts optimization
|
- [renderer] bbox parts optimization
|
||||||
- [General] smart pointers and std::array instead of raw pointers
|
- [General] smart pointers and std::array instead of raw pointers
|
||||||
- [md2] refactor
|
- [md2] refactor
|
||||||
|
|||||||
@@ -19,7 +19,16 @@ class FileUtils {
|
|||||||
FileUtils();
|
FileUtils();
|
||||||
~FileUtils();
|
~FileUtils();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get current working directory.
|
||||||
|
* Example: "host:" or "mass:"
|
||||||
|
*/
|
||||||
static std::string getCwd();
|
static std::string getCwd();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add current working directory prefix to path
|
||||||
|
* Example: "host:..." or "mass:..."
|
||||||
|
*/
|
||||||
static std::string fromCwd(const std::string& relativePath);
|
static std::string fromCwd(const std::string& relativePath);
|
||||||
static std::string fromCwd(const char* relativePath);
|
static std::string fromCwd(const char* relativePath);
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,17 @@ namespace Tyra {
|
|||||||
|
|
||||||
class Packet2TyraUtils {
|
class Packet2TyraUtils {
|
||||||
public:
|
public:
|
||||||
|
inline static void addUnpackData(packet2_t* packet2,
|
||||||
|
const u32& t_dest_address,
|
||||||
|
const void* t_data, const u32& t_size,
|
||||||
|
const u8& t_use_top) {
|
||||||
|
packet2_chain_ref(packet2, t_data, t_size, 0, 0, 0);
|
||||||
|
packet2_vif_stcycl(packet2, 0, 0x0101, 0);
|
||||||
|
packet2_vif_open_unpack(packet2, P2_UNPACK_V4_32, t_dest_address, t_use_top,
|
||||||
|
0, 1, 0);
|
||||||
|
packet2_vif_close_unpack_manual(packet2, t_size);
|
||||||
|
}
|
||||||
|
|
||||||
inline static void addM4x4(packet2_t* packet2, const M4x4& val) {
|
inline static void addM4x4(packet2_t* packet2, const M4x4& val) {
|
||||||
*(reinterpret_cast<M4x4*>(packet2->next)) = val;
|
*(reinterpret_cast<M4x4*>(packet2->next)) = val;
|
||||||
packet2_advance_next(packet2, sizeof(MATRIX));
|
packet2_advance_next(packet2, sizeof(MATRIX));
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ class Renderer2D {
|
|||||||
~Renderer2D();
|
~Renderer2D();
|
||||||
|
|
||||||
void init(RendererCore* rendererCore);
|
void init(RendererCore* rendererCore);
|
||||||
void render(Sprite* sprite);
|
void render(const Sprite* sprite);
|
||||||
|
void render(const Sprite& sprite);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RendererCore* core;
|
RendererCore* core;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class DynPipColorBag {
|
|||||||
~DynPipColorBag();
|
~DynPipColorBag();
|
||||||
|
|
||||||
/** Mandatory */
|
/** Mandatory */
|
||||||
Color* single;
|
const Color* single;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Tyra
|
} // namespace Tyra
|
||||||
|
|||||||
@@ -45,7 +45,8 @@ class DynamicPipeline : public Renderer3DPipeline {
|
|||||||
* Render dynamic model.
|
* Render dynamic model.
|
||||||
* This render() method is a bridge to core.render() method.
|
* This render() method is a bridge to core.render() method.
|
||||||
*/
|
*/
|
||||||
void render(DynamicMesh* mesh, const DynPipOptions* options = nullptr);
|
void render(const DynamicMesh& mesh, const DynPipOptions* options = nullptr);
|
||||||
|
void render(const DynamicMesh* mesh, const DynPipOptions* options = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RendererCore* rendererCore;
|
RendererCore* rendererCore;
|
||||||
@@ -57,29 +58,29 @@ class DynamicPipeline : public Renderer3DPipeline {
|
|||||||
|
|
||||||
void sendRestOfBuffers(DynPipBag* buffers, u16* bufferIndex);
|
void sendRestOfBuffers(DynPipBag* buffers, u16* bufferIndex);
|
||||||
|
|
||||||
void addVertices(MeshMaterialFrame* materialFrameFrom,
|
void addVertices(const MeshMaterialFrame* materialFrameFrom,
|
||||||
MeshMaterialFrame* materialFrameTo, DynPipBag* bag,
|
const MeshMaterialFrame* materialFrameTo, DynPipBag* bag,
|
||||||
const u32& startIndex) const;
|
const u32& startIndex) const;
|
||||||
|
|
||||||
DynPipInfoBag* getInfoBag(DynamicMesh* mesh, const DynPipOptions* options,
|
DynPipInfoBag* getInfoBag(const DynamicMesh* mesh,
|
||||||
M4x4* model) const;
|
const DynPipOptions* options, M4x4* model) const;
|
||||||
|
|
||||||
DynPipColorBag* getColorBag(MeshMaterial* material) const;
|
DynPipColorBag* getColorBag(const MeshMaterial* material) const;
|
||||||
|
|
||||||
DynPipTextureBag* getTextureBag(Texture* texture,
|
DynPipTextureBag* getTextureBag(Texture* texture,
|
||||||
MeshMaterialFrame* materialFrameFrom,
|
const MeshMaterialFrame* materialFrameFrom,
|
||||||
MeshMaterialFrame* materialFrameTo,
|
const MeshMaterialFrame* materialFrameTo,
|
||||||
const u32& startIndex);
|
const u32& startIndex);
|
||||||
|
|
||||||
DynPipLightingBag* getLightingBag(MeshMaterialFrame* materialFrameFrom,
|
DynPipLightingBag* getLightingBag(const MeshMaterialFrame* materialFrameFrom,
|
||||||
MeshMaterialFrame* materialFrameTo,
|
const MeshMaterialFrame* materialFrameTo,
|
||||||
M4x4* model, const DynPipOptions* options,
|
M4x4* model, const DynPipOptions* options,
|
||||||
PipelineDirLightsBag* dirLightsBag,
|
PipelineDirLightsBag* dirLightsBag,
|
||||||
const u32& startIndex) const;
|
const u32& startIndex) const;
|
||||||
|
|
||||||
void setLightingColorsCache(PipelineLightingOptions* lightingOptions);
|
void setLightingColorsCache(PipelineLightingOptions* lightingOptions);
|
||||||
void freeBuffer(DynPipBag* bag);
|
void freeBuffer(DynPipBag* bag);
|
||||||
void setBuffersDefaultVars(DynPipBag* buffers, DynamicMesh* mesh,
|
void setBuffersDefaultVars(DynPipBag* buffers, const DynamicMesh* mesh,
|
||||||
DynPipInfoBag* infoBag);
|
DynPipInfoBag* infoBag);
|
||||||
void setBuffersColorBag(DynPipBag* buffers, DynPipColorBag* colorBag);
|
void setBuffersColorBag(DynPipBag* buffers, DynPipColorBag* colorBag);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ class StaPipBagPackage {
|
|||||||
|
|
||||||
StaPipBag* bag;
|
StaPipBag* bag;
|
||||||
|
|
||||||
Vec4* vertices;
|
const Vec4* vertices;
|
||||||
Vec4* sts;
|
const Vec4* sts;
|
||||||
Vec4* normals;
|
const Vec4* normals;
|
||||||
Vec4* colors;
|
const Vec4* colors;
|
||||||
/** maxVertCount is max value, because we decided to put max maxVertCount
|
/** maxVertCount is max value, because we decided to put max maxVertCount
|
||||||
* verts to single quad buffer in VU1 */
|
* verts to single quad buffer in VU1 */
|
||||||
u16 size;
|
u16 size;
|
||||||
|
|||||||
@@ -23,10 +23,10 @@ class StaPipColorBag {
|
|||||||
~StaPipColorBag();
|
~StaPipColorBag();
|
||||||
|
|
||||||
/** Optional. Single color for all vertices. */
|
/** Optional. Single color for all vertices. */
|
||||||
Color* single;
|
const Color* single;
|
||||||
|
|
||||||
/** Optional. Color per vertex. */
|
/** Optional. Color per vertex. */
|
||||||
Color* many;
|
const Color* many;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Tyra
|
} // namespace Tyra
|
||||||
|
|||||||
@@ -45,28 +45,30 @@ class StaticPipeline : public Renderer3DPipeline {
|
|||||||
* Render static model
|
* Render static model
|
||||||
* This render() method is a bridge to core.render() method.
|
* This render() method is a bridge to core.render() method.
|
||||||
*/
|
*/
|
||||||
void render(StaticMesh* mesh, const StaPipOptions* options = nullptr);
|
void render(const StaticMesh& mesh, const StaPipOptions* options = nullptr);
|
||||||
|
void render(const StaticMesh* mesh, const StaPipOptions* options = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RendererCore* rendererCore;
|
RendererCore* rendererCore;
|
||||||
Vec4* colorsCache;
|
Vec4* colorsCache;
|
||||||
|
|
||||||
void addVertices(MeshMaterialFrame* materialFrame, StaPipBag* bag) const;
|
void addVertices(const MeshMaterialFrame* materialFrame,
|
||||||
|
StaPipBag* bag) const;
|
||||||
|
|
||||||
StaPipInfoBag* getInfoBag(StaticMesh* mesh, const StaPipOptions* options,
|
StaPipInfoBag* getInfoBag(const StaticMesh* mesh,
|
||||||
M4x4* model) const;
|
const StaPipOptions* options, M4x4* model) const;
|
||||||
|
|
||||||
StaPipColorBag* getColorBag(MeshMaterial* material,
|
StaPipColorBag* getColorBag(const MeshMaterial* material,
|
||||||
MeshMaterialFrame* materialFrame) const;
|
const MeshMaterialFrame* materialFrame) const;
|
||||||
|
|
||||||
StaPipTextureBag* getTextureBag(MeshMaterial* material,
|
StaPipTextureBag* getTextureBag(const MeshMaterial* material,
|
||||||
MeshMaterialFrame* materialFrame);
|
const MeshMaterialFrame* materialFrame);
|
||||||
|
|
||||||
StaPipLightingBag* getLightingBag(MeshMaterialFrame* materialFrame,
|
StaPipLightingBag* getLightingBag(const MeshMaterialFrame* materialFrame,
|
||||||
M4x4* model,
|
M4x4* model,
|
||||||
const StaPipOptions* options) const;
|
const StaPipOptions* options) const;
|
||||||
|
|
||||||
void deallocDrawBags(StaPipBag* bag, MeshMaterial* material) const;
|
void deallocDrawBags(StaPipBag* bag, const MeshMaterial* material) const;
|
||||||
|
|
||||||
void setLightingColorsCache(PipelineLightingOptions* lightingOptions);
|
void setLightingColorsCache(PipelineLightingOptions* lightingOptions);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ class RendererCore2D {
|
|||||||
|
|
||||||
void init(RendererSettings* settings, clutbuffer_t* clutBuffer);
|
void init(RendererSettings* settings, clutbuffer_t* clutBuffer);
|
||||||
|
|
||||||
void render(Sprite* sprite, const RendererCoreTextureBuffers& texBuffers,
|
void render(const Sprite& sprite,
|
||||||
Texture* texture);
|
const RendererCoreTextureBuffers& texBuffers, Texture* texture);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setPrim();
|
void setPrim();
|
||||||
|
|||||||
@@ -108,6 +108,8 @@ class TextureRepository {
|
|||||||
* Texture IS destructed.
|
* Texture IS destructed.
|
||||||
*/
|
*/
|
||||||
void free(const u32& t_texId);
|
void free(const u32& t_texId);
|
||||||
|
void free(const Texture* t_tex);
|
||||||
|
void free(const Texture& t_tex);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Texture*> textures;
|
std::vector<Texture*> textures;
|
||||||
|
|||||||
@@ -17,11 +17,13 @@ Renderer2D::~Renderer2D() {}
|
|||||||
|
|
||||||
void Renderer2D::init(RendererCore* t_rendererCore) { core = t_rendererCore; }
|
void Renderer2D::init(RendererCore* t_rendererCore) { core = t_rendererCore; }
|
||||||
|
|
||||||
void Renderer2D::render(Sprite* sprite) {
|
void Renderer2D::render(const Sprite* sprite) { render(*sprite); }
|
||||||
auto* texture = core->texture.repository.getBySpriteOrMesh(sprite->id);
|
|
||||||
|
void Renderer2D::render(const Sprite& sprite) {
|
||||||
|
auto* texture = core->texture.repository.getBySpriteOrMesh(sprite.id);
|
||||||
|
|
||||||
TYRA_ASSERT(
|
TYRA_ASSERT(
|
||||||
texture, "Texture for sprite with id: ", sprite->id,
|
texture, "Texture for sprite with id: ", sprite.id,
|
||||||
"Was not found in texture repository! Did you forget to add texture?");
|
"Was not found in texture repository! Did you forget to add texture?");
|
||||||
|
|
||||||
auto texBuffers = core->texture.useTexture(texture);
|
auto texBuffers = core->texture.useTexture(texture);
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
#include "renderer/3d/pipeline/dynamic/core/dynpip_renderer.hpp"
|
#include "renderer/3d/pipeline/dynamic/core/dynpip_renderer.hpp"
|
||||||
#include "renderer/3d/pipeline/dynamic/core/programs/dynpip_vu1_shared_defines.h"
|
#include "renderer/3d/pipeline/dynamic/core/programs/dynpip_vu1_shared_defines.h"
|
||||||
#include <dma.h>
|
#include <dma.h>
|
||||||
|
#include <utility>
|
||||||
|
#include "packet2/packet2_tyra_utils.hpp"
|
||||||
|
|
||||||
namespace Tyra {
|
namespace Tyra {
|
||||||
|
|
||||||
@@ -114,7 +116,7 @@ void DynPipRenderer::sendObjectData(
|
|||||||
|
|
||||||
if (singleColorEnabled) // Color is placed in 4th slot of
|
if (singleColorEnabled) // Color is placed in 4th slot of
|
||||||
// VU1_LIGHTS_MATRIX_ADDR
|
// VU1_LIGHTS_MATRIX_ADDR
|
||||||
packet2_utils_vu_add_unpack_data(objectDataPacket, VU1_SINGLE_COLOR_ADDR,
|
Packet2TyraUtils::addUnpackData(objectDataPacket, VU1_SINGLE_COLOR_ADDR,
|
||||||
bag->color->single->rgba, 1, false);
|
bag->color->single->rgba, 1, false);
|
||||||
|
|
||||||
packet2_utils_vu_open_unpack(objectDataPacket, VU1_OPTIONS_ADDR, false);
|
packet2_utils_vu_open_unpack(objectDataPacket, VU1_OPTIONS_ADDR, false);
|
||||||
|
|||||||
@@ -51,7 +51,13 @@ void DynamicPipeline::onUseEnd() {
|
|||||||
core.deallocateOnUse();
|
core.deallocateOnUse();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynamicPipeline::render(DynamicMesh* mesh, const DynPipOptions* options) {
|
void DynamicPipeline::render(const DynamicMesh& mesh,
|
||||||
|
const DynPipOptions* options) {
|
||||||
|
render(&mesh, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DynamicPipeline::render(const DynamicMesh* mesh,
|
||||||
|
const DynPipOptions* options) {
|
||||||
bool optionsManuallyAllocated = false;
|
bool optionsManuallyAllocated = false;
|
||||||
|
|
||||||
if (!options) {
|
if (!options) {
|
||||||
@@ -185,7 +191,7 @@ void DynamicPipeline::sendRestOfBuffers(DynPipBag* buffers, u16* bufferIndex) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DynamicPipeline::setBuffersDefaultVars(DynPipBag* buffers,
|
void DynamicPipeline::setBuffersDefaultVars(DynPipBag* buffers,
|
||||||
DynamicMesh* mesh,
|
const DynamicMesh* mesh,
|
||||||
DynPipInfoBag* infoBag) {
|
DynPipInfoBag* infoBag) {
|
||||||
for (u32 i = 0; i < buffersCount; i++) {
|
for (u32 i = 0; i < buffersCount; i++) {
|
||||||
buffers[i].info = infoBag;
|
buffers[i].info = infoBag;
|
||||||
@@ -210,7 +216,7 @@ void DynamicPipeline::freeBuffer(DynPipBag* bag) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DynPipInfoBag* DynamicPipeline::getInfoBag(DynamicMesh* mesh,
|
DynPipInfoBag* DynamicPipeline::getInfoBag(const DynamicMesh* mesh,
|
||||||
const DynPipOptions* options,
|
const DynPipOptions* options,
|
||||||
M4x4* model) const {
|
M4x4* model) const {
|
||||||
auto* result = new DynPipInfoBag();
|
auto* result = new DynPipInfoBag();
|
||||||
@@ -230,22 +236,23 @@ DynPipInfoBag* DynamicPipeline::getInfoBag(DynamicMesh* mesh,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynamicPipeline::addVertices(MeshMaterialFrame* materialFrameFrom,
|
void DynamicPipeline::addVertices(const MeshMaterialFrame* materialFrameFrom,
|
||||||
MeshMaterialFrame* materialFrameTo,
|
const MeshMaterialFrame* materialFrameTo,
|
||||||
DynPipBag* bag, const u32& startIndex) const {
|
DynPipBag* bag, const u32& startIndex) const {
|
||||||
bag->verticesFrom = &materialFrameFrom->vertices[startIndex];
|
bag->verticesFrom = &materialFrameFrom->vertices[startIndex];
|
||||||
bag->verticesTo = &materialFrameTo->vertices[startIndex];
|
bag->verticesTo = &materialFrameTo->vertices[startIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
DynPipColorBag* DynamicPipeline::getColorBag(MeshMaterial* material) const {
|
DynPipColorBag* DynamicPipeline::getColorBag(
|
||||||
|
const MeshMaterial* material) const {
|
||||||
auto* result = new DynPipColorBag();
|
auto* result = new DynPipColorBag();
|
||||||
result->single = &material->ambient;
|
result->single = &material->ambient;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DynPipTextureBag* DynamicPipeline::getTextureBag(
|
DynPipTextureBag* DynamicPipeline::getTextureBag(
|
||||||
Texture* texture, MeshMaterialFrame* materialFrameFrom,
|
Texture* texture, const MeshMaterialFrame* materialFrameFrom,
|
||||||
MeshMaterialFrame* materialFrameTo, const u32& startIndex) {
|
const MeshMaterialFrame* materialFrameTo, const u32& startIndex) {
|
||||||
if (!materialFrameFrom->textureCoords) return nullptr;
|
if (!materialFrameFrom->textureCoords) return nullptr;
|
||||||
|
|
||||||
auto* result = new DynPipTextureBag();
|
auto* result = new DynPipTextureBag();
|
||||||
@@ -259,9 +266,10 @@ DynPipTextureBag* DynamicPipeline::getTextureBag(
|
|||||||
}
|
}
|
||||||
|
|
||||||
DynPipLightingBag* DynamicPipeline::getLightingBag(
|
DynPipLightingBag* DynamicPipeline::getLightingBag(
|
||||||
MeshMaterialFrame* materialFrameFrom, MeshMaterialFrame* materialFrameTo,
|
const MeshMaterialFrame* materialFrameFrom,
|
||||||
M4x4* model, const DynPipOptions* options,
|
const MeshMaterialFrame* materialFrameTo, M4x4* model,
|
||||||
PipelineDirLightsBag* dirLightsBag, const u32& startIndex) const {
|
const DynPipOptions* options, PipelineDirLightsBag* dirLightsBag,
|
||||||
|
const u32& startIndex) const {
|
||||||
if (!materialFrameFrom->normals || options == nullptr ||
|
if (!materialFrameFrom->normals || options == nullptr ||
|
||||||
options->lighting == nullptr)
|
options->lighting == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@@ -43,7 +43,8 @@ StaPipBagPackage* StaPipBagPackager::create(u16* o_size, StaPipBag* data,
|
|||||||
if (data->texture) result[i].sts = &data->texture->coordinates[i * size];
|
if (data->texture) result[i].sts = &data->texture->coordinates[i * size];
|
||||||
|
|
||||||
if (data->color->many)
|
if (data->color->many)
|
||||||
result[i].colors = reinterpret_cast<Vec4*>(&data->color->many[i * size]);
|
result[i].colors =
|
||||||
|
reinterpret_cast<const Vec4*>(&data->color->many[i * size]);
|
||||||
|
|
||||||
if (data->lighting) result[i].normals = &data->lighting->normals[i * size];
|
if (data->lighting) result[i].normals = &data->lighting->normals[i * size];
|
||||||
|
|
||||||
|
|||||||
@@ -37,10 +37,12 @@ void StaPipQBuffer::fillByPointer(const StaPipBagPackage& pkg) {
|
|||||||
|
|
||||||
deallocateDynamicData();
|
deallocateDynamicData();
|
||||||
|
|
||||||
vertices = pkg.vertices;
|
// Too bad, but in reality const is not violated.
|
||||||
sts = pkg.sts;
|
// This class needs refactor
|
||||||
colors = pkg.colors;
|
vertices = const_cast<Vec4*>(pkg.vertices);
|
||||||
normals = pkg.normals;
|
sts = const_cast<Vec4*>(pkg.sts);
|
||||||
|
colors = const_cast<Vec4*>(pkg.colors);
|
||||||
|
normals = const_cast<Vec4*>(pkg.normals);
|
||||||
size = pkg.size;
|
size = pkg.size;
|
||||||
bag = pkg.bag;
|
bag = pkg.bag;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "renderer/3d/pipeline/static/core/stapip_qbuffer_renderer.hpp"
|
#include "renderer/3d/pipeline/static/core/stapip_qbuffer_renderer.hpp"
|
||||||
#include "renderer/3d/pipeline/static/core/programs/stapip_vu1_shared_defines.h"
|
#include "renderer/3d/pipeline/static/core/programs/stapip_vu1_shared_defines.h"
|
||||||
|
#include "packet2/packet2_tyra_utils.hpp"
|
||||||
|
|
||||||
// #define TYRA_QBUFF_RENDERER_VERBOSE_LOG 1
|
// #define TYRA_QBUFF_RENDERER_VERBOSE_LOG 1
|
||||||
|
|
||||||
@@ -135,7 +136,7 @@ void StaPipQBufferRenderer::sendObjectData(
|
|||||||
|
|
||||||
if (singleColorEnabled) // Color is placed in 4th slot of
|
if (singleColorEnabled) // Color is placed in 4th slot of
|
||||||
// VU1_LIGHTS_MATRIX_ADDR
|
// VU1_LIGHTS_MATRIX_ADDR
|
||||||
packet2_utils_vu_add_unpack_data(objectDataPacket, VU1_SINGLE_COLOR_ADDR,
|
Packet2TyraUtils::addUnpackData(objectDataPacket, VU1_SINGLE_COLOR_ADDR,
|
||||||
bag->color->single->rgba, 1, false);
|
bag->color->single->rgba, 1, false);
|
||||||
|
|
||||||
packet2_utils_vu_open_unpack(objectDataPacket, VU1_OPTIONS_ADDR, false);
|
packet2_utils_vu_open_unpack(objectDataPacket, VU1_OPTIONS_ADDR, false);
|
||||||
|
|||||||
@@ -39,7 +39,13 @@ void StaticPipeline::onUseEnd() {
|
|||||||
core.deallocateOnUse();
|
core.deallocateOnUse();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StaticPipeline::render(StaticMesh* mesh, const StaPipOptions* options) {
|
void StaticPipeline::render(const StaticMesh& mesh,
|
||||||
|
const StaPipOptions* options) {
|
||||||
|
render(&mesh, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StaticPipeline::render(const StaticMesh* mesh,
|
||||||
|
const StaPipOptions* options) {
|
||||||
bool optionsManuallyAllocated = false;
|
bool optionsManuallyAllocated = false;
|
||||||
|
|
||||||
if (!options) {
|
if (!options) {
|
||||||
@@ -89,13 +95,13 @@ void StaticPipeline::render(StaticMesh* mesh, const StaPipOptions* options) {
|
|||||||
if (optionsManuallyAllocated) delete options;
|
if (optionsManuallyAllocated) delete options;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StaticPipeline::addVertices(MeshMaterialFrame* materialFrame,
|
void StaticPipeline::addVertices(const MeshMaterialFrame* materialFrame,
|
||||||
StaPipBag* bag) const {
|
StaPipBag* bag) const {
|
||||||
bag->count = materialFrame->count;
|
bag->count = materialFrame->count;
|
||||||
bag->vertices = materialFrame->vertices;
|
bag->vertices = materialFrame->vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
StaPipInfoBag* StaticPipeline::getInfoBag(StaticMesh* mesh,
|
StaPipInfoBag* StaticPipeline::getInfoBag(const StaticMesh* mesh,
|
||||||
const StaPipOptions* options,
|
const StaPipOptions* options,
|
||||||
M4x4* model) const {
|
M4x4* model) const {
|
||||||
auto* result = new StaPipInfoBag();
|
auto* result = new StaPipInfoBag();
|
||||||
@@ -117,7 +123,8 @@ StaPipInfoBag* StaticPipeline::getInfoBag(StaticMesh* mesh,
|
|||||||
}
|
}
|
||||||
|
|
||||||
StaPipColorBag* StaticPipeline::getColorBag(
|
StaPipColorBag* StaticPipeline::getColorBag(
|
||||||
MeshMaterial* material, MeshMaterialFrame* materialFrame) const {
|
const MeshMaterial* material,
|
||||||
|
const MeshMaterialFrame* materialFrame) const {
|
||||||
auto* result = new StaPipColorBag();
|
auto* result = new StaPipColorBag();
|
||||||
|
|
||||||
if (material->lightmapFlag) {
|
if (material->lightmapFlag) {
|
||||||
@@ -130,7 +137,7 @@ StaPipColorBag* StaticPipeline::getColorBag(
|
|||||||
}
|
}
|
||||||
|
|
||||||
StaPipTextureBag* StaticPipeline::getTextureBag(
|
StaPipTextureBag* StaticPipeline::getTextureBag(
|
||||||
MeshMaterial* material, MeshMaterialFrame* materialFrame) {
|
const MeshMaterial* material, const MeshMaterialFrame* materialFrame) {
|
||||||
if (!materialFrame->textureCoords) return nullptr;
|
if (!materialFrame->textureCoords) return nullptr;
|
||||||
|
|
||||||
auto* result = new StaPipTextureBag();
|
auto* result = new StaPipTextureBag();
|
||||||
@@ -149,7 +156,7 @@ StaPipTextureBag* StaticPipeline::getTextureBag(
|
|||||||
}
|
}
|
||||||
|
|
||||||
StaPipLightingBag* StaticPipeline::getLightingBag(
|
StaPipLightingBag* StaticPipeline::getLightingBag(
|
||||||
MeshMaterialFrame* materialFrame, M4x4* model,
|
const MeshMaterialFrame* materialFrame, M4x4* model,
|
||||||
const StaPipOptions* options) const {
|
const StaPipOptions* options) const {
|
||||||
if (!materialFrame->normals || options == nullptr ||
|
if (!materialFrame->normals || options == nullptr ||
|
||||||
options->lighting == nullptr)
|
options->lighting == nullptr)
|
||||||
@@ -181,7 +188,7 @@ void StaticPipeline::setLightingColorsCache(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void StaticPipeline::deallocDrawBags(StaPipBag* bag,
|
void StaticPipeline::deallocDrawBags(StaPipBag* bag,
|
||||||
MeshMaterial* material) const {
|
const MeshMaterial* material) const {
|
||||||
if (bag->texture) {
|
if (bag->texture) {
|
||||||
delete bag->texture;
|
delete bag->texture;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,15 +62,15 @@ void RendererCore2D::init(RendererSettings* t_settings,
|
|||||||
clutBuffer = t_clutBuffer;
|
clutBuffer = t_clutBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererCore2D::render(Sprite* sprite,
|
void RendererCore2D::render(const Sprite& sprite,
|
||||||
const RendererCoreTextureBuffers& texBuffers,
|
const RendererCoreTextureBuffers& texBuffers,
|
||||||
Texture* texture) {
|
Texture* texture) {
|
||||||
auto* rect = rects[context];
|
auto* rect = rects[context];
|
||||||
float sizeX, sizeY;
|
float sizeX, sizeY;
|
||||||
|
|
||||||
if (sprite->mode == MODE_REPEAT) {
|
if (sprite.mode == MODE_REPEAT) {
|
||||||
sizeX = sprite->size.x;
|
sizeX = sprite.size.x;
|
||||||
sizeY = sprite->size.y;
|
sizeY = sprite.size.y;
|
||||||
} else {
|
} else {
|
||||||
sizeX = static_cast<float>(texture->getWidth());
|
sizeX = static_cast<float>(texture->getWidth());
|
||||||
sizeY = static_cast<float>(texture->getHeight());
|
sizeY = static_cast<float>(texture->getHeight());
|
||||||
@@ -84,24 +84,24 @@ void RendererCore2D::render(Sprite* sprite,
|
|||||||
else if (sizeY > sizeX)
|
else if (sizeY > sizeX)
|
||||||
texS = texMax / (sizeY / sizeX);
|
texS = texMax / (sizeY / sizeX);
|
||||||
|
|
||||||
rect->t0.s = sprite->flipHorizontal ? texS : 0.0F;
|
rect->t0.s = sprite.flipHorizontal ? texS : 0.0F;
|
||||||
rect->t0.t = sprite->flipVertical ? texT : 0.0F;
|
rect->t0.t = sprite.flipVertical ? texT : 0.0F;
|
||||||
rect->t1.s = sprite->flipHorizontal ? 0.0F : texS;
|
rect->t1.s = sprite.flipHorizontal ? 0.0F : texS;
|
||||||
rect->t1.t = sprite->flipVertical ? 0.0F : texT;
|
rect->t1.t = sprite.flipVertical ? 0.0F : texT;
|
||||||
|
|
||||||
rect->color.r = sprite->color.r;
|
rect->color.r = sprite.color.r;
|
||||||
rect->color.g = sprite->color.g;
|
rect->color.g = sprite.color.g;
|
||||||
rect->color.b = sprite->color.b;
|
rect->color.b = sprite.color.b;
|
||||||
rect->color.a = sprite->color.a;
|
rect->color.a = sprite.color.a;
|
||||||
rect->color.q = 0;
|
rect->color.q = 0;
|
||||||
|
|
||||||
rect->v0.x = sprite->position.x;
|
rect->v0.x = sprite.position.x;
|
||||||
rect->v0.y = sprite->position.y;
|
rect->v0.y = sprite.position.y;
|
||||||
// rect->v0.y /= 2.0F; // interlacing
|
// rect->v0.y /= 2.0F; // interlacing
|
||||||
rect->v0.z = (u32)-1;
|
rect->v0.z = (u32)-1;
|
||||||
|
|
||||||
rect->v1.x = (sprite->size.x * sprite->scale) + sprite->position.x;
|
rect->v1.x = (sprite.size.x * sprite.scale) + sprite.position.x;
|
||||||
rect->v1.y = (sprite->size.y * sprite->scale) + sprite->position.y;
|
rect->v1.y = (sprite.size.y * sprite.scale) + sprite.position.y;
|
||||||
// rect->v1.y /= 2.0F; // interlacing
|
// rect->v1.y /= 2.0F; // interlacing
|
||||||
rect->v1.z = (u32)-1;
|
rect->v1.z = (u32)-1;
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,10 @@ void TextureRepository::removeById(const u32& t_texId) {
|
|||||||
removeByIndex(index);
|
removeByIndex(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextureRepository::free(const Texture* t_tex) { free(t_tex->id); }
|
||||||
|
|
||||||
|
void TextureRepository::free(const Texture& t_tex) { free(t_tex.id); }
|
||||||
|
|
||||||
void TextureRepository::free(const u32& t_texId) {
|
void TextureRepository::free(const u32& t_texId) {
|
||||||
s32 index = getIndexOf(t_texId);
|
s32 index = getIndexOf(t_texId);
|
||||||
auto* tex = textures[index];
|
auto* tex = textures[index];
|
||||||
|
|||||||
@@ -10,54 +10,30 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <engine.hpp>
|
/** We can include all of Tyra classes via this single line: */
|
||||||
#include <game.hpp>
|
#include <tyra>
|
||||||
#include "renderer/3d/pipeline/minecraft/minecraft_pipeline.hpp"
|
|
||||||
#include "renderer/3d/pipeline/static/static_pipeline.hpp"
|
|
||||||
#include "renderer/3d/pipeline/dynamic/dynamic_pipeline.hpp"
|
|
||||||
#include "renderer/3d/mesh/static/static_mesh.hpp"
|
|
||||||
|
|
||||||
namespace Tyra {
|
namespace Tyra {
|
||||||
|
|
||||||
|
/** Tutorial01 is a name of our game class */
|
||||||
class Tutorial01 : public Game {
|
class Tutorial01 : public Game {
|
||||||
public:
|
public:
|
||||||
Tutorial01(Engine* engine);
|
Tutorial01(Engine* engine);
|
||||||
~Tutorial01();
|
~Tutorial01();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will be called once,
|
||||||
|
* immediatly after initializing Tyra features
|
||||||
|
*/
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will be called every frame
|
||||||
|
*/
|
||||||
void loop();
|
void loop();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Engine* engine;
|
Engine* engine;
|
||||||
|
|
||||||
StaticMesh* skybox;
|
|
||||||
DynamicMesh* cube;
|
|
||||||
StaticMesh* staticMesh;
|
|
||||||
DynamicMesh* warrior;
|
|
||||||
u8 warriorsCount;
|
|
||||||
DynamicMesh** warriors;
|
|
||||||
u32 picturesCount;
|
|
||||||
Sprite** pictures;
|
|
||||||
audsrv_adpcm_t* adpcmSample;
|
|
||||||
Timer adpcmTimer;
|
|
||||||
|
|
||||||
Vec4 cameraPosition, cameraLookAt;
|
|
||||||
|
|
||||||
MinecraftPipeline mcPip;
|
|
||||||
DynamicPipeline dynpip;
|
|
||||||
StaticPipeline stapip;
|
|
||||||
StaPipOptions* skyboxOptions;
|
|
||||||
StaPipOptions* staOptions;
|
|
||||||
DynPipOptions* dynOptions;
|
|
||||||
Texture* warriorTex;
|
|
||||||
Texture* blocksTex;
|
|
||||||
Texture* blocksTex2;
|
|
||||||
|
|
||||||
u32 blocksCount;
|
|
||||||
std::vector<McpipBlock*> blocks;
|
|
||||||
M4x4* translations;
|
|
||||||
M4x4* rotations;
|
|
||||||
M4x4* scales;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Tyra
|
} // namespace Tyra
|
||||||
|
|||||||
@@ -11,10 +11,33 @@
|
|||||||
#include "engine.hpp"
|
#include "engine.hpp"
|
||||||
#include "tutorial_01.hpp"
|
#include "tutorial_01.hpp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hello, thank you for choosing Tyra engine!
|
||||||
|
*
|
||||||
|
* In this tutorial we will learn how to:
|
||||||
|
* - Initialize engine and game class
|
||||||
|
* - Use debug functions
|
||||||
|
* - Print "Hello world" to the screen
|
||||||
|
*/
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
/**
|
||||||
|
* This is a class which contains
|
||||||
|
* all features of Tyra.
|
||||||
|
*/
|
||||||
Tyra::Engine engine;
|
Tyra::Engine engine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a class with our game code.
|
||||||
|
*/
|
||||||
Tyra::Tutorial01 game(&engine);
|
Tyra::Tutorial01 game(&engine);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We need to insert our game class into engine.
|
||||||
|
*/
|
||||||
engine.run(&game);
|
engine.run(&game);
|
||||||
SleepThread();
|
|
||||||
|
/** Continuation in file tutorial_01.hpp */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,300 +8,52 @@
|
|||||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <tyra>
|
||||||
#include "tutorial_01.hpp"
|
#include "tutorial_01.hpp"
|
||||||
#include "file/file_utils.hpp"
|
|
||||||
#include "loaders/3d/md2_loader/md2_loader.hpp"
|
|
||||||
#include "loaders/3d/obj_loader/obj_loader.hpp"
|
|
||||||
#include "thread/threading.hpp"
|
|
||||||
|
|
||||||
namespace Tyra {
|
namespace Tyra {
|
||||||
|
|
||||||
float getRandomFloat(float a, float b) {
|
/** Lets save pointer to engine class */
|
||||||
float random = ((float)rand()) / (float)RAND_MAX;
|
Tutorial01::Tutorial01(Engine* t_engine) : engine(t_engine) {}
|
||||||
float diff = b - a;
|
|
||||||
float r = random * diff;
|
Tutorial01::~Tutorial01() {}
|
||||||
return a + r;
|
|
||||||
|
void Tutorial01::init() {
|
||||||
|
/**
|
||||||
|
* There are 5 debug functions in Tyra engine.
|
||||||
|
*
|
||||||
|
* TYRA_LOG() -> Prints log message
|
||||||
|
*
|
||||||
|
* TYRA_WARN() -> Prints warning message
|
||||||
|
*
|
||||||
|
* TYRA_ERROR() -> Prints error message
|
||||||
|
*
|
||||||
|
* TYRA_ASSERT() -> Checks if condition is true, otherwise prints error
|
||||||
|
* message
|
||||||
|
*
|
||||||
|
* TYRA_BREAKPOINT() -> Freeze program in current place
|
||||||
|
*
|
||||||
|
* Every function has infinite number of various-typed arguments.
|
||||||
|
*/
|
||||||
|
|
||||||
|
short positiveNumber = -1; // Change it to -1 and see what happen!
|
||||||
|
|
||||||
|
TYRA_LOG("Hello world!");
|
||||||
|
|
||||||
|
TYRA_WARN("Something weird happened! ",
|
||||||
|
"Number should be positive, but is: ", -1);
|
||||||
|
|
||||||
|
TYRA_ERROR("Something really bad happened!");
|
||||||
|
|
||||||
|
/** First argument is our check argument */
|
||||||
|
TYRA_ASSERT(positiveNumber > 0, "Number should be positive!",
|
||||||
|
"Please check the code!", "Current value:", (int)positiveNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
int getRandomInt(int a, int b) { return (rand() % (b - a + 1)) + a; }
|
void Tutorial01::loop() {
|
||||||
|
/** Uncomment following line, to check the game loop! */
|
||||||
|
|
||||||
Tutorial01 ::Tutorial01(Engine* t_engine) { engine = t_engine; }
|
// TYRA_LOG("Loop!");
|
||||||
Tutorial01 ::~Tutorial01() {}
|
|
||||||
|
|
||||||
StaticMesh* getStaticMesh(Renderer* renderer);
|
|
||||||
DynamicMesh* getWarrior(Renderer* renderer);
|
|
||||||
StaticMesh* getSkybox(Renderer* renderer);
|
|
||||||
DynamicMesh* getCube(Renderer* renderer);
|
|
||||||
StaPipOptions* getStaPipOptions();
|
|
||||||
DynPipOptions* getDynPipOptions();
|
|
||||||
void setPipelineOptions(PipelineOptions* options);
|
|
||||||
Sprite* get2DPicture(Renderer* renderer);
|
|
||||||
|
|
||||||
void Tutorial01 ::init() {
|
|
||||||
// Song
|
|
||||||
engine->audio.song.load(FileUtils::fromCwd("mafikizolo-loot.wav"));
|
|
||||||
engine->audio.song.inLoop = true;
|
|
||||||
engine->audio.song.setVolume(30);
|
|
||||||
|
|
||||||
adpcmSample = engine->audio.adpcm.load(FileUtils::fromCwd("walk.adpcm"));
|
|
||||||
engine->audio.adpcm.setVolume(80, 1);
|
|
||||||
|
|
||||||
engine->renderer.setClearScreenColor(Color(64.0F, 64.0F, 64.0F));
|
|
||||||
|
|
||||||
staticMesh = getStaticMesh(&engine->renderer);
|
|
||||||
skybox = getSkybox(&engine->renderer);
|
|
||||||
|
|
||||||
cube = getCube(&engine->renderer);
|
|
||||||
|
|
||||||
warrior = getWarrior(&engine->renderer);
|
|
||||||
warriorTex = engine->renderer.core.texture.repository.getBySpriteOrMesh(
|
|
||||||
warrior->materials[0]->id);
|
|
||||||
|
|
||||||
warriorsCount = 22;
|
|
||||||
warriors = new DynamicMesh*[warriorsCount];
|
|
||||||
for (u8 i = 0; i < warriorsCount; i++) {
|
|
||||||
warriors[i] = new DynamicMesh(*warrior);
|
|
||||||
warriors[i]->translation.translateX(-40.0F + static_cast<float>(i) * 4);
|
|
||||||
warriors[i]->translation.translateY(30.0F);
|
|
||||||
warriors[i]->translation.translateZ(-10.0F);
|
|
||||||
warriors[i]->translation.rotateX(-1.5F);
|
|
||||||
warriorTex->addLink(warriors[i]->materials[0]->id);
|
|
||||||
warriors[i]->animation.speed = getRandomFloat(0.1F, 0.9F);
|
|
||||||
}
|
|
||||||
|
|
||||||
staOptions = getStaPipOptions();
|
|
||||||
|
|
||||||
skyboxOptions = new StaPipOptions();
|
|
||||||
skyboxOptions->fullClipChecks = true;
|
|
||||||
skyboxOptions->frustumCulling = PipelineFrustumCulling_Precise;
|
|
||||||
|
|
||||||
dynOptions = getDynPipOptions();
|
|
||||||
|
|
||||||
cameraPosition = Vec4(0.0F, 0.0F, 20.0F);
|
|
||||||
cameraLookAt = *warrior->getPosition();
|
|
||||||
|
|
||||||
blocksTex = engine->renderer.core.texture.repository.add(
|
|
||||||
FileUtils::fromCwd("blocks.png"));
|
|
||||||
blocksTex2 = engine->renderer.core.texture.repository.add(
|
|
||||||
FileUtils::fromCwd("texture_atlas.png"));
|
|
||||||
|
|
||||||
mcPip.setRenderer(&engine->renderer.core);
|
|
||||||
dynpip.setRenderer(&engine->renderer.core);
|
|
||||||
stapip.setRenderer(&engine->renderer.core);
|
|
||||||
|
|
||||||
picturesCount = 3;
|
|
||||||
pictures = new Sprite*[picturesCount];
|
|
||||||
for (u32 i = 0; i < picturesCount; i++)
|
|
||||||
pictures[i] = get2DPicture(&engine->renderer);
|
|
||||||
|
|
||||||
u32 rows = 4; // 64
|
|
||||||
u32 columns = 4; // 64
|
|
||||||
blocksCount = rows * columns;
|
|
||||||
|
|
||||||
float offset = 4.0F;
|
|
||||||
translations = new M4x4[blocksCount];
|
|
||||||
rotations = new M4x4[blocksCount];
|
|
||||||
scales = new M4x4[blocksCount];
|
|
||||||
float center = (rows / 2.0F) * offset;
|
|
||||||
auto* color = new Color(128.0F, 128.0F, 128.0F, 128.0F);
|
|
||||||
|
|
||||||
for (u32 i = 0; i < blocksCount; i++) {
|
|
||||||
u32 column = i % columns;
|
|
||||||
u32 row = i / rows;
|
|
||||||
|
|
||||||
translations[i].identity();
|
|
||||||
rotations[i].identity();
|
|
||||||
scales[i].identity();
|
|
||||||
|
|
||||||
translations[i].translateX(row * offset - center);
|
|
||||||
translations[i].translateY(column * offset - center);
|
|
||||||
translations[i].translateZ(-10.0F);
|
|
||||||
|
|
||||||
// u32 randRow = rand() % (rows + 1);
|
|
||||||
// u32 randColumn = rand() % (columns + 1);
|
|
||||||
u32 randRow = 0;
|
|
||||||
u32 randColumn = 0;
|
|
||||||
|
|
||||||
McpipBlock* block = new McpipBlock();
|
|
||||||
block->textureOffset =
|
|
||||||
new Vec4(mcPip.getTextureOffset() * randRow,
|
|
||||||
mcPip.getTextureOffset() * randColumn, 0.0F, 1.0F);
|
|
||||||
|
|
||||||
block->color = color;
|
|
||||||
blocks.push_back(block);
|
|
||||||
}
|
|
||||||
|
|
||||||
// engine->audio.play();
|
|
||||||
// engine->renderer.setFrameLimit(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 counter = 0;
|
|
||||||
|
|
||||||
void Tutorial01 ::loop() {
|
|
||||||
if (counter++ > 100) {
|
|
||||||
TYRA_LOG("Free RAM: ", engine->info.getAvailableRAM(), " MB");
|
|
||||||
TYRA_LOG("FPS: ", engine->info.getFps());
|
|
||||||
counter = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (u8 i = 0; i < warriorsCount; i++) warriors[i]->update();
|
|
||||||
cube->update();
|
|
||||||
|
|
||||||
skybox->rotation.rotateY(0.02F);
|
|
||||||
|
|
||||||
engine->renderer.beginFrame(CameraInfo3D(&cameraPosition, &cameraLookAt));
|
|
||||||
{
|
|
||||||
for (u32 i = 0; i < blocksCount; i++) {
|
|
||||||
// rotations[i].rotateX(0.04F);
|
|
||||||
rotations[i].rotateY(0.04F);
|
|
||||||
// rotations[i].rotateZ(0.01F);
|
|
||||||
|
|
||||||
if (blocks[i]->model) {
|
|
||||||
delete blocks[i]->model;
|
|
||||||
}
|
|
||||||
blocks[i]->model = new M4x4(translations[i] * rotations[i] * scales[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (u32 i = 0; i < picturesCount; i++)
|
|
||||||
engine->renderer.renderer2D.render(pictures[i]);
|
|
||||||
|
|
||||||
engine->renderer.renderer3D.usePipeline(&stapip);
|
|
||||||
{
|
|
||||||
stapip.render(staticMesh, staOptions);
|
|
||||||
stapip.render(skybox, skyboxOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
engine->renderer.renderer3D.usePipeline(&dynpip);
|
|
||||||
{
|
|
||||||
// dynpip.render(cube);
|
|
||||||
Threading::switchThread();
|
|
||||||
for (u8 i = 0; i < warriorsCount; i++) {
|
|
||||||
dynpip.render(warriors[i], dynOptions);
|
|
||||||
if (i == 5) Threading::switchThread();
|
|
||||||
if (i == 10) Threading::switchThread();
|
|
||||||
if (i == 15) Threading::switchThread();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
engine->renderer.renderer3D.usePipeline(&mcPip);
|
|
||||||
{ mcPip.render(blocks, blocksTex2, true); }
|
|
||||||
}
|
|
||||||
engine->renderer.endFrame();
|
|
||||||
}
|
|
||||||
|
|
||||||
StaticMesh* getStaticMesh(Renderer* renderer) {
|
|
||||||
MD2Loader loader;
|
|
||||||
MD2LoaderOptions options;
|
|
||||||
options.scale = .08F;
|
|
||||||
|
|
||||||
auto* data = loader.load(FileUtils::fromCwd("warrior.md2"), options);
|
|
||||||
auto* result = new StaticMesh(*data);
|
|
||||||
// result->translation.translateZ(-30.0F);
|
|
||||||
delete data;
|
|
||||||
|
|
||||||
renderer->core.texture.repository.addByMesh(result, FileUtils::getCwd(),
|
|
||||||
"png");
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
StaticMesh* getSkybox(Renderer* renderer) {
|
|
||||||
ObjLoader loader;
|
|
||||||
ObjLoaderOptions options;
|
|
||||||
options.flipUVs = true;
|
|
||||||
options.scale = 200.0F;
|
|
||||||
auto* data = loader.load(FileUtils::fromCwd("skybox/skybox.obj"), options);
|
|
||||||
auto* result = new StaticMesh(*data);
|
|
||||||
// result->translation.translateZ(-30.0F);
|
|
||||||
delete data;
|
|
||||||
|
|
||||||
renderer->core.texture.repository.addByMesh(
|
|
||||||
result, FileUtils::fromCwd("skybox/"), "png");
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicMesh* getWarrior(Renderer* renderer) {
|
|
||||||
MD2Loader loader;
|
|
||||||
MD2LoaderOptions options;
|
|
||||||
options.scale = .08F;
|
|
||||||
auto* data = loader.load(FileUtils::fromCwd("warrior.md2"), options);
|
|
||||||
auto* result = new DynamicMesh(*data);
|
|
||||||
// result->translation.translateZ(-30.0F);
|
|
||||||
delete data;
|
|
||||||
|
|
||||||
renderer->core.texture.repository.addByMesh(result, FileUtils::getCwd(),
|
|
||||||
"png");
|
|
||||||
|
|
||||||
result->animation.speed = 0.15F;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicMesh* getCube(Renderer* renderer) {
|
|
||||||
ObjLoader loader;
|
|
||||||
ObjLoaderOptions options;
|
|
||||||
options.animation.count = 2;
|
|
||||||
options.scale = 3.0F;
|
|
||||||
auto* data = loader.load(FileUtils::fromCwd("untitled.obj"), options);
|
|
||||||
data->normalsEnabled = false;
|
|
||||||
data->textureCoordsEnabled = false;
|
|
||||||
auto* result = new DynamicMesh(*data);
|
|
||||||
result->translation.translateZ(-30.0F);
|
|
||||||
delete data;
|
|
||||||
|
|
||||||
result->animation.speed = 0.15F;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sprite* get2DPicture(Renderer* renderer) {
|
|
||||||
auto* sprite = new Sprite;
|
|
||||||
|
|
||||||
sprite->size.set(128.0F, 128.0F);
|
|
||||||
sprite->position.set(300.0F, 280.0F);
|
|
||||||
|
|
||||||
renderer->core.texture.repository.add(FileUtils::fromCwd("reward.png"))
|
|
||||||
->addLink(sprite->id);
|
|
||||||
|
|
||||||
return sprite;
|
|
||||||
}
|
|
||||||
|
|
||||||
StaPipOptions* getStaPipOptions() {
|
|
||||||
auto* options = new StaPipOptions();
|
|
||||||
setPipelineOptions(options);
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
DynPipOptions* getDynPipOptions() {
|
|
||||||
auto* options = new DynPipOptions();
|
|
||||||
setPipelineOptions(options);
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setPipelineOptions(PipelineOptions* options) {
|
|
||||||
auto* ambientColor = new Color(32.0F, 32.0F, 32.0F, 32.0F);
|
|
||||||
auto* directionalColors = new Color[3];
|
|
||||||
for (int i = 0; i < 3; i++) directionalColors[i].set(0.0F, 0.0F, 0.0F, 1.0F);
|
|
||||||
auto* directionalDirections = new Vec4[3];
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
directionalDirections[i].set(1.0F, 1.0F, 1.0F, 1.0F);
|
|
||||||
|
|
||||||
auto* lightingOptions = new PipelineLightingOptions(); // Memory leak!
|
|
||||||
lightingOptions->ambientColor = ambientColor;
|
|
||||||
lightingOptions->directionalColors = directionalColors;
|
|
||||||
lightingOptions->directionalDirections = directionalDirections;
|
|
||||||
|
|
||||||
options->shadingType = Tyra::TyraShadingGouraud;
|
|
||||||
options->blendingEnabled = true;
|
|
||||||
options->antiAliasingEnabled = false;
|
|
||||||
options->lighting = lightingOptions;
|
|
||||||
|
|
||||||
directionalDirections[0].set(-1.0F, 0.0F, 0.0F);
|
|
||||||
directionalColors[0].set(0.0F, 96.0F, 0.0F);
|
|
||||||
|
|
||||||
directionalDirections[1].set(1.0F, 0.0F, 0.0F);
|
|
||||||
directionalColors[1].set(96.0F, 0.0F, 0.0F);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Tyra
|
} // namespace Tyra
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
TARGET := tutorial_01.elf
|
||||||
|
ENGINEDIR := ../../engine
|
||||||
|
|
||||||
|
#The Directories, Source, Includes, Objects, Binary and Resources
|
||||||
|
SRCDIR := src
|
||||||
|
INCDIR := inc
|
||||||
|
BUILDDIR := obj
|
||||||
|
TARGETDIR := bin
|
||||||
|
RESDIR := res
|
||||||
|
SRCEXT := cpp
|
||||||
|
VSMEXT := vsm
|
||||||
|
VCLEXT := vcl
|
||||||
|
VCLPPEXT := vclpp
|
||||||
|
DEPEXT := d
|
||||||
|
OBJEXT := o
|
||||||
|
|
||||||
|
#Flags, Libraries and Includes
|
||||||
|
CFLAGS :=
|
||||||
|
LIB :=
|
||||||
|
LIBDIRS :=
|
||||||
|
INC := -I$(INCDIR)
|
||||||
|
INCDEP := -I$(INCDIR)
|
||||||
|
|
||||||
|
include ../Makefile.tutorials-base
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# Ignore everything in this directory
|
||||||
|
*
|
||||||
|
# Except this file
|
||||||
|
!.gitignore
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
# _____ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# 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>
|
||||||
|
#include <memory.h>
|
||||||
|
|
||||||
|
namespace Tyra {
|
||||||
|
|
||||||
|
class Tutorial02 : public Game {
|
||||||
|
public:
|
||||||
|
Tutorial02(Engine* engine);
|
||||||
|
~Tutorial02();
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void loop();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void loadTexture();
|
||||||
|
void loadSprite();
|
||||||
|
|
||||||
|
Engine* engine;
|
||||||
|
|
||||||
|
Sprite sprite;
|
||||||
|
Texture* texture;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Tyra
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# Ignore everything in this directory
|
||||||
|
*
|
||||||
|
# Except this file
|
||||||
|
!.gitignore
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# Ignore everything in this directory
|
||||||
|
*
|
||||||
|
# Except this file
|
||||||
|
!.gitignore
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
$ConfigFile = Join-Path $PSScriptRoot '../../windows-pcsx2.ps1'
|
||||||
|
. $ConfigFile
|
||||||
|
|
||||||
|
RunPCSX2
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
# _____ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2022, tyra - https://github.com/h4570/tyra
|
||||||
|
# Licensed under Apache License 2.0
|
||||||
|
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "engine.hpp"
|
||||||
|
#include "tutorial_02.hpp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In this tutorial we will learn how to:
|
||||||
|
* - Load png file and create texture from it
|
||||||
|
* - Create sprite class
|
||||||
|
* - Clear screen and render sprite
|
||||||
|
*/
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
Tyra::Engine engine;
|
||||||
|
Tyra::Tutorial02 game(&engine);
|
||||||
|
engine.run(&game);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
# _____ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2022, tyra - https://github.com/h4570/tyra
|
||||||
|
# Licensed under Apache License 2.0
|
||||||
|
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <tyra>
|
||||||
|
#include "tutorial_02.hpp"
|
||||||
|
|
||||||
|
namespace Tyra {
|
||||||
|
|
||||||
|
Tutorial02::Tutorial02(Engine* t_engine) : engine(t_engine) {
|
||||||
|
texture = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tutorial02::~Tutorial02() {
|
||||||
|
if (texture != nullptr) {
|
||||||
|
engine->renderer.core.texture.repository.free(texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tutorial02::init() {
|
||||||
|
engine->renderer.setClearScreenColor(Color(32.0F, 32.0F, 32.0F));
|
||||||
|
|
||||||
|
loadSprite();
|
||||||
|
loadTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tutorial02::loop() {
|
||||||
|
auto& renderer = engine->renderer;
|
||||||
|
|
||||||
|
renderer.beginFrame();
|
||||||
|
renderer.renderer2D.render(sprite);
|
||||||
|
renderer.endFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tutorial02::loadSprite() {
|
||||||
|
const auto& screenSettings = engine->renderer.core.getSettings();
|
||||||
|
|
||||||
|
sprite.mode = SpriteMode::MODE_STRETCH;
|
||||||
|
sprite.size = Vec2(256.0F, 128.0F);
|
||||||
|
sprite.position =
|
||||||
|
Vec2(screenSettings.getWidth() / 2.0F - sprite.size.x / 2.0F,
|
||||||
|
screenSettings.getHeight() / 2.0F - sprite.size.y / 2.0F);
|
||||||
|
|
||||||
|
TYRA_LOG("Sprite created!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tutorial02::loadTexture() {
|
||||||
|
auto& renderer = engine->renderer;
|
||||||
|
auto& rendererCore = renderer.core;
|
||||||
|
auto& textureRepository = rendererCore.texture.repository;
|
||||||
|
|
||||||
|
auto filepath = FileUtils::fromCwd("tyra.png");
|
||||||
|
texture = textureRepository.add(filepath);
|
||||||
|
|
||||||
|
texture->addLink(sprite.id);
|
||||||
|
|
||||||
|
TYRA_LOG("Texture loaded!");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Tyra
|
||||||
Reference in New Issue
Block a user