finally frame buffer rendering is working
This commit is contained in:
parent
e690d0f8e2
commit
29834d528a
@ -446,6 +446,8 @@ add_executable(space-game001
|
||||
Perlin.h
|
||||
StoneObject.cpp
|
||||
StoneObject.h
|
||||
FrameBuffer.cpp
|
||||
FrameBuffer.h
|
||||
)
|
||||
|
||||
# Установка проекта по умолчанию для Visual Studio
|
||||
|
||||
49
FrameBuffer.cpp
Normal file
49
FrameBuffer.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
#include "FrameBuffer.h"
|
||||
#include <iostream>
|
||||
#include "Environment.h"
|
||||
|
||||
namespace ZL {
|
||||
|
||||
FrameBuffer::FrameBuffer(int w, int h) : width(w), height(h) {
|
||||
// 1. Ñîçäàåì FBO
|
||||
glGenFramebuffers(1, &fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
|
||||
// 2. Ñîçäàåì òåêñòóðó, êóäà áóäåì "ôîòîãðàôèðîâàòü"
|
||||
glGenTextures(1, &textureID);
|
||||
glBindTexture(GL_TEXTURE_2D, textureID);
|
||||
|
||||
// Óñòàíàâëèâàåì ïàðàìåòðû òåêñòóðû
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
// 3. Ïðèâÿçûâàåì òåêñòóðó ê FBO
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureID, 0);
|
||||
|
||||
// Ïðîâåðêà ãîòîâíîñòè
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
std::cerr << "Error: Framebuffer is not complete!" << std::endl;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
FrameBuffer::~FrameBuffer() {
|
||||
glDeleteFramebuffers(1, &fbo);
|
||||
glDeleteTextures(1, &textureID);
|
||||
}
|
||||
|
||||
void FrameBuffer::Bind() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glViewport(0, 0, width, height); // Âàæíî: óñòàíàâëèâàåì âüþïîðò ïîä ðàçìåð òåêñòóðû
|
||||
}
|
||||
|
||||
void FrameBuffer::Unbind() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
// Çäåñü æåëàòåëüíî âîçâðàùàòü âüþïîðò ê ðàçìåðàì ýêðàíà,
|
||||
// íàïðèìåð, ÷åðåç Environment::width/height
|
||||
glViewport(0, 0, Environment::width, Environment::height);
|
||||
}
|
||||
|
||||
} // namespace ZL
|
||||
29
FrameBuffer.h
Normal file
29
FrameBuffer.h
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
#include "OpenGlExtensions.h"
|
||||
#include <memory>
|
||||
|
||||
namespace ZL {
|
||||
|
||||
class FrameBuffer {
|
||||
private:
|
||||
GLuint fbo = 0;
|
||||
GLuint textureID = 0;
|
||||
int width, height;
|
||||
|
||||
public:
|
||||
FrameBuffer(int w, int h);
|
||||
~FrameBuffer();
|
||||
|
||||
// Çàïðåùàåì êîïèðîâàíèå, êàê â VBOHolder
|
||||
FrameBuffer(const FrameBuffer&) = delete;
|
||||
FrameBuffer& operator=(const FrameBuffer&) = delete;
|
||||
|
||||
void Bind(); // Íà÷àòü ðåíäåð â ýòîò áóôåð
|
||||
void Unbind(); // Âåðíóòüñÿ ê îáû÷íîìó ðåíäåðó â ýêðàí
|
||||
|
||||
GLuint getTextureID() const { return textureID; }
|
||||
int getWidth() const { return width; }
|
||||
int getHeight() const { return height; }
|
||||
};
|
||||
|
||||
} // namespace ZL
|
||||
28
Game.cpp
28
Game.cpp
@ -137,6 +137,7 @@ namespace ZL
|
||||
renderer.shaderManager.AddShaderFromFiles("defaultColor", "./shaders/defaultColor.vertex", "./shaders/defaultColor_web.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("env", "./shaders/env.vertex", "./shaders/env_web.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "./shaders/defaultAtmosphere.vertex", "./shaders/defaultAtmosphere.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("defaultColorPlanet", "./shaders/defaultColorPlanet.vertex", "./shaders/defaultColorPlanet_web.fragment", CONST_ZIP_FILE);
|
||||
|
||||
#else
|
||||
renderer.shaderManager.AddShaderFromFiles("default", "./shaders/default.vertex", "./shaders/default_desktop.fragment", CONST_ZIP_FILE);
|
||||
@ -144,7 +145,8 @@ namespace ZL
|
||||
renderer.shaderManager.AddShaderFromFiles("env", "./shaders/env_sky.vertex", "./shaders/env_sky_desktop.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "./shaders/defaultAtmosphere.vertex", "./shaders/defaultAtmosphere.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("defaultColor2", "./shaders/defaultColor_fog2.vertex", "./shaders/defaultColor_fog2_desktop.fragment", CONST_ZIP_FILE);
|
||||
|
||||
renderer.shaderManager.AddShaderFromFiles("defaultColorStones", "./shaders/defaultColor_fog_stones.vertex", "./shaders/defaultColor_fog_stones_desktop.fragment", CONST_ZIP_FILE);
|
||||
//renderer.shaderManager.AddShaderFromFiles("defaultColorBake", "./shaders/defaultColor_fog_bake.vertex", "./shaders/defaultColor_fog_stones_bake.fragment", CONST_ZIP_FILE);
|
||||
#endif
|
||||
|
||||
cubemapTexture = std::make_shared<Texture>(
|
||||
@ -181,8 +183,8 @@ namespace ZL
|
||||
|
||||
for (int i = 0; i < boxCoordsArr.size(); i++)
|
||||
{
|
||||
//boxRenderArr[i].AssignFrom(boxBase);
|
||||
boxRenderArr[i].data = CreateBaseConvexPolyhedron(1999);
|
||||
boxRenderArr[i].AssignFrom(boxBase);
|
||||
//boxRenderArr[i].data = CreateBaseConvexPolyhedron(1999);
|
||||
boxRenderArr[i].RefreshVBO();
|
||||
}
|
||||
|
||||
@ -357,8 +359,8 @@ namespace ZL
|
||||
renderer.TranslateMatrix(boxCoordsArr[i].pos);
|
||||
renderer.RotateMatrix(boxCoordsArr[i].m);
|
||||
|
||||
//glBindTexture(GL_TEXTURE_2D, boxTexture->getTexID());
|
||||
glBindTexture(GL_TEXTURE_2D, rockTexture->getTexID());
|
||||
glBindTexture(GL_TEXTURE_2D, boxTexture->getTexID());
|
||||
//glBindTexture(GL_TEXTURE_2D, rockTexture->getTexID());
|
||||
renderer.DrawVertexRenderStruct(boxRenderArr[i]);
|
||||
|
||||
renderer.PopMatrix();
|
||||
@ -624,6 +626,22 @@ namespace ZL
|
||||
}
|
||||
else if (event.type == SDL_KEYUP)
|
||||
{
|
||||
if (event.key.keysym.sym == SDLK_a)
|
||||
{
|
||||
planetObject.x += 1;
|
||||
}
|
||||
if (event.key.keysym.sym == SDLK_s)
|
||||
{
|
||||
planetObject.x -= 1;
|
||||
}
|
||||
if (event.key.keysym.sym == SDLK_q)
|
||||
{
|
||||
planetObject.y += 1;
|
||||
}
|
||||
if (event.key.keysym.sym == SDLK_w)
|
||||
{
|
||||
planetObject.y -= 1;
|
||||
}
|
||||
if (event.key.keysym.sym == SDLK_i)
|
||||
{
|
||||
Environment::shipVelocity += 500.f;
|
||||
|
||||
@ -327,10 +327,16 @@ namespace ZL {
|
||||
// Ñòàíäàðòíûå UV-êîîðäèíàòû äëÿ ïîêðûòèÿ îäíîãî òðåóãîëüíèêà
|
||||
// Ïîêðûâàåò òåêñòóðîé âñþ ãðàíü.
|
||||
const std::array<Vector2f, 3> triangleUVs = {
|
||||
Vector2f(0.5f, 1.0f),
|
||||
Vector2f(0.0f, 1.0f - sqrt(3)*0.5),
|
||||
Vector2f(1.0f, 1.0f - sqrt(3) * 0.5),
|
||||
|
||||
};
|
||||
/*const std::array<Vector2f, 3> triangleUVs2 = {
|
||||
Vector2f(0.0f, 0.0f),
|
||||
Vector2f(1.0f, 0.0f),
|
||||
Vector2f(0.0f, 1.0f)
|
||||
};
|
||||
};*/
|
||||
result.VertexIDs.reserve(geometry.size() * 3); // Çàïîëíÿåì ID çäåñü
|
||||
|
||||
for (const auto& t : geometry) {
|
||||
@ -341,6 +347,7 @@ namespace ZL {
|
||||
// Çàïîëíÿåì NormalData (íîðìàëü = íîðìàëèçîâàííàÿ ïîçèöèÿ íà ñôåðå)
|
||||
result.vertexData.NormalData.push_back(t.data[i].normalized());
|
||||
result.vertexData.TexCoordData.push_back(triangleUVs[i]);
|
||||
//result.vertexData.TexCoord2Data.push_back(triangleUVs2[i]);
|
||||
|
||||
// Çàïîëíÿåì VertexIDs
|
||||
result.VertexIDs.push_back(t.ids[i]);
|
||||
|
||||
@ -16,7 +16,8 @@ namespace ZL {
|
||||
|
||||
VertexID generateEdgeID(const VertexID& id1, const VertexID& id2);
|
||||
|
||||
constexpr static int MAX_LOD_LEVELS = 6;
|
||||
//constexpr static int MAX_LOD_LEVELS = 6;
|
||||
constexpr static int MAX_LOD_LEVELS = 1;
|
||||
|
||||
struct Triangle
|
||||
{
|
||||
|
||||
349
PlanetObject.cpp
349
PlanetObject.cpp
@ -23,12 +23,25 @@ namespace ZL {
|
||||
planetRenderStruct.data = planetData.getLodLevel(lodIndex).vertexData;
|
||||
planetRenderStruct.RefreshVBO();
|
||||
|
||||
sandTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/sand2.png", ""));
|
||||
stoneTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/rock.png", ""));
|
||||
planetRenderStructCut.data = planetData.getLodLevel(lodIndex).vertexData;
|
||||
planetRenderStructCut.data.PositionData.resize(3);
|
||||
planetRenderStructCut.RefreshVBO();
|
||||
//sandTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/sand2.png", ""));
|
||||
sandTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/sandx.png", ""));
|
||||
stoneTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/rockx.png", ""));
|
||||
|
||||
// Атмосфера
|
||||
planetAtmosphereRenderStruct.data = planetData.getAtmosphereLod().vertexData;
|
||||
planetAtmosphereRenderStruct.RefreshVBO();
|
||||
|
||||
|
||||
|
||||
planetStones = CreateStoneGroupData(777, planetData.getLodLevel(lodIndex));
|
||||
planetStones.inflate({ 0/*,1,2,3,4,5,6,7*/ });
|
||||
planetStonesRenderStruct.AssignFrom(planetStones.mesh);
|
||||
planetStonesRenderStruct.RefreshVBO();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void PlanetObject::prepareDrawData() {
|
||||
@ -37,81 +50,124 @@ namespace ZL {
|
||||
}
|
||||
|
||||
void PlanetObject::update(float deltaTimeMs) {
|
||||
// Получаем видимые треугольники, передавая позицию корабля
|
||||
// 1. Получаем базовые треугольники под камерой
|
||||
auto lr = planetData.getTrianglesUnderCamera(Environment::shipPosition);
|
||||
int currentLod = planetData.getCurrentLodIndex();
|
||||
const auto& fullMesh = planetData.getLodLevel(currentLod).vertexData;
|
||||
|
||||
planetRenderYellowStruct.data.PositionData.clear();
|
||||
planetRenderYellowStruct.data.TexCoordData.clear();
|
||||
|
||||
triangleIndicesToDraw.clear();
|
||||
std::set<int> usedYellow;
|
||||
// Временный вектор для сбора новых индексов
|
||||
std::vector<int> newIndices;
|
||||
std::set<int> used;
|
||||
|
||||
// Рекурсивно (или итеративно, как у тебя) собираем индексы видимых зон
|
||||
for (int i : lr) {
|
||||
planetRenderYellowStruct.data.PositionData.push_back(fullMesh.PositionData[i * 3]);
|
||||
planetRenderYellowStruct.data.PositionData.push_back(fullMesh.PositionData[i * 3 + 1]);
|
||||
planetRenderYellowStruct.data.PositionData.push_back(fullMesh.PositionData[i * 3 + 2]);
|
||||
planetRenderYellowStruct.data.TexCoordData.push_back(fullMesh.TexCoordData[i * 3]);
|
||||
planetRenderYellowStruct.data.TexCoordData.push_back(fullMesh.TexCoordData[i * 3 + 1]);
|
||||
planetRenderYellowStruct.data.TexCoordData.push_back(fullMesh.TexCoordData[i * 3 + 2]);
|
||||
usedYellow.insert(i);
|
||||
triangleIndicesToDraw.push_back(i);
|
||||
}
|
||||
if (used.insert(i).second) newIndices.push_back(i);
|
||||
|
||||
for (int i : lr) {
|
||||
auto neighbors = planetData.findNeighbors(i, currentLod);
|
||||
for (int n : neighbors) {
|
||||
if (usedYellow.count(n) == 0) {
|
||||
usedYellow.insert(n);
|
||||
triangleIndicesToDraw.push_back(n);
|
||||
planetRenderYellowStruct.data.PositionData.push_back(fullMesh.PositionData[n * 3]);
|
||||
planetRenderYellowStruct.data.PositionData.push_back(fullMesh.PositionData[n * 3 + 1]);
|
||||
planetRenderYellowStruct.data.PositionData.push_back(fullMesh.PositionData[n * 3 + 2]);
|
||||
planetRenderYellowStruct.data.TexCoordData.push_back(fullMesh.TexCoordData[n * 3]);
|
||||
planetRenderYellowStruct.data.TexCoordData.push_back(fullMesh.TexCoordData[n * 3 + 1]);
|
||||
planetRenderYellowStruct.data.TexCoordData.push_back(fullMesh.TexCoordData[n * 3 + 2]);
|
||||
}
|
||||
auto neighbors2 = planetData.findNeighbors(n, currentLod);
|
||||
if (used.insert(n).second) newIndices.push_back(n);
|
||||
|
||||
auto neighbors2 = planetData.findNeighbors(n, currentLod);
|
||||
for (int n2 : neighbors2) {
|
||||
if (usedYellow.count(n2) == 0) {
|
||||
usedYellow.insert(n2);
|
||||
triangleIndicesToDraw.push_back(n2);
|
||||
planetRenderYellowStruct.data.PositionData.push_back(fullMesh.PositionData[n2 * 3]);
|
||||
planetRenderYellowStruct.data.PositionData.push_back(fullMesh.PositionData[n2 * 3 + 1]);
|
||||
planetRenderYellowStruct.data.PositionData.push_back(fullMesh.PositionData[n2 * 3 + 2]);
|
||||
planetRenderYellowStruct.data.TexCoordData.push_back(fullMesh.TexCoordData[n2 * 3]);
|
||||
planetRenderYellowStruct.data.TexCoordData.push_back(fullMesh.TexCoordData[n2 * 3 + 1]);
|
||||
planetRenderYellowStruct.data.TexCoordData.push_back(fullMesh.TexCoordData[n2 * 3 + 2]);
|
||||
}
|
||||
if (used.insert(n2).second) newIndices.push_back(n2);
|
||||
}
|
||||
}
|
||||
}
|
||||
planetRenderYellowStruct.RefreshVBO();
|
||||
|
||||
planetStonesRenderStruct.data = CreateConvexPolyhedron(777, planetData.getLodLevel(5), triangleIndicesToDraw);
|
||||
planetStonesRenderStruct.RefreshVBO();
|
||||
// 2. Сортируем новый список, чтобы порядок не влиял на сравнение
|
||||
std::sort(newIndices.begin(), newIndices.end());
|
||||
|
||||
// 3. Сравниваем с тем, что было нарисовано в прошлый раз
|
||||
if (newIndices != triangleIndicesToDraw) {
|
||||
// Обновляем список индексов (используем move для эффективности)
|
||||
triangleIndicesToDraw = std::move(newIndices);
|
||||
|
||||
// --- ОБНОВЛЯЕМ ЖЕЛТУЮ ЗОНУ (только когда изменился состав треугольников) ---
|
||||
const auto& fullMesh = planetData.getLodLevel(currentLod).vertexData;
|
||||
planetRenderYellowStruct.data.PositionData.clear();
|
||||
planetRenderYellowStruct.data.TexCoordData.clear();
|
||||
|
||||
for (int i : triangleIndicesToDraw) {
|
||||
// Копируем геометрию для подсветки
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
planetRenderYellowStruct.data.PositionData.push_back(fullMesh.PositionData[i * 3 + j]);
|
||||
planetRenderYellowStruct.data.TexCoordData.push_back(fullMesh.TexCoordData[i * 3 + j]);
|
||||
}
|
||||
}
|
||||
planetRenderYellowStruct.RefreshVBO();
|
||||
|
||||
// --- ОБНОВЛЯЕМ КАМНИ (через новую структуру StoneGroup) ---
|
||||
//planetStones.inflate(triangleIndicesToDraw);
|
||||
// Используем AssignFrom, он внутри сам вызывает RefreshVBO
|
||||
//planetStonesRenderStruct.AssignFrom(planetStones.mesh);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void PlanetObject::bakeStoneTexture(Renderer& renderer) {
|
||||
// 1. Создаем FB (размер 512x512 для четкости)
|
||||
|
||||
void PlanetObject::draw(Renderer& renderer) {
|
||||
|
||||
prepareDrawData();
|
||||
glViewport(0, 0, 1024, 1024);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
//--------------------------
|
||||
/*
|
||||
static const std::string stoneShader = "defaultColor2";
|
||||
renderer.shaderManager.PushShader(stoneShader);
|
||||
|
||||
drawPlanet(renderer);
|
||||
//drawYellowZone(renderer);
|
||||
drawStones(renderer);
|
||||
static const std::string vPositionName = "vPosition";
|
||||
static const std::string vColorName = "vColor";
|
||||
static const std::string vNormalName = "vNormal";
|
||||
static const std::string vTexCoordName = "vTexCoord";
|
||||
//static const std::string vTexCoord3Name = "vTexCoord3";
|
||||
static const std::string textureUniformName = "Texture";
|
||||
|
||||
drawAtmosphere(renderer);
|
||||
}
|
||||
renderer.EnableVertexAttribArray(vPositionName);
|
||||
renderer.EnableVertexAttribArray(vColorName);
|
||||
renderer.EnableVertexAttribArray(vNormalName);
|
||||
renderer.EnableVertexAttribArray(vTexCoordName);
|
||||
|
||||
void PlanetObject::drawPlanet(Renderer& renderer)
|
||||
{
|
||||
static const std::string defaultShaderName = "defaultColor";
|
||||
// 2. Очищаем (черный фон - это "нет камня")
|
||||
glClearColor(0.0f, 0.5f, 0.0f, 0.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// 3. Настраиваем камеру (Ортографическая проекция над треугольником)
|
||||
// Смотрим на плоскость, где лежит эталонный треугольник
|
||||
renderer.PushProjectionMatrix(0.666667f, 1.777779f, 2000, 200000);
|
||||
renderer.PushMatrix();
|
||||
renderer.LoadIdentity();
|
||||
renderer.TranslateMatrix({ 0, 0, -45000.0f }); // Отодвигаемся, чтобы видеть камни
|
||||
|
||||
// 4. Рендерим камни
|
||||
// Берем семена и параметры из первого треугольника (индекс 0)
|
||||
// Используем упрощенный вызов отрисовки геометрии камней
|
||||
|
||||
// Рисуем меш камней для ОДНОГО эталонного треугольника
|
||||
// Здесь используем уже созданную нами функцию inflate для индекса 0
|
||||
planetStones.inflate({ 0 });
|
||||
VertexRenderStruct tempStoneRender;
|
||||
tempStoneRender.AssignFrom(planetStones.mesh);
|
||||
|
||||
renderer.DrawVertexRenderStruct(tempStoneRender);
|
||||
|
||||
renderer.PopMatrix();
|
||||
renderer.PopProjectionMatrix();
|
||||
|
||||
//stoneMapFB->Unbind();
|
||||
|
||||
renderer.DisableVertexAttribArray(vPositionName);
|
||||
renderer.DisableVertexAttribArray(vColorName);
|
||||
renderer.DisableVertexAttribArray(vNormalName);
|
||||
renderer.DisableVertexAttribArray(vTexCoordName);
|
||||
renderer.shaderManager.PopShader();
|
||||
|
||||
|
||||
|
||||
// Восстанавливаем вьюпорт под экран
|
||||
glViewport(0, 0, Environment::width, Environment::height);*/
|
||||
|
||||
//static const std::string defaultShaderName = "defaultColor";
|
||||
static const std::string defaultShaderName2 = "defaultColor2";
|
||||
static const std::string vPositionName = "vPosition";
|
||||
static const std::string vColorName = "vColor";
|
||||
@ -120,7 +176,10 @@ namespace ZL {
|
||||
//static const std::string vTexCoord3Name = "vTexCoord3";
|
||||
static const std::string textureUniformName = "Texture";
|
||||
|
||||
renderer.shaderManager.PushShader(defaultShaderName);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
renderer.shaderManager.PushShader(defaultShaderName2);
|
||||
renderer.RenderUniform1i(textureUniformName, 0);
|
||||
renderer.EnableVertexAttribArray(vPositionName);
|
||||
renderer.EnableVertexAttribArray(vColorName);
|
||||
@ -133,6 +192,166 @@ namespace ZL {
|
||||
const float currentZNear = zRange.first;
|
||||
const float currentZFar = zRange.second;
|
||||
|
||||
// 2. Применяем динамическую матрицу проекции
|
||||
/*renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
|
||||
1.0,
|
||||
currentZNear, currentZFar);*/
|
||||
renderer.PushProjectionMatrix(
|
||||
-PlanetData::PLANET_RADIUS*sqrt(2)*(1-0/100.f)*0.5,
|
||||
PlanetData::PLANET_RADIUS * sqrt(2) * (1 - 0 / 100.f) * 0.5,
|
||||
-PlanetData::PLANET_RADIUS * sqrt(2) * (1 - 0 / 100.f) * 0.5,
|
||||
PlanetData::PLANET_RADIUS * sqrt(2) * (1 - 0 / 100.f) * 0.5,
|
||||
currentZNear, currentZFar);
|
||||
|
||||
renderer.PushMatrix();
|
||||
renderer.LoadIdentity();
|
||||
//renderer.RotateMatrix(Environment::inverseShipMatrix);
|
||||
renderer.TranslateMatrix(Vector3f{ 0,0,-45000 });
|
||||
|
||||
|
||||
Vector4f q1 = QuatFromRotateAroundX(-M_PI * 45.0 / 180.0);
|
||||
Vector4f q2 = QuatFromRotateAroundY(M_PI * 45.0 / 180.0);
|
||||
//Vector4f q3 = {-cos(0.5*M_PI * x / 180.0), -cos(0.5 * M_PI * x / 180.0), -cos(0.5 * M_PI * x / 180.0),sin(0.5 * M_PI * x / 180.0) };
|
||||
|
||||
Matrix3f r1 = QuatToMatrix(q1);
|
||||
|
||||
Matrix3f r2 = QuatToMatrix(q2);
|
||||
|
||||
//Matrix3f r3 = QuatToMatrix(q3);
|
||||
|
||||
Matrix3f invr = InverseMatrix( MultMatrixMatrix(r2, r1));
|
||||
|
||||
renderer.RotateMatrix(invr);
|
||||
|
||||
|
||||
|
||||
const Matrix4f viewMatrix = renderer.GetCurrentModelViewMatrix();
|
||||
|
||||
|
||||
Vector3f lightDir_World = Vector3f(1.0f, 0.0f, -1.0f).normalized();
|
||||
// В OpenGL/шейдерах удобнее работать с вектором, указывающим ОТ источника к поверхности.
|
||||
Vector3f lightDirection_World = -lightDir_World; // Вектор, направленный от источника
|
||||
Vector3f lightDirection_View;
|
||||
|
||||
lightDirection_View.v[0] = viewMatrix.m[0] * lightDirection_World.v[0] + viewMatrix.m[4] * lightDirection_World.v[1] + viewMatrix.m[8] * lightDirection_World.v[2];
|
||||
lightDirection_View.v[1] = viewMatrix.m[1] * lightDirection_World.v[0] + viewMatrix.m[5] * lightDirection_World.v[1] + viewMatrix.m[9] * lightDirection_World.v[2];
|
||||
lightDirection_View.v[2] = viewMatrix.m[2] * lightDirection_World.v[0] + viewMatrix.m[6] * lightDirection_World.v[1] + viewMatrix.m[10] * lightDirection_World.v[2];
|
||||
lightDirection_View = lightDirection_View.normalized(); // Нормализуем на всякий случай
|
||||
|
||||
// Установка uniform-переменной
|
||||
// Предполагается, что RenderUniform3fv определена в Renderer.h
|
||||
/*
|
||||
renderer.RenderUniform3fv("uLightDirection", &lightDirection_View.v[0]);
|
||||
renderer.RenderUniformMatrix4fv("ModelViewMatrix", false, &viewMatrix.m[0]);
|
||||
|
||||
renderer.RenderUniform1f("uDistanceToPlanetSurface", dist);
|
||||
renderer.RenderUniform1f("uCurrentZFar", currentZFar);
|
||||
Vector3f color2 = { 1.0, 1.0, 1.0 };
|
||||
|
||||
renderer.RenderUniform3fv("uColor", &color2.v[0]);*/
|
||||
|
||||
//glEnable(GL_BLEND);
|
||||
//glBlendFunc(GL_SRC_ALPHA, GL_ONE);// Аддитивное смешивание для эффекта свечения
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, sandTexture->getTexID());
|
||||
|
||||
|
||||
//planetRenderStructCut.AssignFrom(planetRenderStruct.data);
|
||||
//planetRenderStructCut.data.PositionData.resize(3);
|
||||
//planetRenderStructCut.RefreshVBO();
|
||||
renderer.DrawVertexRenderStruct(planetRenderStructCut);
|
||||
|
||||
|
||||
//planetStones.inflate({0/*,1,2,3,4,5,6,7*/});
|
||||
//planetStonesRenderStruct.AssignFrom(planetStones.mesh);
|
||||
//planetStonesRenderStruct.RefreshVBO();
|
||||
|
||||
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
if (planetStonesRenderStruct.data.PositionData.size() > 0)
|
||||
{
|
||||
|
||||
//glBindTexture(GL_TEXTURE_2D, fb->getTextureID());
|
||||
glBindTexture(GL_TEXTURE_2D, stoneTexture->getTexID());
|
||||
renderer.DrawVertexRenderStruct(planetStonesRenderStruct);
|
||||
//glDisable(GL_BLEND);
|
||||
CheckGlError();
|
||||
}
|
||||
|
||||
|
||||
renderer.PopMatrix();
|
||||
renderer.PopProjectionMatrix();
|
||||
//renderer.DisableVertexAttribArray(vTexCoord3Name);
|
||||
renderer.DisableVertexAttribArray(vTexCoordName);
|
||||
renderer.DisableVertexAttribArray(vNormalName);
|
||||
renderer.DisableVertexAttribArray(vColorName);
|
||||
renderer.DisableVertexAttribArray(vPositionName);
|
||||
renderer.shaderManager.PopShader();
|
||||
CheckGlError();
|
||||
|
||||
|
||||
//glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void PlanetObject::draw(Renderer& renderer) {
|
||||
|
||||
prepareDrawData();
|
||||
|
||||
|
||||
{
|
||||
if (stoneMapFB == nullptr)
|
||||
{
|
||||
stoneMapFB = std::make_unique<FrameBuffer>(1024, 1024);
|
||||
}
|
||||
stoneMapFB->Bind();
|
||||
|
||||
bakeStoneTexture(renderer);
|
||||
|
||||
stoneMapFB->Unbind();
|
||||
|
||||
}
|
||||
|
||||
//bakeStoneTexture(renderer);
|
||||
|
||||
glViewport(0, 0, Environment::width, Environment::height);
|
||||
//--------------------------
|
||||
|
||||
drawPlanet(renderer);
|
||||
//drawYellowZone(renderer);
|
||||
//drawStones(renderer);
|
||||
|
||||
//drawAtmosphere(renderer);
|
||||
}
|
||||
|
||||
void PlanetObject::drawPlanet(Renderer& renderer)
|
||||
{
|
||||
static const std::string defaultShaderName = "defaultColorStones";
|
||||
|
||||
static const std::string vPositionName = "vPosition";
|
||||
static const std::string vColorName = "vColor";
|
||||
static const std::string vNormalName = "vNormal";
|
||||
static const std::string vTexCoordName = "vTexCoord";
|
||||
static const std::string vTexCoord2Name = "vTexCoord2";
|
||||
//static const std::string vTexCoord3Name = "vTexCoord3";
|
||||
static const std::string textureUniformName = "Texture";
|
||||
|
||||
renderer.shaderManager.PushShader(defaultShaderName);
|
||||
|
||||
renderer.EnableVertexAttribArray(vPositionName);
|
||||
renderer.EnableVertexAttribArray(vColorName);
|
||||
renderer.EnableVertexAttribArray(vNormalName);
|
||||
renderer.EnableVertexAttribArray(vTexCoordName);
|
||||
//renderer.EnableVertexAttribArray(vTexCoord3Name);
|
||||
|
||||
float dist = planetData.distanceToPlanetSurface(Environment::shipPosition);
|
||||
auto zRange = planetData.calculateZRange(dist);
|
||||
const float currentZNear = zRange.first;
|
||||
const float currentZFar = zRange.second;
|
||||
|
||||
// 2. Применяем динамическую матрицу проекции
|
||||
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
|
||||
static_cast<float>(Environment::width) / static_cast<float>(Environment::height),
|
||||
@ -146,7 +365,6 @@ namespace ZL {
|
||||
|
||||
const Matrix4f viewMatrix = renderer.GetCurrentModelViewMatrix();
|
||||
|
||||
|
||||
Vector3f lightDir_World = Vector3f(1.0f, 0.0f, -1.0f).normalized();
|
||||
// В OpenGL/шейдерах удобнее работать с вектором, указывающим ОТ источника к поверхности.
|
||||
Vector3f lightDirection_World = -lightDir_World; // Вектор, направленный от источника
|
||||
@ -164,10 +382,20 @@ namespace ZL {
|
||||
|
||||
renderer.RenderUniform1f("uDistanceToPlanetSurface", dist);
|
||||
renderer.RenderUniform1f("uCurrentZFar", currentZFar);
|
||||
//glEnable(GL_BLEND);
|
||||
//glBlendFunc(GL_SRC_ALPHA, GL_ONE);// Аддитивное смешивание для эффекта свечения
|
||||
renderer.RenderUniform1f("testShift1", x/500.f);
|
||||
renderer.RenderUniform1f("testShift2", y / 5000.f);
|
||||
|
||||
renderer.RenderUniform1i("Texture", 0);
|
||||
|
||||
renderer.RenderUniform1i("StoneMap", 1);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, stoneMapFB->getTextureID());
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, sandTexture->getTexID());
|
||||
|
||||
|
||||
|
||||
renderer.DrawVertexRenderStruct(planetRenderStruct);
|
||||
//glDisable(GL_BLEND);
|
||||
CheckGlError();
|
||||
@ -176,6 +404,7 @@ namespace ZL {
|
||||
renderer.PopMatrix();
|
||||
renderer.PopProjectionMatrix();
|
||||
//renderer.DisableVertexAttribArray(vTexCoord3Name);
|
||||
renderer.DisableVertexAttribArray(vTexCoord2Name);
|
||||
renderer.DisableVertexAttribArray(vTexCoordName);
|
||||
renderer.DisableVertexAttribArray(vNormalName);
|
||||
renderer.DisableVertexAttribArray(vColorName);
|
||||
@ -188,7 +417,7 @@ namespace ZL {
|
||||
|
||||
void PlanetObject::drawStones(Renderer& renderer)
|
||||
{
|
||||
static const std::string defaultShaderName = "defaultColor";
|
||||
//static const std::string defaultShaderName = "defaultColor";
|
||||
static const std::string defaultShaderName2 = "defaultColor2";
|
||||
static const std::string vPositionName = "vPosition";
|
||||
static const std::string vColorName = "vColor";
|
||||
@ -223,7 +452,6 @@ namespace ZL {
|
||||
|
||||
const Matrix4f viewMatrix = renderer.GetCurrentModelViewMatrix();
|
||||
|
||||
|
||||
Vector3f lightDir_World = Vector3f(1.0f, 0.0f, -1.0f).normalized();
|
||||
// В OpenGL/шейдерах удобнее работать с вектором, указывающим ОТ источника к поверхности.
|
||||
Vector3f lightDirection_World = -lightDir_World; // Вектор, направленный от источника
|
||||
@ -250,6 +478,7 @@ namespace ZL {
|
||||
|
||||
if (planetStonesRenderStruct.data.PositionData.size() > 0)
|
||||
{
|
||||
//glBindTexture(GL_TEXTURE_2D, fb->getTextureID());
|
||||
glBindTexture(GL_TEXTURE_2D, stoneTexture->getTexID());
|
||||
renderer.DrawVertexRenderStruct(planetStonesRenderStruct);
|
||||
//glDisable(GL_BLEND);
|
||||
|
||||
@ -15,6 +15,8 @@
|
||||
#include <set>
|
||||
#include "Perlin.h"
|
||||
#include "PlanetData.h"
|
||||
#include "StoneObject.h"
|
||||
#include "FrameBuffer.h"
|
||||
|
||||
namespace ZL {
|
||||
|
||||
@ -25,9 +27,11 @@ namespace ZL {
|
||||
|
||||
// Данные только для рендеринга (OpenGL specific)
|
||||
VertexRenderStruct planetRenderStruct;
|
||||
VertexRenderStruct planetRenderStructCut;
|
||||
VertexRenderStruct planetRenderYellowStruct;
|
||||
VertexRenderStruct planetAtmosphereRenderStruct;
|
||||
VertexRenderStruct planetStonesRenderStruct;
|
||||
StoneGroup planetStones;
|
||||
|
||||
std::vector<int> triangleIndicesToDraw;
|
||||
|
||||
@ -37,11 +41,17 @@ namespace ZL {
|
||||
bool drawDataDirty = true;
|
||||
void prepareDrawData();
|
||||
|
||||
std::unique_ptr<FrameBuffer> stoneMapFB;
|
||||
|
||||
public:
|
||||
PlanetObject();
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
void init();
|
||||
void update(float deltaTimeMs);
|
||||
void bakeStoneTexture(Renderer& renderer);
|
||||
void draw(Renderer& renderer);
|
||||
void drawStones(Renderer& renderer);
|
||||
void drawPlanet(Renderer& renderer);
|
||||
|
||||
27
Renderer.cpp
27
Renderer.cpp
@ -294,6 +294,18 @@ namespace ZL {
|
||||
glBufferData(GL_ARRAY_BUFFER, data.TexCoordData.size() * 8, &data.TexCoordData[0], GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
/*if (data.TexCoord2Data.size() > 0)
|
||||
{
|
||||
if (!texCoord2VBO)
|
||||
{
|
||||
texCoord2VBO = std::make_shared<VBOHolder>();
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, texCoord2VBO->getBuffer());
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, data.TexCoord2Data.size() * 8, &data.TexCoord2Data[0], GL_STATIC_DRAW);
|
||||
}*/
|
||||
|
||||
if (data.TexCoord3Data.size() > 0)
|
||||
{
|
||||
if (!texCoord3VBO)
|
||||
@ -443,6 +455,18 @@ namespace ZL {
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::PushProjectionMatrix(float xmin, float xmax, float ymin, float ymax, float zNear, float zFar)
|
||||
{
|
||||
Matrix4f m = MakeOrthoMatrix(xmin, xmax, ymin, ymax, zNear, zFar);
|
||||
ProjectionMatrixStack.push(m);
|
||||
SetMatrix();
|
||||
|
||||
if (ProjectionMatrixStack.size() > CONST_MATRIX_STACK_SIZE)
|
||||
{
|
||||
throw std::runtime_error("Projection matrix stack overflow!!!!");
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::PushPerspectiveProjectionMatrix(float fovY, float aspectRatio, float zNear, float zFar)
|
||||
{
|
||||
Matrix4f m = MakePerspectiveMatrix(fovY, aspectRatio, zNear, zFar);
|
||||
@ -764,6 +788,7 @@ namespace ZL {
|
||||
static const std::string vBinormal("vBinormal");
|
||||
static const std::string vColor("vColor");
|
||||
static const std::string vTexCoord("vTexCoord");
|
||||
//static const std::string vTexCoord2("vTexCoord2");
|
||||
static const std::string vTexCoord3("vTexCoord3");
|
||||
static const std::string vPosition("vPosition");
|
||||
|
||||
@ -798,7 +823,7 @@ namespace ZL {
|
||||
if (VertexRenderStruct.data.TexCoord3Data.size() > 0)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.texCoord3VBO->getBuffer());
|
||||
VertexAttribPointer2fv(vTexCoord3, 0, NULL);
|
||||
VertexAttribPointer3fv(vTexCoord3, 0, NULL);
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.positionVBO->getBuffer());
|
||||
|
||||
@ -44,6 +44,7 @@ namespace ZL {
|
||||
{
|
||||
std::vector<Vector3f> PositionData;
|
||||
std::vector<Vector2f> TexCoordData;
|
||||
//std::vector<Vector2f> TexCoord2Data;
|
||||
std::vector<Vector3f> TexCoord3Data;
|
||||
std::vector<Vector3f> NormalData;
|
||||
std::vector<Vector3f> TangentData;
|
||||
@ -64,6 +65,7 @@ namespace ZL {
|
||||
std::shared_ptr<VAOHolder> vao;
|
||||
std::shared_ptr<VBOHolder> positionVBO;
|
||||
std::shared_ptr<VBOHolder> texCoordVBO;
|
||||
//std::shared_ptr<VBOHolder> texCoord2VBO;
|
||||
std::shared_ptr<VBOHolder> texCoord3VBO;
|
||||
std::shared_ptr<VBOHolder> normalVBO;
|
||||
std::shared_ptr<VBOHolder> tangentVBO;
|
||||
@ -95,6 +97,7 @@ namespace ZL {
|
||||
void InitOpenGL();
|
||||
|
||||
void PushProjectionMatrix(float width, float height, float zNear = 0.f, float zFar = 1.f);
|
||||
void PushProjectionMatrix(float xmin, float xmax, float ymin, float ymax, float zNear, float zFar);
|
||||
void PushPerspectiveProjectionMatrix(float fovY, float aspectRatio, float zNear, float zFar);
|
||||
void PopProjectionMatrix();
|
||||
|
||||
|
||||
@ -39,6 +39,7 @@ namespace ZL {
|
||||
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &fragmentShaderCompiled);
|
||||
glGetShaderInfoLog(fragmentShader, CONST_INFOLOG_LENGTH, &infoLogLength, infoLog);
|
||||
|
||||
|
||||
if (!vertexShaderCompiled)
|
||||
{
|
||||
throw std::runtime_error("Failed to compile vertex shader code!");
|
||||
|
||||
139
StoneObject.cpp
139
StoneObject.cpp
@ -47,7 +47,7 @@ namespace ZL {
|
||||
|
||||
// --- ÊÎÍÑÒÀÍÒÛ ÏÀÐÀÌÅÒÐÎÂ (êàê âû ïðîñèëè) ---
|
||||
//const float BASE_SCALE = 3.0f; // Îáùèé ðàçìåð êàìíÿ
|
||||
const float BASE_SCALE = 20.0f; // Îáùèé ðàçìåð êàìíÿ
|
||||
const float BASE_SCALE = 800.0f; // Îáùèé ðàçìåð êàìíÿ
|
||||
const float MIN_AXIS_SCALE = 0.5f; // Ìèíèìàëüíîå ðàñòÿæåíèå/ñæàòèå ïî îñè
|
||||
const float MAX_AXIS_SCALE = 1.5f; // Ìàêñèìàëüíîå ðàñòÿæåíèå/ñæàòèå ïî îñè
|
||||
const float MIN_PERTURBATION = 0.05f; // Ìèíèìàëüíîå ðàäèàëüíîå âîçìóùåíèå âåðøèíû
|
||||
@ -201,107 +201,70 @@ namespace ZL {
|
||||
return result;
|
||||
}
|
||||
|
||||
VertexDataStruct CreateConvexPolyhedron(uint64_t seed, const LodLevel& planetLodLevel, const std::vector<int>& triangleIndices) {
|
||||
|
||||
VertexDataStruct finalMesh;
|
||||
StoneGroup CreateStoneGroupData(uint64_t globalSeed, const LodLevel& planetLodLevel) {
|
||||
StoneGroup group;
|
||||
const int STONES_PER_TRIANGLE = 100;
|
||||
|
||||
// Êîíñòàíòû òðàíñôîðìàöèè (íóæíû çäåñü, ÷òîáû êàæäûé êàìåíü áûë óíèêàëüíûì)
|
||||
const float MIN_AXIS_SCALE = 0.5f;
|
||||
const float MAX_AXIS_SCALE = 1.5f;
|
||||
// Ðåçåðâèðóåì ìåñòî ïîä âñå òðåóãîëüíèêè òåêóùåãî LOD
|
||||
group.allInstances.resize(planetLodLevel.triangles.size());
|
||||
|
||||
// 1. Ñîçäàåì ÁÀÇÎÂÛÉ ÌÅØ ÎÄÈÍ ÐÀÇ, ÷òîáû íå ïîâòîðÿòü ñëîæíóþ ãåíåðàöèþ
|
||||
// Èñïîëüçóåì îòäåëüíûé seed äëÿ áàçîâîé ôîðìû, ÷òîáû îíà áûëà óíèêàëüíîé,
|
||||
// íî îñòàâàëàñü îäèíàêîâîé ïðè ðàçíûõ seed äëÿ ðàçìåùåíèÿ.
|
||||
uint64_t baseSeed = 1337; // Êîíñòàíòíûé seed äëÿ ôîðìû êàìíÿ
|
||||
VertexDataStruct baseStone = CreateBaseConvexPolyhedron(baseSeed);
|
||||
for (size_t tIdx = 0; tIdx < planetLodLevel.triangles.size(); ++tIdx) {
|
||||
const Triangle& tri = planetLodLevel.triangles[tIdx];
|
||||
std::mt19937 engine(static_cast<unsigned int>(globalSeed));
|
||||
|
||||
// 2. Èòåðèðóåìñÿ ïî çàäàííûì òðåóãîëüíèêàì
|
||||
for (int triangleIndex : triangleIndices) {
|
||||
for (int i = 0; i < STONES_PER_TRIANGLE; ++i) {
|
||||
StoneInstance instance;
|
||||
instance.seed = globalSeed;// + tIdx * 1000 + i; // Óíèêàëüíûé ñèä äëÿ êàæäîãî êàìíÿ
|
||||
|
||||
std::mt19937 engine(static_cast<unsigned int>(seed));
|
||||
instance.position = GetRandomPointOnTriangle(tri, engine);
|
||||
|
||||
|
||||
if (triangleIndex >= planetLodLevel.triangles.size()) {
|
||||
// Îáðàáîòêà îøèáêè
|
||||
continue;
|
||||
}
|
||||
|
||||
const Triangle& currentTriangle = planetLodLevel.triangles[triangleIndex];
|
||||
|
||||
// 3. Ãåíåðèðóåì 100 êàìíåé íà êàæäîì òðåóãîëüíèêå
|
||||
for (int i = 0; i < STONES_PER_TRIANGLE; i++) {
|
||||
|
||||
// --- 3.1. Ãåíåðèðóåì ñëó÷àéíîå ìåñòîïîëîæåíèå íà òðåóãîëüíèêå ---
|
||||
Vector3f stoneCenter = GetRandomPointOnTriangle(currentTriangle, engine);
|
||||
|
||||
// --- 3.2. Ïðèìåíÿåì ñëó÷àéíóþ òðàíñôîðìàöèþ (Ìàñøòàá + Ïîâîðîò) ---
|
||||
|
||||
// Ñëó÷àéíûå ìàñøòàáû
|
||||
Vector3f scaleFactors = {
|
||||
getRandomFloat(engine, MIN_AXIS_SCALE, MAX_AXIS_SCALE),
|
||||
getRandomFloat(engine, MIN_AXIS_SCALE, MAX_AXIS_SCALE),
|
||||
getRandomFloat(engine, MIN_AXIS_SCALE, MAX_AXIS_SCALE)
|
||||
// Ãåíåðèðóåì ñëó÷àéíûå ïàðàìåòðû îäèí ðàç
|
||||
instance.scale = {
|
||||
getRandomFloat(engine, 0.5f, 1.5f),
|
||||
getRandomFloat(engine, 0.5f, 1.5f),
|
||||
getRandomFloat(engine, 0.5f, 1.5f)
|
||||
};
|
||||
|
||||
// Ñëó÷àéíûé ïîâîðîò (íàïðèìåð, âîêðóã îñè íîðìàëè ê ïîâåðõíîñòè)
|
||||
// Äëÿ ðåàëèñòè÷íîñòè, êàìåíü äîëæåí ëåæàòü íà ïîâåðõíîñòè.
|
||||
// Âåêòîð 'ââåðõ' äëÿ êàìíÿ äîëæåí áûòü âûðîâíåí ïî íîðìàëè òðåóãîëüíèêà.
|
||||
|
||||
// 1. Ñîçäàåì âðàùåíèå âîêðóã íîðìàëè òðåóãîëüíèêà (currentTriangle.normal)
|
||||
float angle = getRandomFloat(engine, 0.0f, 360.0f);
|
||||
// (Äëÿ ïðîñòîòû çäåñü èñïîëüçóåòñÿ Matrix4f::Identity, íî âàì íóæíî ðåàëèçîâàòü
|
||||
// QuaternionFromAxisAngle äëÿ êîððåêòíîãî âðàùåíèÿ âîêðóã çàäàííîé îñè Normal)
|
||||
|
||||
// --- ÏÐÎÑÒÎÅ ÐÅØÅÍÈÅ: Ñëó÷àéíûé ïîâîðîò âîêðóã òðåõ îñåé ---
|
||||
Vector4f qx = QuatFromRotateAroundX(getRandomFloat(engine, 0.0f, 360.0f));
|
||||
Vector4f qy = QuatFromRotateAroundY(getRandomFloat(engine, 0.0f, 360.0f));
|
||||
Vector4f qz = QuatFromRotateAroundZ(getRandomFloat(engine, 0.0f, 360.0f));
|
||||
Vector4f qFinal = slerp(qx, qy, 0.5f);
|
||||
qFinal = slerp(qFinal, qz, 0.5f).normalized();
|
||||
Matrix3f rotationMatrix = QuatToMatrix(qFinal);
|
||||
instance.rotation = slerp(slerp(qx, qy, 0.5f), qz, 0.5f).normalized();
|
||||
|
||||
|
||||
// --- 3.3. Òðàíñôîðìèðóåì è Ñìåùàåì âåðøèíû áàçîâîãî ìåøà ---
|
||||
|
||||
// Êîïèðóåì äàííûå äëÿ òåêóùåãî êàìíÿ
|
||||
VertexDataStruct currentStone = baseStone;
|
||||
|
||||
// Ïðèìåíÿåì ìàñøòàáèðîâàíèå, ïîâîðîò, è ñìåùåíèå ê êàæäîé âåðøèíå
|
||||
for (size_t j = 0; j < currentStone.PositionData.size(); j++) {
|
||||
Vector3f& pos = currentStone.PositionData[j];
|
||||
Vector3f& norm = currentStone.NormalData[j];
|
||||
|
||||
// 1. Ìàñøòàáèðîâàíèå
|
||||
pos.v[0] *= scaleFactors.v[0];
|
||||
pos.v[1] *= scaleFactors.v[1];
|
||||
pos.v[2] *= scaleFactors.v[2];
|
||||
|
||||
// 2. Ïîâîðîò
|
||||
pos = MultMatrixVector(rotationMatrix, pos);
|
||||
norm = MultMatrixVector(rotationMatrix, norm);
|
||||
|
||||
// 3. Ñìåùåíèå (Translation)
|
||||
pos = pos + stoneCenter;
|
||||
}
|
||||
|
||||
// --- 3.4. Îáúåäèíÿåì ìåøè ---
|
||||
finalMesh.PositionData.insert(finalMesh.PositionData.end(),
|
||||
currentStone.PositionData.begin(),
|
||||
currentStone.PositionData.end());
|
||||
|
||||
finalMesh.NormalData.insert(finalMesh.NormalData.end(),
|
||||
currentStone.NormalData.begin(),
|
||||
currentStone.NormalData.end());
|
||||
|
||||
finalMesh.TexCoordData.insert(finalMesh.TexCoordData.end(),
|
||||
currentStone.TexCoordData.begin(),
|
||||
currentStone.TexCoordData.end());
|
||||
|
||||
// ... àíàëîãè÷íî äëÿ äðóãèõ äàííûõ (Tangent, Binormal, Color)
|
||||
group.allInstances[tIdx].push_back(instance);
|
||||
}
|
||||
}
|
||||
return group;
|
||||
}
|
||||
|
||||
return finalMesh;
|
||||
void StoneGroup::inflate(const std::vector<int>& triangleIndices) {
|
||||
// 1. Î÷èùàåì òåêóùèé ìåø ïåðåä çàïîëíåíèåì
|
||||
mesh.PositionData.clear();
|
||||
mesh.NormalData.clear();
|
||||
mesh.TexCoordData.clear();
|
||||
|
||||
static VertexDataStruct baseStone = CreateBaseConvexPolyhedron(1337);
|
||||
|
||||
// 2. Íàïîëíÿåì ìåø òîëüêî äëÿ âèäèìûõ òðåóãîëüíèêîâ
|
||||
for (int tIdx : triangleIndices) {
|
||||
if (tIdx >= allInstances.size()) continue;
|
||||
|
||||
for (const auto& inst : allInstances[tIdx]) {
|
||||
Matrix3f rotMat = QuatToMatrix(inst.rotation);
|
||||
|
||||
for (size_t j = 0; j < baseStone.PositionData.size(); ++j) {
|
||||
Vector3f p = baseStone.PositionData[j];
|
||||
Vector3f n = baseStone.NormalData[j];
|
||||
|
||||
// Ìàñøòàá -> Ïîâîðîò -> Ñìåùåíèå
|
||||
p.v[0] *= inst.scale.v[0];
|
||||
p.v[1] *= inst.scale.v[1];
|
||||
p.v[2] *= inst.scale.v[2];
|
||||
|
||||
mesh.PositionData.push_back(MultMatrixVector(rotMat, p) + inst.position);
|
||||
mesh.NormalData.push_back(MultMatrixVector(rotMat, n));
|
||||
mesh.TexCoordData.push_back(baseStone.TexCoordData[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace ZL
|
||||
|
||||
@ -5,7 +5,26 @@
|
||||
|
||||
namespace ZL {
|
||||
|
||||
VertexDataStruct CreateBaseConvexPolyhedron(uint64_t seed);
|
||||
VertexDataStruct CreateConvexPolyhedron(uint64_t seed, const LodLevel& planetLodLevel, const std::vector<int>& triangleIndices);
|
||||
struct StoneInstance {
|
||||
uint64_t seed;
|
||||
Vector3f position;
|
||||
Vector3f scale;
|
||||
Vector4f rotation;
|
||||
};
|
||||
|
||||
struct StoneGroup {
|
||||
// mesh.PositionData è ïðî÷èå áóäóò çàïîëíÿòüñÿ â inflate()
|
||||
VertexDataStruct mesh;
|
||||
|
||||
// Âíåøíèé âåêòîð — èíäåêñ òðåóãîëüíèêà ïëàíåòû,
|
||||
// âíóòðåííèé — ñïèñîê êàìíåé íà ýòîì òðåóãîëüíèêå
|
||||
std::vector<std::vector<StoneInstance>> allInstances;
|
||||
|
||||
// Î÷èùàåò ñòàðóþ ãåîìåòðèþ è ãåíåðèðóåò íîâóþ äëÿ óêàçàííûõ èíäåêñîâ
|
||||
void inflate(const std::vector<int>& triangleIndices);
|
||||
};
|
||||
|
||||
// Òåïåðü âîçâðàùàåò çàãîòîâêó ñî âñåìè ïàðàìåòðàìè, íî áåç òÿæåëîãî ìåøà
|
||||
StoneGroup CreateStoneGroupData(uint64_t globalSeed, const LodLevel& planetLodLevel);
|
||||
|
||||
} // namespace ZL
|
||||
|
||||
32
ZLMath.cpp
32
ZLMath.cpp
@ -189,6 +189,38 @@ namespace ZL {
|
||||
return r;
|
||||
}
|
||||
|
||||
Matrix4f MakeOrthoMatrix(float xmin, float xmax, float ymin, float ymax, float zNear, float zFar)
|
||||
{
|
||||
float width = xmax - xmin;
|
||||
float height = ymax - ymin;
|
||||
float depthRange = zFar - zNear;
|
||||
|
||||
if (width <= 0 || height <= 0 || depthRange <= 0)
|
||||
{
|
||||
throw std::runtime_error("Invalid dimensions for orthogonal matrix");
|
||||
}
|
||||
|
||||
Matrix4f r;
|
||||
|
||||
// Масштабирование
|
||||
r.m[0] = 2.f / width;
|
||||
r.m[5] = 2.f / height;
|
||||
r.m[10] = -1.f / depthRange;
|
||||
|
||||
// Обнуление неиспользуемых компонентов
|
||||
r.m[1] = r.m[2] = r.m[3] = 0;
|
||||
r.m[4] = r.m[6] = r.m[7] = 0;
|
||||
r.m[8] = r.m[9] = r.m[11] = 0;
|
||||
|
||||
// Трансляция (смещение)
|
||||
r.m[12] = -(xmax + xmin) / width;
|
||||
r.m[13] = -(ymax + ymin) / height;
|
||||
r.m[14] = zNear / depthRange;
|
||||
r.m[15] = 1.f;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
Matrix4f MakePerspectiveMatrix(float fovY, float aspectRatio, float zNear, float zFar)
|
||||
{
|
||||
float tanHalfFovy = tan(fovY / 2.f);
|
||||
|
||||
1
ZLMath.h
1
ZLMath.h
@ -153,6 +153,7 @@ namespace ZL {
|
||||
Matrix4f operator*(const Matrix4f& m1, const Matrix4f& m2);
|
||||
|
||||
Matrix4f MakeOrthoMatrix(float width, float height, float zNear, float zFar);
|
||||
Matrix4f MakeOrthoMatrix(float xmin, float xmax, float ymin, float ymax, float zNear, float zFar);
|
||||
|
||||
Matrix4f MakePerspectiveMatrix(float fovY, float aspectRatio, float zNear, float zFar);
|
||||
|
||||
|
||||
BIN
resources/rockx.png
(Stored with Git LFS)
Normal file
BIN
resources/rockx.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
resources/sandx.png
(Stored with Git LFS)
Normal file
BIN
resources/sandx.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -90,8 +90,8 @@ void main()
|
||||
// 4. Смешивание цвета с туманом
|
||||
|
||||
//vec3 mountainColor = vec3((length(pos+vec3(0.0,0.0,45000.0))-20000.0)/100.0, 0.5,0.0);
|
||||
gl_FragColor = mix(vec4(uColor* finalColor.rgb, 1.0), FOG_COLOR, fogFactor);
|
||||
//gl_FragColor = mix(vec4(uColor* finalColor.rgb, 1.0), FOG_COLOR, fogFactor);
|
||||
//gl_FragColor = vec4((length(pos+vec3(0.0,0.0,45000.0))-20000.0)/100.0, 0.0,0.0, 1.0);
|
||||
//gl_FragColor = vec4(fogFactor, 0.5,0.5, 1.0);
|
||||
//gl_FragColor = vec4(uColor*textureColor.rgb, 1.0);
|
||||
gl_FragColor = vec4(textureColor.rgb, 1.0);
|
||||
}
|
||||
18
shaders/defaultColor_fog_stones.vertex
Normal file
18
shaders/defaultColor_fog_stones.vertex
Normal file
@ -0,0 +1,18 @@
|
||||
// Вершинный шейдер (Vertex Shader)
|
||||
|
||||
attribute vec3 vPosition;
|
||||
attribute vec2 vTexCoord;
|
||||
|
||||
|
||||
varying vec2 TexCoord;
|
||||
|
||||
uniform mat4 ProjectionModelViewMatrix;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
gl_Position = ProjectionModelViewMatrix * vec4(vPosition.xyz, 1.0);
|
||||
|
||||
TexCoord = vTexCoord;
|
||||
}
|
||||
24
shaders/defaultColor_fog_stones_desktop.fragment
Normal file
24
shaders/defaultColor_fog_stones_desktop.fragment
Normal file
@ -0,0 +1,24 @@
|
||||
// Fragment Shader
|
||||
varying vec2 TexCoord;
|
||||
uniform sampler2D Texture; // sandTexture
|
||||
uniform sampler2D StoneMap; // Наша запеченная текстура
|
||||
uniform float testShift1;
|
||||
uniform float testShift2;
|
||||
void main()
|
||||
{
|
||||
vec2 newTexCoord;
|
||||
newTexCoord.x = TexCoord.x;
|
||||
//newTexCoord.y = 1.0 - TexCoord.y - 0.0122;
|
||||
//newTexCoord.y = TexCoord.y * (1.0+testShift) + 0.0122;
|
||||
//newTexCoord.y = (TexCoord.y + 0.0122)*(1.0 +x/500.0);
|
||||
newTexCoord.y = TexCoord.y * (1.0-6.0/500.0) + 0.0122+ (11.0/500.0) *0.1 -6/5000.0;
|
||||
//newTexCoord.y = TexCoord.y;
|
||||
vec4 sandColor = texture2D(Texture, TexCoord);
|
||||
vec4 stoneData = texture2D(StoneMap, newTexCoord);
|
||||
|
||||
//vec3 finalColor = sandColor.rgb*0.5 + stoneData.rgb*0.5;
|
||||
vec3 finalColor = stoneData.rgb;
|
||||
//vec3 finalColor = sandColor.rgb;
|
||||
|
||||
gl_FragColor = vec4(finalColor, 1.0);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user