mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-24 00:00:13 +00:00
Initial commit: wowee native WoW 3.3.5a client
This commit is contained in:
commit
ce6cb8f38e
147 changed files with 32347 additions and 0 deletions
259
src/rendering/starfield.cpp
Normal file
259
src/rendering/starfield.cpp
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
#include "rendering/starfield.hpp"
|
||||
#include "rendering/shader.hpp"
|
||||
#include "rendering/camera.hpp"
|
||||
#include "core/logger.hpp"
|
||||
#include <GL/glew.h>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <cmath>
|
||||
#include <random>
|
||||
|
||||
namespace wowee {
|
||||
namespace rendering {
|
||||
|
||||
StarField::StarField() = default;
|
||||
|
||||
StarField::~StarField() {
|
||||
shutdown();
|
||||
}
|
||||
|
||||
bool StarField::initialize() {
|
||||
LOG_INFO("Initializing star field");
|
||||
|
||||
// Create star shader
|
||||
starShader = std::make_unique<Shader>();
|
||||
|
||||
// Vertex shader - simple point rendering
|
||||
const char* vertexShaderSource = R"(
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in float aBrightness;
|
||||
layout (location = 2) in float aTwinklePhase;
|
||||
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
uniform float time;
|
||||
uniform float intensity;
|
||||
|
||||
out float Brightness;
|
||||
|
||||
void main() {
|
||||
// Remove translation from view matrix (stars are infinitely far)
|
||||
mat4 viewNoTranslation = mat4(mat3(view));
|
||||
|
||||
gl_Position = projection * viewNoTranslation * vec4(aPos, 1.0);
|
||||
|
||||
// Twinkle effect (subtle brightness variation)
|
||||
float twinkle = sin(time * 2.0 + aTwinklePhase) * 0.2 + 0.8; // 0.6 to 1.0
|
||||
|
||||
Brightness = aBrightness * twinkle * intensity;
|
||||
|
||||
// Point size based on brightness
|
||||
gl_PointSize = 2.0 + aBrightness * 2.0; // 2-4 pixels
|
||||
}
|
||||
)";
|
||||
|
||||
// Fragment shader - star color
|
||||
const char* fragmentShaderSource = R"(
|
||||
#version 330 core
|
||||
in float Brightness;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
// Circular point (not square)
|
||||
vec2 coord = gl_PointCoord - vec2(0.5);
|
||||
float dist = length(coord);
|
||||
if (dist > 0.5) {
|
||||
discard;
|
||||
}
|
||||
|
||||
// Soften edges
|
||||
float alpha = smoothstep(0.5, 0.3, dist);
|
||||
|
||||
// Star color (slightly blue-white)
|
||||
vec3 starColor = vec3(0.9, 0.95, 1.0);
|
||||
|
||||
FragColor = vec4(starColor * Brightness, alpha * Brightness);
|
||||
}
|
||||
)";
|
||||
|
||||
if (!starShader->loadFromSource(vertexShaderSource, fragmentShaderSource)) {
|
||||
LOG_ERROR("Failed to create star shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Generate random stars
|
||||
generateStars();
|
||||
|
||||
// Create OpenGL buffers
|
||||
createStarBuffers();
|
||||
|
||||
LOG_INFO("Star field initialized: ", starCount, " stars");
|
||||
return true;
|
||||
}
|
||||
|
||||
void StarField::shutdown() {
|
||||
destroyStarBuffers();
|
||||
starShader.reset();
|
||||
stars.clear();
|
||||
}
|
||||
|
||||
void StarField::render(const Camera& camera, float timeOfDay) {
|
||||
if (!renderingEnabled || vao == 0 || !starShader || stars.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get star intensity based on time of day
|
||||
float intensity = getStarIntensity(timeOfDay);
|
||||
|
||||
// Don't render if stars would be invisible
|
||||
if (intensity <= 0.01f) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable blending for star glow
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// Enable point sprites
|
||||
glEnable(GL_PROGRAM_POINT_SIZE);
|
||||
|
||||
// Disable depth writing (stars are background)
|
||||
glDepthMask(GL_FALSE);
|
||||
|
||||
starShader->use();
|
||||
|
||||
// Set uniforms
|
||||
glm::mat4 view = camera.getViewMatrix();
|
||||
glm::mat4 projection = camera.getProjectionMatrix();
|
||||
|
||||
starShader->setUniform("view", view);
|
||||
starShader->setUniform("projection", projection);
|
||||
starShader->setUniform("time", twinkleTime);
|
||||
starShader->setUniform("intensity", intensity);
|
||||
|
||||
// Render stars as points
|
||||
glBindVertexArray(vao);
|
||||
glDrawArrays(GL_POINTS, 0, starCount);
|
||||
glBindVertexArray(0);
|
||||
|
||||
// Restore state
|
||||
glDepthMask(GL_TRUE);
|
||||
glDisable(GL_PROGRAM_POINT_SIZE);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void StarField::update(float deltaTime) {
|
||||
// Update twinkle animation
|
||||
twinkleTime += deltaTime;
|
||||
}
|
||||
|
||||
void StarField::generateStars() {
|
||||
stars.clear();
|
||||
stars.reserve(starCount);
|
||||
|
||||
// Random number generator
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::uniform_real_distribution<float> phiDist(0.0f, M_PI / 2.0f); // 0 to 90 degrees (hemisphere)
|
||||
std::uniform_real_distribution<float> thetaDist(0.0f, 2.0f * M_PI); // 0 to 360 degrees
|
||||
std::uniform_real_distribution<float> brightnessDist(0.3f, 1.0f); // Varying brightness
|
||||
std::uniform_real_distribution<float> twinkleDist(0.0f, 2.0f * M_PI); // Random twinkle phase
|
||||
|
||||
const float radius = 900.0f; // Slightly larger than skybox
|
||||
|
||||
for (int i = 0; i < starCount; i++) {
|
||||
Star star;
|
||||
|
||||
// Spherical coordinates (hemisphere)
|
||||
float phi = phiDist(gen); // Elevation angle
|
||||
float theta = thetaDist(gen); // Azimuth angle
|
||||
|
||||
// Convert to Cartesian coordinates
|
||||
float x = radius * std::sin(phi) * std::cos(theta);
|
||||
float y = radius * std::sin(phi) * std::sin(theta);
|
||||
float z = radius * std::cos(phi);
|
||||
|
||||
star.position = glm::vec3(x, y, z);
|
||||
star.brightness = brightnessDist(gen);
|
||||
star.twinklePhase = twinkleDist(gen);
|
||||
|
||||
stars.push_back(star);
|
||||
}
|
||||
|
||||
LOG_DEBUG("Generated ", stars.size(), " stars");
|
||||
}
|
||||
|
||||
void StarField::createStarBuffers() {
|
||||
// Prepare vertex data (position, brightness, twinkle phase)
|
||||
std::vector<float> vertexData;
|
||||
vertexData.reserve(stars.size() * 5); // 3 pos + 1 brightness + 1 phase
|
||||
|
||||
for (const auto& star : stars) {
|
||||
vertexData.push_back(star.position.x);
|
||||
vertexData.push_back(star.position.y);
|
||||
vertexData.push_back(star.position.z);
|
||||
vertexData.push_back(star.brightness);
|
||||
vertexData.push_back(star.twinklePhase);
|
||||
}
|
||||
|
||||
// Create OpenGL buffers
|
||||
glGenVertexArrays(1, &vao);
|
||||
glGenBuffers(1, &vbo);
|
||||
|
||||
glBindVertexArray(vao);
|
||||
|
||||
// Upload vertex data
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertexData.size() * sizeof(float), vertexData.data(), GL_STATIC_DRAW);
|
||||
|
||||
// Set vertex attributes
|
||||
// Position
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
// Brightness
|
||||
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
// Twinkle phase
|
||||
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(4 * sizeof(float)));
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void StarField::destroyStarBuffers() {
|
||||
if (vao != 0) {
|
||||
glDeleteVertexArrays(1, &vao);
|
||||
vao = 0;
|
||||
}
|
||||
if (vbo != 0) {
|
||||
glDeleteBuffers(1, &vbo);
|
||||
vbo = 0;
|
||||
}
|
||||
}
|
||||
|
||||
float StarField::getStarIntensity(float timeOfDay) const {
|
||||
// Stars visible at night (fade in/out at dusk/dawn)
|
||||
|
||||
// Full night: 20:00-4:00
|
||||
if (timeOfDay >= 20.0f || timeOfDay < 4.0f) {
|
||||
return 1.0f;
|
||||
}
|
||||
// Fade in at dusk: 18:00-20:00
|
||||
else if (timeOfDay >= 18.0f && timeOfDay < 20.0f) {
|
||||
return (timeOfDay - 18.0f) / 2.0f; // 0 to 1 over 2 hours
|
||||
}
|
||||
// Fade out at dawn: 4:00-6:00
|
||||
else if (timeOfDay >= 4.0f && timeOfDay < 6.0f) {
|
||||
return 1.0f - (timeOfDay - 4.0f) / 2.0f; // 1 to 0 over 2 hours
|
||||
}
|
||||
// Daytime: no stars
|
||||
else {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace rendering
|
||||
} // namespace wowee
|
||||
Loading…
Add table
Add a link
Reference in a new issue