diff --git a/resources/config/spark_config.json b/resources/config/spark_config.json index 2329820..2a46f11 100644 --- a/resources/config/spark_config.json +++ b/resources/config/spark_config.json @@ -1,5 +1,5 @@ { - "emissionRate": 0.4, + "emissionRate": 1.2, "maxParticles": 400, "particleSize": 0.3, "biasX": 0.3, diff --git a/resources/config/spark_config_cargo.json b/resources/config/spark_config_cargo.json index 36816c7..c853da0 100644 --- a/resources/config/spark_config_cargo.json +++ b/resources/config/spark_config_cargo.json @@ -1,5 +1,5 @@ { - "emissionRate": 0.4, + "emissionRate": 1.2, "maxParticles": 400, "particleSize": 0.3, "biasX": 0.3, diff --git a/src/Game.cpp b/src/Game.cpp index c55e31a..6936e59 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -41,6 +41,10 @@ namespace ZL const char* CONST_ZIP_FILE = ""; #endif + float x = 0; + float y = 0; + float z = 0; + #ifdef EMSCRIPTEN Game* Game::s_instance = nullptr; @@ -420,22 +424,6 @@ namespace ZL handleMotion(ZL::UiManager::MOUSE_FINGER_ID, mx, my); } - /*if (event.type == SDL_MOUSEBUTTONDOWN) { - int mx = event.button.x; - int my = event.button.y; - handleDown(mx, my); - } - if (event.type == SDL_MOUSEBUTTONUP) { - int mx = event.button.x; - int my = event.button.y; - handleUp(mx, my); - } - if (event.type == SDL_MOUSEMOTION) { - int mx = event.motion.x; - int my = event.motion.y; - handleMotion(mx, my); - }*/ - if (event.type == SDL_MOUSEWHEEL) { static const float zoomstep = 2.0f; if (event.wheel.y > 0) { @@ -465,7 +453,25 @@ namespace ZL if (event.type == SDL_KEYUP) { if (event.key.keysym.sym == SDLK_a) { - //Environment::shipState.position = { 9466.15820, 1046.00159, 18531.2090 }; + x = x + 0.2f; + } + if (event.key.keysym.sym == SDLK_q) { + x = x - 0.2f; + } + if (event.key.keysym.sym == SDLK_s) { + y = y + 0.2f; + } + if (event.key.keysym.sym == SDLK_w) { + y = y - 0.2f; + } + if (event.key.keysym.sym == SDLK_d) { + z = z + 0.2f; + } + if (event.key.keysym.sym == SDLK_e) { + z = z - 0.2f; + } + if (event.key.keysym.sym == SDLK_r) { + std::cout << "Camera position: x=" << x << " y=" << y << " z=" << z << std::endl; } } #endif diff --git a/src/Space.cpp b/src/Space.cpp index c3f3b67..c7cfc3d 100644 --- a/src/Space.cpp +++ b/src/Space.cpp @@ -33,6 +33,8 @@ namespace ZL extern const char* CONST_ZIP_FILE; extern float x; + extern float y; + extern float z; Eigen::Quaternionf generateRandomQuaternion(std::mt19937& gen) { @@ -507,17 +509,7 @@ namespace ZL } - renderer.PushMatrix(); - renderer.RotateMatrix(Environment::inverseShipMatrix); - renderer.TranslateMatrix(- /*0.5 * */ Environment::shipState.position); - std::cout << "Ship pos draw: " << Environment::shipState.position.transpose() << "\n"; - if (Environment::shipState.shipType == 1) { - sparkEmitterCargo.draw(renderer, Environment::zoom, Environment::width, Environment::height); - } - else { - sparkEmitter.draw(renderer, Environment::zoom, Environment::width, Environment::height); - } - renderer.PopMatrix(); + drawShipSparkEmitters(); } renderer.PopMatrix(); @@ -591,16 +583,7 @@ namespace ZL glViewport(0, 0, Environment::width, Environment::height); - // Готовим данные всех эмиттеров (CPU + VBO upload) до начала отрисовки, - // чтобы draw() делал только GPU-вызовы без пауз между кораблём и частицами. - sparkEmitter.prepareForDraw(true); - sparkEmitterCargo.prepareForDraw(true); - explosionEmitter.prepareForDraw(false); - for (const auto& p : projectiles) { - if (p && p->isActive()) { - p->projectileEmitter.prepareForDraw(true); - } - } + prepareSparkEmittersForDraw(); CheckGlError(); @@ -1431,6 +1414,89 @@ namespace ZL targetWasVisible = false; } + void Space::updateSparkEmitters(float deltaMs) + { + // Local ship + SparkEmitter* sparkEmitterPtr; + if (Environment::shipState.shipType == 1) { + sparkEmitterPtr = &sparkEmitterCargo; + static std::vector emissionPoints = { Vector3f(0, 0, 0), Vector3f(0, 0, 0) }; + emissionPoints[0] = Environment::shipState.position + Environment::shipState.rotation * Vector3f{ 0.0, 2.8, -6.5 + 16.0 }; + emissionPoints[1] = Environment::shipState.position + Environment::shipState.rotation * Vector3f{ 0.0, 1.5, -6.5 + 16.0 }; + sparkEmitterPtr->setEmissionPoints(emissionPoints); + } + else { + sparkEmitterPtr = &sparkEmitter; + static std::vector emissionPoints = { Vector3f(0, 0, 0), Vector3f(0, 0, 0) }; + emissionPoints[0] = Environment::shipState.position + Environment::shipState.rotation * Vector3f{ -0.9, 1.4 - 1.0, -8.5 + 16.0 }; + emissionPoints[1] = Environment::shipState.position + Environment::shipState.rotation * Vector3f{ 0.9, 1.4 - 1.0, -8.5 + 16.0 }; + sparkEmitterPtr->setEmissionPoints(emissionPoints); + } + sparkEmitterPtr->setIsActive(Environment::shipState.velocity > 0.1f); + sparkEmitterPtr->update(deltaMs); + + // Remote ships + for (auto const& [id, playerState] : remotePlayerStates) { + if (deadRemotePlayers.count(id)) continue; + if (!remoteShipSparkEmitters.count(id)) { + remoteShipSparkEmitters.emplace(id, playerState.shipType == 1 ? sparkEmitterCargo : sparkEmitter); + } + auto& remEmitter = remoteShipSparkEmitters.at(id); + std::vector remEmitPts(2); + if (playerState.shipType == 1) { + remEmitPts[0] = playerState.position + playerState.rotation * Vector3f{ 0.0f, -0.4f+2.8f, 8.4f }; + remEmitPts[1] = playerState.position + playerState.rotation * Vector3f{ 0.0f, -0.4f+1.5f, 8.4f }; + } else { + remEmitPts[0] = playerState.position + playerState.rotation * Vector3f{ -0.9f, -0.2,5.6 }; + remEmitPts[1] = playerState.position + playerState.rotation * Vector3f{ 0.9f,-0.2,5.6 }; + } + remEmitter.setEmissionPoints(remEmitPts); + remEmitter.setIsActive(playerState.velocity > 0.1f); + remEmitter.update(deltaMs); + } + } + + void Space::prepareSparkEmittersForDraw() + { + sparkEmitter.prepareForDraw(true); + sparkEmitterCargo.prepareForDraw(true); + for (auto& [id, emitter] : remoteShipSparkEmitters) { + if (!deadRemotePlayers.count(id)) emitter.prepareForDraw(true); + } + explosionEmitter.prepareForDraw(false); + for (const auto& p : projectiles) { + if (p && p->isActive()) { + p->projectileEmitter.prepareForDraw(true); + } + } + } + + void Space::drawShipSparkEmitters() + { + renderer.PushMatrix(); + renderer.RotateMatrix(Environment::inverseShipMatrix); + renderer.TranslateMatrix(-Environment::shipState.position); + if (Environment::shipState.shipType == 1) { + sparkEmitterCargo.draw(renderer, Environment::zoom, Environment::width, Environment::height); + } else { + sparkEmitter.draw(renderer, Environment::zoom, Environment::width, Environment::height); + } + + for (auto& [id, emitter] : remoteShipSparkEmitters) { + if (!deadRemotePlayers.count(id)) { + + renderer.PushMatrix(); + renderer.LoadIdentity(); + renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom }); + renderer.RotateMatrix(Environment::inverseShipMatrix); + renderer.TranslateMatrix(-Environment::shipState.position); + emitter.draw(renderer, Environment::zoom, Environment::width, Environment::height); + renderer.PopMatrix(); + } + } + renderer.PopMatrix(); + } + void Space::processTickCount(int64_t newTickCount, int64_t delta) { auto now_ms = newTickCount; @@ -1522,7 +1588,7 @@ namespace ZL std::string msg = "UPD:" + std::to_string(now_ms) + ":" + Environment::shipState.formPingMessageContent(); networkClient->Send(msg); - std::cout << "Sending: " << msg << std::endl; + //std::cout << "Sending: " << msg << std::endl; } long long leftoverDelta = delta; @@ -1545,41 +1611,6 @@ namespace ZL } - //-------------- - - SparkEmitter* sparkEmitterPtr; - - if (Environment::shipState.shipType == 1) { - sparkEmitterPtr = &sparkEmitterCargo; - static std::vector emissionPoints = { Vector3f(0, 0, 0), Vector3f(0, 0, 0) }; - emissionPoints[0] = Environment::shipState.position + Environment::shipState.rotation * Vector3f{ 0.0, 2.8, -6.5 + 16.0 }; - emissionPoints[1] = Environment::shipState.position + Environment::shipState.rotation * Vector3f{ 0.0, 1.5, -6.5 + 16.0 }; - sparkEmitterPtr->setEmissionPoints(emissionPoints); - } - else - { - sparkEmitterPtr = &sparkEmitter; - static std::vector emissionPoints = { Vector3f(0, 0, 0), Vector3f(0, 0, 0) }; - emissionPoints[0] = Environment::shipState.position + Environment::shipState.rotation * Vector3f{ -0.9, 1.4 - 1.0, -8.5 + 16.0 }; - emissionPoints[1] = Environment::shipState.position + Environment::shipState.rotation * Vector3f{ 0.9, 1.4 - 1.0, -8.5 + 16.0 }; - sparkEmitterPtr->setEmissionPoints(emissionPoints); - //sparkEmitterPtr->setEmissionPoints({ /*0.5* */Environment::shipState.position }); - //sparkEmitterPtr->setEmissionPoints({ Vector3f(0, 0, 0) }); - std::cout << "Ship pos empo: " << Environment::shipState.position.transpose() << "\n"; - } - - if (Environment::shipState.velocity > 0.1f) - { - sparkEmitterPtr->setIsActive(true); - } - else - { - sparkEmitterPtr->setIsActive(false); - } - - sparkEmitterPtr->update(static_cast(delta)); - - auto latestRemotePlayers = networkClient->getRemotePlayers(); std::chrono::system_clock::time_point nowRoundedWithDelay{ std::chrono::milliseconds(newTickCount - CLIENT_DELAY) }; @@ -1601,6 +1632,8 @@ namespace ZL remotePlayerStates[id] = playerState; } + updateSparkEmitters(static_cast(delta)); + for (auto& p : projectiles) { if (p && p->isActive()) { p->update(static_cast(delta), renderer); @@ -1875,6 +1908,7 @@ namespace ZL for (int pid : disconnects) { remotePlayerStates.erase(pid); deadRemotePlayers.erase(pid); + remoteShipSparkEmitters.erase(pid); if (trackedTargetId == pid) { trackedTargetId = -1; targetAcquireAnim = 0.f; diff --git a/src/Space.h b/src/Space.h index ee7ae12..05395a3 100644 --- a/src/Space.h +++ b/src/Space.h @@ -66,6 +66,7 @@ namespace ZL { std::unique_ptr textRenderer; std::unordered_map remotePlayerStates; + std::unordered_map remoteShipSparkEmitters; float newShipVelocity = 0; @@ -144,6 +145,10 @@ namespace ZL { void resetPlayerState(); void clearTextRendererCache(); + void updateSparkEmitters(float deltaMs); + void prepareSparkEmittersForDraw(); + void drawShipSparkEmitters(); + // Crosshair HUD struct CrosshairConfig { bool enabled = true; diff --git a/src/SparkEmitter.cpp b/src/SparkEmitter.cpp index 1115abf..4baa1dc 100644 --- a/src/SparkEmitter.cpp +++ b/src/SparkEmitter.cpp @@ -26,12 +26,12 @@ namespace ZL { sparkQuad.data = VertexDataStruct(); } - SparkEmitter::SparkEmitter(const SparkEmitter& copyFrom) + SparkEmitter::SparkEmitter(const SparkEmitter& copyFrom) : particles(copyFrom.particles), emissionPoints(copyFrom.emissionPoints), lastEmissionTime(copyFrom.lastEmissionTime), emissionRate(copyFrom.emissionRate), isActive(copyFrom.isActive), drawPositions(copyFrom.drawPositions), - drawTexCoords(copyFrom.drawTexCoords), drawDataDirty(copyFrom.drawDataDirty), - sparkQuad(copyFrom.sparkQuad), texture(copyFrom.texture), + drawTexCoords(copyFrom.drawTexCoords), drawDataDirty(true), + texture(copyFrom.texture), maxParticles(copyFrom.maxParticles), particleSize(copyFrom.particleSize), biasX(copyFrom.biasX), speedRange(copyFrom.speedRange), zSpeedRange(copyFrom.zSpeedRange), @@ -40,6 +40,8 @@ namespace ZL { shaderProgramName(copyFrom.shaderProgramName), configured(copyFrom.configured), useWorldSpace(copyFrom.useWorldSpace) { + // Each copy gets its own GPU buffers; only copy CPU-side data + sparkQuad.data = copyFrom.sparkQuad.data; } @@ -198,16 +200,10 @@ namespace ZL { throw std::runtime_error("Failed to load spark emitter config file 2!"); } - //prepareDrawData(withRotation); - if (drawPositions.empty()) { return; } - /* - sparkQuad.data.PositionData = drawPositions; - sparkQuad.data.TexCoordData = drawTexCoords; - sparkQuad.RefreshVBO(); - */ + renderer.shaderManager.PushShader(shaderProgramName); renderer.RenderUniform1i(textureUniformName, 0); renderer.SetMatrix(); diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 003e71d..f50aec0 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -617,6 +617,7 @@ namespace ZL { { throw std::runtime_error("Modelview matrix stack overflow!!!!"); } + SetMatrix(); } void Renderer::LoadIdentity() @@ -922,8 +923,6 @@ namespace ZL { glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.positionVBO->getBuffer()); VertexAttribPointer3fv(vPosition, 0, NULL); - //EnableVertexAttribArray(vPosition); - glDrawArrays(GL_TRIANGLES, 0, static_cast(VertexRenderStruct.data.PositionData.size())); }