Working on multi-threading, including web
This commit is contained in:
1 parent
b055faf882
commit
648acf8938
12 files changed
+230
-45
No files matched your search
+88
-16
@@ -4,7 +4,7 @@
|
||||
#include "render/OpenGlExtensions.h"
|
||||
#include "Environment.h"
|
||||
#include "StoneObject.h"
|
||||
|
||||
#include "utils/TaskManager.h"
|
||||
|
||||
namespace ZL {
|
||||
|
||||
@@ -77,20 +77,18 @@ namespace ZL {
|
||||
sandTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/sand2.png", CONST_ZIP_FILE));
|
||||
stoneTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/rock.png", CONST_ZIP_FILE));
|
||||
|
||||
|
||||
//#ifndef SIMPLIFIED
|
||||
// Атмосфера
|
||||
planetAtmosphereRenderStruct.data = planetData.getAtmosphereLod().vertexData;
|
||||
if (planetAtmosphereRenderStruct.data.PositionData.size() > 0)
|
||||
{
|
||||
planetAtmosphereRenderStruct.RefreshVBO();
|
||||
}
|
||||
//#endif
|
||||
|
||||
|
||||
planetStones = CreateStoneGroupData(778, planetData.getLodLevel(lodIndex));
|
||||
|
||||
stonesToRender = planetStones.inflate(planetStones.allInstances.size());
|
||||
//stonesToRender = planetStones.inflate(planetStones.allInstances.size());
|
||||
stonesToRender.resize(planetStones.allInstances.size());
|
||||
planetStones.initStatuses();
|
||||
|
||||
stoneToBake = planetStones.inflateOne(0, 0.75);
|
||||
}
|
||||
@@ -98,6 +96,75 @@ namespace ZL {
|
||||
|
||||
void PlanetObject::update(float deltaTimeMs) {
|
||||
|
||||
// 1. Проверка порога движения (оптимизация из текущего кода)
|
||||
float movementThreshold = 1.0f;
|
||||
if ((Environment::shipPosition - lastUpdatePos).squaredNorm() < movementThreshold * movementThreshold
|
||||
&& !triangleIndicesToDraw.empty()) {
|
||||
processMainThreadTasks(); // Все равно обрабатываем очередь OpenGL задач
|
||||
return;
|
||||
}
|
||||
lastUpdatePos = Environment::shipPosition;
|
||||
|
||||
// 2. Получаем список видимых треугольников
|
||||
auto newIndices = planetData.getTrianglesUnderCameraNew2(Environment::shipPosition);
|
||||
std::sort(newIndices.begin(), newIndices.end());
|
||||
|
||||
// 3. Анализируем, что нужно загрузить
|
||||
for (int triIdx : newIndices) {
|
||||
if (planetStones.statuses[triIdx] == ChunkStatus::Empty) {
|
||||
// Помечаем, чтобы не спамить задачами
|
||||
planetStones.statuses[triIdx] = ChunkStatus::Generating;
|
||||
|
||||
// Отправляем тяжелую математику в TaskManager
|
||||
taskManager->EnqueueBackgroundTask([this, triIdx]() {
|
||||
// Выполняется в фоновом потоке: только генерация геометрии в RAM
|
||||
float scaleModifier = 1.0f;
|
||||
VertexDataStruct generatedData = planetStones.inflateOneDataOnly(triIdx, scaleModifier);
|
||||
|
||||
// Передаем задачу на загрузку в GPU в очередь главного потока
|
||||
this->EnqueueMainThreadTask([this, triIdx, data = std::move(generatedData)]() mutable {
|
||||
// Проверяем актуальность: если треугольник всё еще в списке видимых
|
||||
auto it = std::find(triangleIndicesToDraw.begin(), triangleIndicesToDraw.end(), triIdx);
|
||||
if (it != triangleIndicesToDraw.end()) {
|
||||
stonesToRender[triIdx].data = std::move(data);
|
||||
stonesToRender[triIdx].RefreshVBO(); // OpenGL вызов
|
||||
planetStones.statuses[triIdx] = ChunkStatus::Live;
|
||||
}
|
||||
else {
|
||||
// Если уже не нужен — просто сбрасываем статус
|
||||
planetStones.statuses[triIdx] = ChunkStatus::Empty;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Очистка (Unload)
|
||||
// Если статус Live, но треугольника нет в новых индексах — освобождаем GPU память
|
||||
for (size_t i = 0; i < planetStones.statuses.size(); ++i) {
|
||||
if (planetStones.statuses[i] == ChunkStatus::Live) {
|
||||
bool isVisible = std::binary_search(newIndices.begin(), newIndices.end(), (int)i);
|
||||
if (!isVisible) {
|
||||
// Очищаем данные и VBO (деструкторы shared_ptr в VertexRenderStruct сделают glDeleteBuffers)
|
||||
stonesToRender[i].data.PositionData.clear();
|
||||
stonesToRender[i].vao.reset();
|
||||
stonesToRender[i].positionVBO.reset();
|
||||
stonesToRender[i].normalVBO.reset();
|
||||
stonesToRender[i].tangentVBO.reset();
|
||||
stonesToRender[i].binormalVBO.reset();
|
||||
stonesToRender[i].colorVBO.reset();
|
||||
stonesToRender[i].texCoordVBO.reset();
|
||||
|
||||
planetStones.statuses[i] = ChunkStatus::Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
triangleIndicesToDraw = std::move(newIndices);
|
||||
|
||||
// 5. Выполняем одну задачу из очереди OpenGL (RefreshVBO и т.д.)
|
||||
processMainThreadTasks();
|
||||
/*
|
||||
float movementThreshold = 1.0f;
|
||||
if ((Environment::shipPosition - lastUpdatePos).squaredNorm() < movementThreshold * movementThreshold && !triangleIndicesToDraw.empty()) {
|
||||
return;
|
||||
@@ -111,7 +178,7 @@ namespace ZL {
|
||||
|
||||
if (newIndices != triangleIndicesToDraw) {
|
||||
triangleIndicesToDraw = std::move(newIndices);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
@@ -205,7 +272,6 @@ namespace ZL {
|
||||
|
||||
void PlanetObject::draw(Renderer& renderer) {
|
||||
|
||||
//#ifndef SIMPLIFIED
|
||||
{
|
||||
if (stoneMapFB == nullptr)
|
||||
{
|
||||
@@ -221,10 +287,6 @@ namespace ZL {
|
||||
stoneMapFB->GenerateMipmaps();
|
||||
|
||||
}
|
||||
//#endif
|
||||
|
||||
|
||||
//bakeStoneTexture(renderer);
|
||||
|
||||
glViewport(0, 0, Environment::width, Environment::height);
|
||||
//--------------------------
|
||||
@@ -232,10 +294,7 @@ namespace ZL {
|
||||
|
||||
drawPlanet(renderer);
|
||||
drawStones(renderer);
|
||||
|
||||
//#ifndef SIMPLIFIED
|
||||
drawAtmosphere(renderer);
|
||||
//#endif
|
||||
}
|
||||
|
||||
void PlanetObject::drawPlanet(Renderer& renderer)
|
||||
@@ -382,7 +441,7 @@ namespace ZL {
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBindTexture(GL_TEXTURE_2D, stoneTexture->getTexID());
|
||||
|
||||
|
||||
/*
|
||||
for (int i : triangleIndicesToDraw)
|
||||
//for (int i = 0; i < stonesToRender.size(); i++)
|
||||
{
|
||||
@@ -390,7 +449,20 @@ namespace ZL {
|
||||
{
|
||||
renderer.DrawVertexRenderStruct(stonesToRender[i]);
|
||||
}
|
||||
}*/
|
||||
for (int i : triangleIndicesToDraw) {
|
||||
// КРИТИЧЕСКОЕ ИЗМЕНЕНИЕ:
|
||||
// Проверяем, что данные не просто существуют, а загружены в GPU
|
||||
if (planetStones.statuses[i] == ChunkStatus::Live) {
|
||||
// Дополнительная проверка на наличие данных (на всякий случай)
|
||||
if (stonesToRender[i].data.PositionData.size() > 0) {
|
||||
renderer.DrawVertexRenderStruct(stonesToRender[i]);
|
||||
}
|
||||
}
|
||||
// Если статус Generating или Empty — мы просто пропускаем этот индекс.
|
||||
// Камни появятся на экране плавно, как только отработает TaskManager и RefreshVBO.
|
||||
}
|
||||
|
||||
CheckGlError();
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
Reference in new issue
Block a user