Fixing particles
This commit is contained in:
parent
9da3cc4401
commit
59b5bea540
@ -5,7 +5,7 @@
|
||||
"texture": "resources/spark_white.png",
|
||||
"speedRange": [10.0, 30.0],
|
||||
"zSpeedRange": [-1.0, 1.0],
|
||||
"scaleRange": [0.5, 1.0],
|
||||
"scaleRange": [5.0, 10.0],
|
||||
"lifeTimeRange": [200.0, 800.0],
|
||||
"emissionRate": 50.0,
|
||||
"maxParticles": 5,
|
||||
|
||||
@ -1,20 +1,14 @@
|
||||
{
|
||||
"emissionRate": 100,
|
||||
"maxParticles": 200,
|
||||
"emissionRate": 0.4,
|
||||
"maxParticles": 400,
|
||||
"particleSize": 0.3,
|
||||
"biasX": 0.3,
|
||||
"emissionPoints": [
|
||||
{
|
||||
"position": [-1.0, 1.4, -3.5]
|
||||
},
|
||||
{
|
||||
"position": [1.0, 1.4, -3.5]
|
||||
}
|
||||
],
|
||||
"speedRange": [0.5, 2.0],
|
||||
"zSpeedRange": [1.0, 3.0],
|
||||
"scaleRange": [0.8, 1.2],
|
||||
"lifeTimeRange": [600.0, 1400.0],
|
||||
"lifeTimeRange": [300.0, 500.0],
|
||||
"texture": "resources/spark.png",
|
||||
"shaderProgramName": "spark"
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"emissionRate": 10.0,
|
||||
"maxParticles": 200,
|
||||
"emissionRate": 0.4,
|
||||
"maxParticles": 400,
|
||||
"particleSize": 0.3,
|
||||
"biasX": 0.3,
|
||||
"emissionPoints": [
|
||||
|
||||
@ -334,8 +334,10 @@ namespace ZL
|
||||
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
//processTickCount();
|
||||
drawScene();
|
||||
processTickCount();
|
||||
//std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
|
||||
SDL_GL_SwapWindow(ZL::Environment::window);
|
||||
}
|
||||
@ -390,19 +392,16 @@ namespace ZL
|
||||
int mx = static_cast<int>(event.tfinger.x * Environment::projectionWidth);
|
||||
int my = static_cast<int>(event.tfinger.y * Environment::projectionHeight);
|
||||
handleDown(static_cast<int64_t>(event.tfinger.fingerId), mx, my);
|
||||
//std::cout << "Finger down: id=" << event.tfinger.fingerId << " x=" << mx << " y=" << my << std::endl;
|
||||
}
|
||||
else if (event.type == SDL_FINGERUP) {
|
||||
int mx = static_cast<int>(event.tfinger.x * Environment::projectionWidth);
|
||||
int my = static_cast<int>(event.tfinger.y * Environment::projectionHeight);
|
||||
handleUp(static_cast<int64_t>(event.tfinger.fingerId), mx, my);
|
||||
//std::cout << "Finger up: id=" << event.tfinger.fingerId << " x=" << mx << " y=" << my << std::endl;
|
||||
}
|
||||
else if (event.type == SDL_FINGERMOTION) {
|
||||
int mx = static_cast<int>(event.tfinger.x * Environment::projectionWidth);
|
||||
int my = static_cast<int>(event.tfinger.y * Environment::projectionHeight);
|
||||
handleMotion(static_cast<int64_t>(event.tfinger.fingerId), mx, my);
|
||||
//std::cout << "Finger motion: id=" << event.tfinger.fingerId << " x=" << mx << " y=" << my << std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -506,9 +506,11 @@ namespace ZL
|
||||
renderer.DrawVertexRenderStruct(spaceship);
|
||||
}
|
||||
|
||||
|
||||
renderer.PushMatrix();
|
||||
renderer.RotateMatrix(Environment::inverseShipMatrix);
|
||||
renderer.TranslateMatrix(-Environment::shipState.position);
|
||||
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);
|
||||
}
|
||||
@ -541,21 +543,6 @@ namespace ZL
|
||||
|
||||
renderer.shaderManager.PopShader();
|
||||
|
||||
/*
|
||||
if (shipAlive) {
|
||||
renderer.PushMatrix();
|
||||
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
|
||||
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);
|
||||
}
|
||||
renderer.PopMatrix();
|
||||
}*/
|
||||
|
||||
if (showExplosion) {
|
||||
explosionEmitter.draw(renderer, Environment::zoom, Environment::width, Environment::height, false);
|
||||
}
|
||||
@ -604,6 +591,17 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
CheckGlError();
|
||||
|
||||
float skyPercent = 0.0;
|
||||
@ -1437,35 +1435,6 @@ namespace ZL
|
||||
|
||||
auto now_ms = newTickCount;
|
||||
|
||||
SparkEmitter* sparkEmitterPtr;
|
||||
|
||||
if (Environment::shipState.shipType == 1) {
|
||||
sparkEmitterPtr = &sparkEmitterCargo;
|
||||
static std::vector<Vector3f> emissionPoints = { Vector3f(0, 0, 0), Vector3f(0, 0, 0) };
|
||||
emissionPoints[0] = Environment::shipState.position + Environment::shipState.rotation * Vector3f{ 0.0, 2.8, -3.5 + 16.0 };
|
||||
emissionPoints[1] = Environment::shipState.position + Environment::shipState.rotation * Vector3f{ 0.0, 1.5, -3.5 + 16.0 };
|
||||
sparkEmitterPtr->setEmissionPoints(emissionPoints);
|
||||
}
|
||||
else
|
||||
{
|
||||
sparkEmitterPtr = &sparkEmitter;
|
||||
static std::vector<Vector3f> emissionPoints = { Vector3f(0, 0, 0), Vector3f(0, 0, 0) };
|
||||
emissionPoints[0] = Environment::shipState.position + Environment::shipState.rotation * Vector3f{-1.0, 1.4-1.0, -3.5 + 16.0};
|
||||
emissionPoints[1] = Environment::shipState.position + Environment::shipState.rotation * Vector3f{1.0, 1.4 - 1.0, -3.5 + 16.0 };
|
||||
sparkEmitterPtr->setEmissionPoints(emissionPoints);
|
||||
}
|
||||
|
||||
if (Environment::shipState.velocity > 0.1f)
|
||||
{
|
||||
sparkEmitterPtr->setIsActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
sparkEmitterPtr->setIsActive(false);
|
||||
}
|
||||
|
||||
sparkEmitterPtr->update(static_cast<float>(delta));
|
||||
|
||||
if (firePressed)
|
||||
{
|
||||
firePressed = false;
|
||||
@ -1576,6 +1545,41 @@ namespace ZL
|
||||
}
|
||||
|
||||
|
||||
//--------------
|
||||
|
||||
SparkEmitter* sparkEmitterPtr;
|
||||
|
||||
if (Environment::shipState.shipType == 1) {
|
||||
sparkEmitterPtr = &sparkEmitterCargo;
|
||||
static std::vector<Vector3f> 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<Vector3f> 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<float>(delta));
|
||||
|
||||
|
||||
auto latestRemotePlayers = networkClient->getRemotePlayers();
|
||||
|
||||
std::chrono::system_clock::time_point nowRoundedWithDelay{ std::chrono::milliseconds(newTickCount - CLIENT_DELAY) };
|
||||
@ -1607,7 +1611,7 @@ namespace ZL
|
||||
for (const auto& p : projectiles) {
|
||||
if (p && p->isActive()) {
|
||||
Vector3f worldPos = p->getPosition();
|
||||
p->projectileEmitter.setEmissionPoints({ worldPos });
|
||||
p->projectileEmitter.resetEmissionPoints({ worldPos });
|
||||
p->projectileEmitter.update(static_cast<float>(delta));
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,6 +168,18 @@ namespace ZL {
|
||||
drawDataDirty = false;
|
||||
}
|
||||
|
||||
void SparkEmitter::prepareForDraw(bool withRotation) {
|
||||
if (!configured) return;
|
||||
|
||||
prepareDrawData(withRotation);
|
||||
|
||||
if (!drawPositions.empty()) {
|
||||
sparkQuad.data.PositionData = drawPositions;
|
||||
sparkQuad.data.TexCoordData = drawTexCoords;
|
||||
sparkQuad.RefreshVBO();
|
||||
}
|
||||
}
|
||||
|
||||
void SparkEmitter::draw(Renderer& renderer, float zoom, int screenWidth, int screenHeight)
|
||||
{
|
||||
draw(renderer, zoom, screenWidth, screenHeight, true);
|
||||
@ -186,35 +198,28 @@ namespace ZL {
|
||||
throw std::runtime_error("Failed to load spark emitter config file 2!");
|
||||
}
|
||||
|
||||
prepareDrawData(withRotation);
|
||||
//prepareDrawData(withRotation);
|
||||
|
||||
if (drawPositions.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
sparkQuad.data.PositionData = drawPositions;
|
||||
sparkQuad.data.TexCoordData = drawTexCoords;
|
||||
sparkQuad.RefreshVBO();
|
||||
|
||||
*/
|
||||
renderer.shaderManager.PushShader(shaderProgramName);
|
||||
renderer.RenderUniform1i(textureUniformName, 0);
|
||||
|
||||
//float aspectRatio = static_cast<float>(screenWidth) / static_cast<float>(screenHeight);
|
||||
//renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5, aspectRatio, Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR);
|
||||
renderer.SetMatrix();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture->getTexID());
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
|
||||
renderer.PushMatrix();
|
||||
//renderer.LoadIdentity();
|
||||
//renderer.TranslateMatrix({ 0, 0, -1.0f * zoom });
|
||||
|
||||
//renderer.PushMatrix();
|
||||
renderer.DrawVertexRenderStruct(sparkQuad);
|
||||
|
||||
renderer.PopMatrix();
|
||||
//renderer.PopProjectionMatrix();
|
||||
//renderer.PopMatrix();
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
renderer.shaderManager.PopShader();
|
||||
@ -229,9 +234,19 @@ namespace ZL {
|
||||
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
currentTime - lastEmissionTime).count();
|
||||
|
||||
if (isActive && elapsed >= emissionRate) {
|
||||
emit();
|
||||
lastEmissionTime = currentTime;
|
||||
if (isActive && elapsed >= static_cast<long long>(emissionRate)) {
|
||||
int emitCount = static_cast<int>(elapsed / emissionRate);
|
||||
float elapsedF = static_cast<float>(elapsed);
|
||||
for (int e = 0; e < emitCount; ++e) {
|
||||
// e=0 — самая старая эмиссия, e=emitCount-1 — самая свежая
|
||||
float ageMs = static_cast<float>(emitCount - 1 - e) * emissionRate;
|
||||
// lerpT=0 → текущая позиция (новейшая), lerpT=1 → предыдущая (самая старая)
|
||||
float lerpT = (elapsedF > 0.0f) ? min(ageMs / elapsedF, 1.0f) : 0.0f;
|
||||
emit(ageMs, lerpT);
|
||||
}
|
||||
lastEmissionTime += std::chrono::milliseconds(
|
||||
static_cast<long long>(emitCount * emissionRate));
|
||||
|
||||
drawDataDirty = true;
|
||||
}
|
||||
|
||||
@ -270,7 +285,7 @@ namespace ZL {
|
||||
}
|
||||
}
|
||||
|
||||
void SparkEmitter::emit() {
|
||||
void SparkEmitter::emit(float ageMs, float lerpT) {
|
||||
if (!configured) {
|
||||
throw std::runtime_error("Failed to load spark emitter config file 4!");
|
||||
}
|
||||
@ -278,7 +293,30 @@ namespace ZL {
|
||||
if (emissionPoints.empty()) return;
|
||||
bool emitted = false;
|
||||
|
||||
for (int i = 0; i < emissionPoints.size(); ++i) {
|
||||
auto applyAge = [](SparkParticle& particle, float age) {
|
||||
if (age <= 0.0f) return;
|
||||
particle.position(0) += particle.velocity(0) * age / 1000.0f;
|
||||
particle.position(1) += particle.velocity(1) * age / 1000.0f;
|
||||
particle.position(2) += particle.velocity(2) * age / 1000.0f;
|
||||
particle.lifeTime = age;
|
||||
if (particle.lifeTime >= particle.maxLifeTime) {
|
||||
particle.active = false;
|
||||
} else {
|
||||
float lifeRatio = particle.lifeTime / particle.maxLifeTime;
|
||||
particle.scale = 1.0f - lifeRatio * 0.8f;
|
||||
}
|
||||
};
|
||||
|
||||
// Вычисляем стартовую позицию с интерполяцией между prev и current
|
||||
// lerpT=0 → текущая позиция (новейшая эмиссия), lerpT=1 → предыдущая (самая старая)
|
||||
bool canInterp = (prevEmissionPoints.size() == emissionPoints.size());
|
||||
|
||||
for (int i = 0; i < (int)emissionPoints.size(); ++i) {
|
||||
Vector3f birthPos = emissionPoints[i];
|
||||
if (canInterp && lerpT > 0.0f) {
|
||||
birthPos = emissionPoints[i] * (1.0f - lerpT) + prevEmissionPoints[i] * lerpT;
|
||||
}
|
||||
|
||||
bool particleFound = false;
|
||||
|
||||
for (auto& particle : particles) {
|
||||
@ -286,8 +324,9 @@ namespace ZL {
|
||||
initParticle(particle, i);
|
||||
particle.active = true;
|
||||
particle.lifeTime = 0;
|
||||
particle.position = emissionPoints[i];
|
||||
particle.position = birthPos;
|
||||
particle.emitterIndex = i;
|
||||
applyAge(particle, ageMs);
|
||||
particleFound = true;
|
||||
emitted = true;
|
||||
break;
|
||||
@ -296,11 +335,11 @@ namespace ZL {
|
||||
|
||||
if (!particleFound && !particles.empty()) {
|
||||
size_t oldestIndex = 0;
|
||||
float maxLifeTime = 0;
|
||||
float maxLifeRatio = 0;
|
||||
|
||||
for (size_t j = 0; j < particles.size(); ++j) {
|
||||
if (particles[j].lifeTime > maxLifeTime) {
|
||||
maxLifeTime = particles[j].lifeTime;
|
||||
if (particles[j].lifeTime > maxLifeRatio) {
|
||||
maxLifeRatio = particles[j].lifeTime;
|
||||
oldestIndex = j;
|
||||
}
|
||||
}
|
||||
@ -308,8 +347,9 @@ namespace ZL {
|
||||
initParticle(particles[oldestIndex], i);
|
||||
particles[oldestIndex].active = true;
|
||||
particles[oldestIndex].lifeTime = 0;
|
||||
particles[oldestIndex].position = emissionPoints[i];
|
||||
particles[oldestIndex].position = birthPos;
|
||||
particles[oldestIndex].emitterIndex = i;
|
||||
applyAge(particles[oldestIndex], ageMs);
|
||||
emitted = true;
|
||||
}
|
||||
}
|
||||
@ -320,6 +360,14 @@ namespace ZL {
|
||||
}
|
||||
|
||||
void SparkEmitter::setEmissionPoints(const std::vector<Vector3f>& positions) {
|
||||
prevEmissionPoints = emissionPoints;
|
||||
emissionPoints = positions;
|
||||
drawDataDirty = true;
|
||||
}
|
||||
|
||||
void SparkEmitter::resetEmissionPoints(const std::vector<Vector3f>& positions)
|
||||
{
|
||||
prevEmissionPoints.clear();
|
||||
emissionPoints = positions;
|
||||
drawDataDirty = true;
|
||||
}
|
||||
@ -487,8 +535,9 @@ namespace ZL {
|
||||
std::cout << "Total emission points: " << emissionPoints.size() << std::endl;
|
||||
}
|
||||
else {
|
||||
std::cerr << "Emission points parsed but empty" << std::endl;
|
||||
throw std::runtime_error("Failed to load spark emitter config file 10!");
|
||||
setEmissionPoints({});
|
||||
std::cout << "Emission points parsed but empty" << std::endl;
|
||||
//throw std::runtime_error("Failed to load spark emitter config file 10!");
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -575,25 +624,6 @@ namespace ZL {
|
||||
throw std::runtime_error("Failed to load spark emitter config file 18!");
|
||||
}
|
||||
|
||||
|
||||
std::cout << "Working with shaders 2" << std::endl;
|
||||
/*
|
||||
if (j.contains("vertexShader") && j.contains("fragmentShader")
|
||||
&& j["vertexShader"].is_string() && j["fragmentShader"].is_string()) {
|
||||
std::string v = j["vertexShader"].get<std::string>();
|
||||
std::string f = j["fragmentShader"].get<std::string>();
|
||||
std::cout << "Loading shaders - vertex: " << v << ", fragment: " << f << std::endl;
|
||||
|
||||
try {
|
||||
renderer.shaderManager.AddShaderFromFiles(shaderProgramName, v, f, zipFile.c_str());
|
||||
std::cout << "Shaders loaded successfully" << std::endl;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "Shader load error: " << e.what() << std::endl;
|
||||
throw std::runtime_error("Failed to load spark emitter config file 19!");
|
||||
}
|
||||
}*/
|
||||
|
||||
drawDataDirty = true;
|
||||
configured = true;
|
||||
std::cout << "SparkEmitter configuration loaded successfully!" << std::endl;
|
||||
|
||||
@ -26,6 +26,7 @@ namespace ZL {
|
||||
private:
|
||||
std::vector<SparkParticle> particles;
|
||||
std::vector<Vector3f> emissionPoints;
|
||||
std::vector<Vector3f> prevEmissionPoints;
|
||||
std::chrono::steady_clock::time_point lastEmissionTime;
|
||||
float emissionRate;
|
||||
bool isActive;
|
||||
@ -62,6 +63,7 @@ namespace ZL {
|
||||
float rate = 100.0f);
|
||||
|
||||
void setEmissionPoints(const std::vector<Vector3f>& positions);
|
||||
void resetEmissionPoints(const std::vector<Vector3f>& positions);
|
||||
void setTexture(std::shared_ptr<Texture> tex);
|
||||
void setEmissionRate(float rate) { emissionRate = rate; }
|
||||
void setShaderProgramName(const std::string& name) { shaderProgramName = name; }
|
||||
@ -73,7 +75,10 @@ namespace ZL {
|
||||
bool loadFromJsonFile(const std::string& path, Renderer& renderer, const std::string& zipFile = "");
|
||||
|
||||
void update(float deltaTimeMs);
|
||||
void emit();
|
||||
void emit(float ageMs = 0.0f, float lerpT = 0.0f);
|
||||
|
||||
// Вызывать ДО draw() в начале кадра: готовит данные и загружает в VBO.
|
||||
void prepareForDraw(bool withRotation = true);
|
||||
|
||||
void draw(Renderer& renderer, float zoom, int screenWidth, int screenHeight);
|
||||
void draw(Renderer& renderer, float zoom, int screenWidth, int screenHeight, bool withRotation);
|
||||
|
||||
@ -381,7 +381,7 @@ namespace ZL {
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, positionVBO->getBuffer());
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, data.PositionData.size() * 12, &data.PositionData[0], GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, data.PositionData.size() * 12, &data.PositionData[0], GL_DYNAMIC_DRAW);
|
||||
|
||||
if (data.TexCoordData.size() > 0)
|
||||
{
|
||||
@ -392,7 +392,7 @@ namespace ZL {
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, texCoordVBO->getBuffer());
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, data.TexCoordData.size() * 8, &data.TexCoordData[0], GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, data.TexCoordData.size() * 8, &data.TexCoordData[0], GL_DYNAMIC_DRAW);
|
||||
}
|
||||
|
||||
if (data.NormalData.size() > 0)
|
||||
@ -404,7 +404,7 @@ namespace ZL {
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, normalVBO->getBuffer());
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, data.NormalData.size() * 12, &data.NormalData[0], GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, data.NormalData.size() * 12, &data.NormalData[0], GL_DYNAMIC_DRAW);
|
||||
}
|
||||
|
||||
if (data.TangentData.size() > 0)
|
||||
@ -416,7 +416,7 @@ namespace ZL {
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tangentVBO->getBuffer());
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, data.TangentData.size() * 12, &data.TangentData[0], GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, data.TangentData.size() * 12, &data.TangentData[0], GL_DYNAMIC_DRAW);
|
||||
}
|
||||
|
||||
if (data.BinormalData.size() > 0)
|
||||
@ -428,7 +428,7 @@ namespace ZL {
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, binormalVBO->getBuffer());
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, data.BinormalData.size() * 12, &data.BinormalData[0], GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, data.BinormalData.size() * 12, &data.BinormalData[0], GL_DYNAMIC_DRAW);
|
||||
}
|
||||
|
||||
if (data.ColorData.size() > 0)
|
||||
@ -440,7 +440,7 @@ namespace ZL {
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, colorVBO->getBuffer());
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, data.ColorData.size() * 12, &data.ColorData[0], GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, data.ColorData.size() * 12, &data.ColorData[0], GL_DYNAMIC_DRAW);
|
||||
}
|
||||
}
|
||||
|
||||
@ -846,8 +846,25 @@ namespace ZL {
|
||||
glVertexAttribPointer(shader->attribList[attribName], 3, GL_FLOAT, GL_FALSE, stride, pointer);
|
||||
}
|
||||
|
||||
void Renderer::DisableVertexAttribArray(const std::string& attribName)
|
||||
{
|
||||
auto shader = shaderManager.GetCurrentShader();
|
||||
auto it = shader->attribList.find(attribName);
|
||||
if (it != shader->attribList.end())
|
||||
glDisableVertexAttribArray(it->second);
|
||||
}
|
||||
|
||||
void Renderer::DrawVertexRenderStruct(const VertexRenderStruct& VertexRenderStruct)
|
||||
{
|
||||
#ifndef EMSCRIPTEN
|
||||
#ifndef __ANDROID__
|
||||
if (VertexRenderStruct.vao) {
|
||||
glBindVertexArray(VertexRenderStruct.vao->getBuffer());
|
||||
shaderManager.EnableVertexAttribArrays();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static const std::string vNormal("vNormal");
|
||||
static const std::string vTangent("vTangent");
|
||||
static const std::string vBinormal("vBinormal");
|
||||
@ -861,51 +878,46 @@ namespace ZL {
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.normalVBO->getBuffer());
|
||||
VertexAttribPointer3fv(vNormal, 0, NULL);
|
||||
//EnableVertexAttribArray(vNormal);
|
||||
}
|
||||
else
|
||||
{
|
||||
//DisableVertexAttribArray(vNormal);
|
||||
DisableVertexAttribArray(vNormal);
|
||||
}
|
||||
if (VertexRenderStruct.data.TangentData.size() > 0)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.tangentVBO->getBuffer());
|
||||
VertexAttribPointer3fv(vTangent, 0, NULL);
|
||||
//EnableVertexAttribArray(vTangent);
|
||||
}
|
||||
else
|
||||
{
|
||||
//DisableVertexAttribArray(vTangent);
|
||||
DisableVertexAttribArray(vTangent);
|
||||
}
|
||||
if (VertexRenderStruct.data.BinormalData.size() > 0)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.binormalVBO->getBuffer());
|
||||
VertexAttribPointer3fv(vBinormal, 0, NULL);
|
||||
//EnableVertexAttribArray(vBinormal);
|
||||
}
|
||||
else
|
||||
{
|
||||
//DisableVertexAttribArray(vBinormal);
|
||||
DisableVertexAttribArray(vBinormal);
|
||||
}
|
||||
if (VertexRenderStruct.data.ColorData.size() > 0)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.colorVBO->getBuffer());
|
||||
VertexAttribPointer3fv(vColor, 0, NULL);
|
||||
//EnableVertexAttribArray(vColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
//DisableVertexAttribArray(vColor);
|
||||
DisableVertexAttribArray(vColor);
|
||||
}
|
||||
if (VertexRenderStruct.data.TexCoordData.size() > 0)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.texCoordVBO->getBuffer());
|
||||
VertexAttribPointer2fv(vTexCoord, 0, NULL);
|
||||
//EnableVertexAttribArray(vTexCoord);
|
||||
}
|
||||
else
|
||||
{
|
||||
//DisableVertexAttribArray(vTexCoord);
|
||||
DisableVertexAttribArray(vTexCoord);
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.positionVBO->getBuffer());
|
||||
|
||||
@ -138,6 +138,8 @@ namespace ZL {
|
||||
|
||||
void VertexAttribPointer3fv(const std::string& attribName, int stride, const char* pointer);
|
||||
|
||||
void DisableVertexAttribArray(const std::string& attribName);
|
||||
|
||||
void DrawVertexRenderStruct(const VertexRenderStruct& VertexRenderStruct);
|
||||
};
|
||||
|
||||
|
||||
@ -200,7 +200,6 @@ namespace ZL {
|
||||
{
|
||||
glEnableVertexAttribArray(attrib.second);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -232,6 +231,19 @@ namespace ZL {
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderManager::EnableVertexAttribArrays()
|
||||
{
|
||||
if (shaderStack.size() != 0) {
|
||||
auto& shaderResource = shaderResourceMap[shaderStack.top()];
|
||||
|
||||
auto& shaderAttribList = shaderResource->attribList;
|
||||
for (auto& attrib : shaderAttribList)
|
||||
{
|
||||
glEnableVertexAttribArray(attrib.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr <ShaderResource> ShaderManager::GetCurrentShader() {
|
||||
if (shaderStack.size() == 0) {
|
||||
throw std::runtime_error("Shader stack underflow!");
|
||||
|
||||
@ -42,6 +42,7 @@ namespace ZL {
|
||||
|
||||
void PushShader(const std::string& shaderName);
|
||||
void PopShader();
|
||||
void EnableVertexAttribArrays();
|
||||
|
||||
std::shared_ptr<ShaderResource> GetCurrentShader();
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user