Отрисовка модели без загрузки¶
Может это поможет вам сделать воксельную игру или какую-либо нестандартную геометрию. Перед выполнением данного туториала рекомендуется всё же попробывать загрузить модель, чтобы иметь базовое понимание о моделях в Firesteel.
Пояснение перед началом¶
Начнём с главного - все модели состоят из мешей и нодов.
Ноды нам пока не нужны. Главное знать, что они позволяют трансформировать меши.
А вот меши являются сеткой и состоят они из треугольников, а именно полигонов. На данный момент Firesteel не поддерживает ничего кроме полигонов по стандарту.
Так вот полигоны состоят из двух самых важных компонентов - точек углов и индексов.

Первые определяют все возможные точки, которые позже объединяются в треугольники и отрисовываются на экран.
Вторые же позволяют сократить итоговое количество точек. Они позволяют переиспользывать уже существующие точки.
К примеру у куба 6 сторон. А у каждой стороны по 2 треугольника внутри. И у каждого треугольника по 3 точки.
Тем самым 6*2*3=36 точек! Но зачем их 36, если можно использовать уже готовые и сократить их итоговое необходимое количество до 8?
Для этого как раз и нужны индексы.
Треугольник (полигон)¶
Почему бы не отрисовать сам полигон?
Введите следущий код в main.cpp:
#include <firesteel/firesteel.hpp>
using namespace Firesteel;
Entity entity;
class CustomMesh : public Firesteel::App {
void onInitialize() override {
//Setup mesh.
const float setup[3][3]={
{ 1, 1, 0},
{ 0, -1, 0},
{-1, 1, 1}
};
std::vector<Vertex> verticies(3);
std::vector<unsigned int> indicies{0,1,2};
for(unsigned int i=0;i<3;i++) {
Vertex vert{};
vert.position=glm::vec3(setup[i][0],setup[i][1],setup[i][2]);
vert.normal=glm::vec3(i==0,i==1,i==2);
verticies[i]=vert;
}
//Append mesh to the model.
entity.addMesh(verticies,indicies,&material);
}
void onUpdate() override {
entity.draw();
}
void onShutdown() override {
entity.remove();
material.remove();
}
};
int main() {
return CustomMesh{}.start();
}
Промежуточный результат #1¶

Чтож... Что-то пошло не так. Ну начнём с того, что полигон повёрнут на 180 градусов от камеры. Для лучшей производительности в Firesteel задние стороны полигонов не отрисовываются - поэтому его и не видно.
А также нету материала.
Крутим треугольник¶
#include <firesteel/firesteel.hpp>
using namespace Firesteel;
Material material;
Entity entity;
class CustomMesh : public Firesteel::App {
void onInitialize() override {
material.setShader("shader.vs", "shader.fs");
//Setup mesh.
const float setup[3][3]={
{ 1, 1, 0},
{ 0, -1, 0},
{-1, 1, 1}
};
std::vector<Vertex> verticies(3);
std::vector<unsigned int> indicies{0,1,2};
for(unsigned int i=0;i<3;i++) {
Vertex vert{};
vert.position=glm::vec3(setup[i][0],setup[i][1],setup[i][2]);
verticies[i]=vert;
}
//Append mesh to the model.
entity.addMesh(verticies,indicies,&material);
//Adjust model to be visible.
entity.transform.rotation.x=180.f;
entity.transform.size=glm::vec3(0.8f);
}
void onUpdate() override {
entity.draw();
}
void onShutdown() override {
entity.remove();
material.remove();
}
};
int main() {
return CustomMesh{}.start();
}
Вертексный шейдер¶
#version 330 core
layout (location = 0) in vec3 aPos;
out vec3 frag_POS;
uniform mat4 model;
void main() {
gl_Position = model*vec4(aPos, 1.0);
frag_POS = aPos;
}
Фрагментный шейдер¶
#version 330 core
out vec4 frag_COLOR;
in vec3 frag_POS;
void main() {
frag_COLOR = vec4((frag_POS/2+vec3(0.5))-frag_POS,1);
}
Промежуточный результат #2¶

Ну теперь можно отрисовать и пластину (квад).
Отрисовываем пластину¶
Пластину передать чуть сложнее чем треугольник. Как вы знаете у треугольника три точки и Firesteel может только их и отрисовывать. Так что надо как-то 4 точки превратить в треугольники. Визуально это должно выглядить так:

Однако если не использовать индексы и просто передать точки для двух треугольников, то выйдет вот так:

Ну это никуда не пойдёт. Зачем создавать 6 точек, если можно справиться всего 4-мя? Используя индексы можно сказать Firesteel-у, что первый треугольник стоит на точках 1, 4 и 3, а второй на 1, 2 и 3.

Теперь надо написать для этого код.
Код для отрисовки пластины¶
Внесите в main.cpp следущие изменения:
#include <firesteel/firesteel.hpp>
using namespace Firesteel;
Material material;
Entity entity;
class CustomMesh : public Firesteel::App {
void onInitialize() override {
material.setShader("shader.vs", "shader.fs");
//Setup mesh.
const float setup[4][3]={
{-1, -1, 0},
{-1, 1, 0.5f},
{ 1, -1, 0.5f},
{ 1, 1, 1}
};
std::vector<Vertex> verticies(4);
std::vector<unsigned int> indicies{0,3,2,1,3,0};
for(unsigned int i=0;i<4;i++) {
Vertex vert{};
vert.position=glm::vec3(setup[i][0],setup[i][1],setup[i][2]);
verticies[i]=vert;
}
//Append mesh to the model.
entity.addMesh(verticies,indicies,&material);
//Adjust model to be visible.
entity.transform.rotation.x=180.f;
entity.transform.size=glm::vec3(0.8f);
}
void onUpdate() override {
entity.draw();
}
void onShutdown() override {
entity.remove();
material.remove();
}
};
int main() {
return CustomMesh{}.start();
}
Промежуточный результат #3¶

На этом собственно всё.