629 lines
24 KiB
C++
629 lines
24 KiB
C++
#include "PlanetObject.h"
|
||
#include <random>
|
||
#include <cmath>
|
||
#include "OpenGlExtensions.h"
|
||
#include "Environment.h"
|
||
#include "StoneObject.h"
|
||
|
||
namespace ZL {
|
||
|
||
|
||
PlanetObject::PlanetObject()
|
||
{
|
||
|
||
}
|
||
|
||
void PlanetObject::init() {
|
||
// 1. Инициализируем данные (генерация мешей)
|
||
planetData.init();
|
||
|
||
// 2. Забираем данные для VBO
|
||
// Берем максимальный LOD для начальной отрисовки
|
||
int lodIndex = planetData.getMaxLodIndex();
|
||
planetRenderStruct.data = planetData.getLodLevel(lodIndex).vertexData;
|
||
planetRenderStruct.RefreshVBO();
|
||
|
||
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() {
|
||
if (!drawDataDirty) return;
|
||
drawDataDirty = false;
|
||
}
|
||
|
||
void PlanetObject::update(float deltaTimeMs) {
|
||
// 1. Получаем базовые треугольники под камерой
|
||
auto lr = planetData.getTrianglesUnderCamera(Environment::shipPosition);
|
||
int currentLod = planetData.getCurrentLodIndex();
|
||
|
||
// Временный вектор для сбора новых индексов
|
||
std::vector<int> newIndices;
|
||
std::set<int> used;
|
||
|
||
// Рекурсивно (или итеративно, как у тебя) собираем индексы видимых зон
|
||
for (int i : lr) {
|
||
if (used.insert(i).second) newIndices.push_back(i);
|
||
|
||
auto neighbors = planetData.findNeighbors(i, currentLod);
|
||
for (int n : neighbors) {
|
||
if (used.insert(n).second) newIndices.push_back(n);
|
||
|
||
auto neighbors2 = planetData.findNeighbors(n, currentLod);
|
||
for (int n2 : neighbors2) {
|
||
if (used.insert(n2).second) newIndices.push_back(n2);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 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 для четкости)
|
||
|
||
|
||
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);
|
||
|
||
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";
|
||
|
||
renderer.EnableVertexAttribArray(vPositionName);
|
||
renderer.EnableVertexAttribArray(vColorName);
|
||
renderer.EnableVertexAttribArray(vNormalName);
|
||
renderer.EnableVertexAttribArray(vTexCoordName);
|
||
|
||
// 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";
|
||
static const std::string vNormalName = "vNormal";
|
||
static const std::string vTexCoordName = "vTexCoord";
|
||
//static const std::string vTexCoord3Name = "vTexCoord3";
|
||
static const std::string textureUniformName = "Texture";
|
||
|
||
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);
|
||
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,
|
||
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),
|
||
currentZNear, currentZFar);
|
||
|
||
renderer.PushMatrix();
|
||
renderer.LoadIdentity();
|
||
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
|
||
renderer.RotateMatrix(Environment::inverseShipMatrix);
|
||
renderer.TranslateMatrix(-Environment::shipPosition);
|
||
|
||
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);
|
||
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();
|
||
|
||
|
||
renderer.PopMatrix();
|
||
renderer.PopProjectionMatrix();
|
||
//renderer.DisableVertexAttribArray(vTexCoord3Name);
|
||
renderer.DisableVertexAttribArray(vTexCoord2Name);
|
||
renderer.DisableVertexAttribArray(vTexCoordName);
|
||
renderer.DisableVertexAttribArray(vNormalName);
|
||
renderer.DisableVertexAttribArray(vColorName);
|
||
renderer.DisableVertexAttribArray(vPositionName);
|
||
renderer.shaderManager.PopShader();
|
||
CheckGlError();
|
||
|
||
|
||
}
|
||
|
||
void PlanetObject::drawStones(Renderer& renderer)
|
||
{
|
||
//static const std::string defaultShaderName = "defaultColor";
|
||
static const std::string defaultShaderName2 = "defaultColor2";
|
||
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";
|
||
|
||
renderer.shaderManager.PushShader(defaultShaderName2);
|
||
renderer.RenderUniform1i(textureUniformName, 0);
|
||
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),
|
||
currentZNear, currentZFar);
|
||
|
||
renderer.PushMatrix();
|
||
renderer.LoadIdentity();
|
||
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
|
||
renderer.RotateMatrix(Environment::inverseShipMatrix);
|
||
renderer.TranslateMatrix(-Environment::shipPosition);
|
||
|
||
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);// Аддитивное смешивание для эффекта свечения
|
||
|
||
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();
|
||
|
||
glClear(GL_DEPTH_BUFFER_BIT);
|
||
}
|
||
|
||
void PlanetObject::drawYellowZone(Renderer& renderer)
|
||
{
|
||
|
||
static const std::string defaultShaderName = "defaultColor";
|
||
static const std::string defaultShaderName2 = "defaultColor2";
|
||
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";
|
||
|
||
float dist = planetData.distanceToPlanetSurface(Environment::shipPosition);
|
||
auto zRange = planetData.calculateZRange(dist);
|
||
const float currentZNear = zRange.first;
|
||
const float currentZFar = zRange.second;
|
||
|
||
|
||
glClear(GL_DEPTH_BUFFER_BIT);
|
||
if (planetRenderYellowStruct.data.PositionData.size() > 0)
|
||
{
|
||
|
||
renderer.shaderManager.PushShader(defaultShaderName2);
|
||
renderer.RenderUniform1i(textureUniformName, 0);
|
||
renderer.EnableVertexAttribArray(vPositionName);
|
||
renderer.EnableVertexAttribArray(vTexCoordName);
|
||
|
||
|
||
// 2. Применяем динамическую матрицу проекции
|
||
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
|
||
static_cast<float>(Environment::width) / static_cast<float>(Environment::height),
|
||
currentZNear, currentZFar);
|
||
|
||
renderer.PushMatrix();
|
||
renderer.LoadIdentity();
|
||
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
|
||
renderer.RotateMatrix(Environment::inverseShipMatrix);
|
||
|
||
renderer.TranslateMatrix(-Environment::shipPosition);
|
||
|
||
|
||
|
||
renderer.RenderUniform1f("uDistanceToPlanetSurface", dist);
|
||
renderer.RenderUniform1f("uCurrentZFar", currentZFar);
|
||
|
||
Vector3f color2 = { 1.0, 1.0, 0.0 };
|
||
|
||
glBindTexture(GL_TEXTURE_2D, sandTexture->getTexID());
|
||
|
||
renderer.RenderUniform3fv("uColor", &color2.v[0]);
|
||
renderer.DrawVertexRenderStruct(planetRenderYellowStruct);
|
||
//glDisable(GL_BLEND);
|
||
CheckGlError();
|
||
|
||
|
||
renderer.PopMatrix();
|
||
renderer.PopProjectionMatrix();
|
||
renderer.DisableVertexAttribArray(vTexCoordName);
|
||
|
||
renderer.DisableVertexAttribArray(vPositionName);
|
||
renderer.shaderManager.PopShader();
|
||
CheckGlError();
|
||
|
||
}
|
||
}
|
||
|
||
void PlanetObject::drawAtmosphere(Renderer& renderer) {
|
||
static const std::string defaultShaderName = "defaultAtmosphere";
|
||
static const std::string vPositionName = "vPosition";
|
||
static const std::string vNormalName = "vNormal";
|
||
//glClear(GL_DEPTH_BUFFER_BIT);
|
||
glDepthMask(GL_FALSE);
|
||
|
||
renderer.shaderManager.PushShader(defaultShaderName);
|
||
renderer.EnableVertexAttribArray(vPositionName);
|
||
renderer.EnableVertexAttribArray(vNormalName);
|
||
|
||
|
||
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),
|
||
currentZNear, currentZFar);
|
||
|
||
renderer.PushMatrix();
|
||
renderer.LoadIdentity();
|
||
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
|
||
renderer.RotateMatrix(Environment::inverseShipMatrix);
|
||
renderer.TranslateMatrix(-Environment::shipPosition);
|
||
|
||
const Matrix4f viewMatrix = renderer.GetCurrentModelViewMatrix();
|
||
|
||
Vector3f color = { 0.0, 0.5, 1.0 };
|
||
|
||
renderer.RenderUniform3fv("uColor", &color.v[0]);
|
||
|
||
renderer.RenderUniformMatrix4fv("ModelViewMatrix", false, &viewMatrix.m[0]);
|
||
|
||
renderer.RenderUniform1f("uDistanceToPlanetSurface", dist);
|
||
|
||
glEnable(GL_BLEND);
|
||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);// Аддитивное смешивание для эффекта свечения
|
||
|
||
renderer.DrawVertexRenderStruct(planetAtmosphereRenderStruct);
|
||
glDisable(GL_BLEND);
|
||
glDepthMask(GL_TRUE);
|
||
renderer.PopMatrix();
|
||
renderer.PopProjectionMatrix();
|
||
|
||
renderer.DisableVertexAttribArray(vNormalName);
|
||
renderer.DisableVertexAttribArray(vPositionName);
|
||
renderer.shaderManager.PopShader();
|
||
CheckGlError();
|
||
|
||
}
|
||
|
||
float PlanetObject::distanceToPlanetSurface(const Vector3f& viewerPosition)
|
||
{
|
||
return planetData.distanceToPlanetSurface(viewerPosition);
|
||
}
|
||
|
||
|
||
|
||
} // namespace ZL
|