This commit is contained in:
lennlouisgeek
2026-03-02 22:50:17 +08:00
parent c59c921997
commit 348e4130a3
4 changed files with 144 additions and 5 deletions

View File

@@ -1,6 +1,3 @@
If:
OS: Windows
CompileFlags: CompileFlags:
Add: Add:
--target=x86_64-w64-mingw32 --target=x86_64-w64-mingw32

View File

@@ -43,4 +43,6 @@ elseif(UNIX)
) )
endif() endif()
if (WIN32)
add_compile_options(--target=x86_64-w64-mingw32)
endif()

View File

@@ -58,6 +58,15 @@ public:
if (heatmapIbo_) { if (heatmapIbo_) {
glDeleteBuffers(1, &heatmapIbo_); glDeleteBuffers(1, &heatmapIbo_);
} }
if (skirtVao_) {
glDeleteVertexArrays(1, &skirtVao_);
}
if (skirtVbo_) {
glDeleteBuffers(1, &skirtVbo_);
}
if (skirtIbo_) {
glDeleteBuffers(1, &skirtIbo_);
}
deinit_ = true; deinit_ = true;
} }
@@ -301,6 +310,80 @@ private:
glBindVertexArray(0); glBindVertexArray(0);
} }
void initSkirtGeometry_() {
if (skirtIbo_) {
glDeleteBuffers(1, &skirtIbo_);
skirtIbo_ = 0;
}
if (skirtVao_) {
glDeleteVertexArrays(1, &skirtVao_);
skirtVao_ = 0;
}
if (skirtVbo_) {
glDeleteBuffers(1, &skirtVbo_);
skirtVbo_ = 0;
}
skirtUVs.clear();
skirtNormals.clear();
const int cols = std::max(2, heatmapcols_);
const int rows = std::max(2, heatmaprows_);
auto push_border = [&](int c, int r, const glm::vec3& n) {
const float u = (cols > 1) ? float(c) / float(cols - 1) : 0.0F;
const float v = (rows > 1) ? float(r) / float(rows - 1) : 0.0F;
skirtUVs.push_back(glm::vec2(u, v));
skirtNormals.push_back(n);
};
for (int c = 0; c < cols; ++c) {
push_border(c, 0, glm::vec3(0.0F, -1.0F, 0.0F));
}
for (int r = 1; r < rows; ++r) {
push_border(cols - 1, r, glm::vec3(1.0F, 0.0F, 0.0F));
}
for (int c = cols -1; c >= 0; --c) {
push_border(c, rows - 1, glm::vec3(0.0F, 1.0F, 0.0F));
}
for (int r = rows - 2; r >= 1; --r) {
push_border(0, r, glm::vec3(-1.0F, 0.0F, 0.0F));
}
const int border_count = skirtUVs.size();
// TODO: fill
// std::vector<float> verts;
// verts.assign(border_count * 2 * 8, 0.0F);
skirtVertices.assign(border_count * 8 * 2, 0.0F);
std::vector<unsigned int> idx;
idx.reserve(border_count * 6);
for (int i = 0; i < border_count; ++i) {
unsigned int next = (i + 1) % border_count;
const unsigned int top0 = unsigned(i * 2);
const unsigned int bot0 = unsigned(i * 2 + 1);
const unsigned int top1 = unsigned(next * 2);
const unsigned int bot1 = unsigned(next * 2 + 1);
idx.push_back(top0);
idx.push_back(top1);
idx.push_back(bot1);
idx.push_back(top0);
idx.push_back(bot0);
idx.push_back(bot1);
}
skirtIndexCount_ = static_cast<int>(idx.size());
glGenVertexArrays(1, &skirtVao_);
glBindVertexArray(skirtVao_);
glGenBuffers(1, &skirtVbo_);
glBindBuffer(GL_ARRAY_BUFFER, skirtVbo_);
glBufferData(GL_ARRAY_BUFFER, skirtVertices.size() * sizeof(float), skirtVertices.data(), GL_STATIC_DRAW);
glGenBuffers(1, &skirtIbo_);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, skirtIbo_);
}
bool initBgProgram() { bool initBgProgram() {
auto vshader = std::make_unique<LOpenGLShader>(LOpenGLShader::ShaderType::Vertex); auto vshader = std::make_unique<LOpenGLShader>(LOpenGLShader::ShaderType::Vertex);
auto fshader = std::make_unique<LOpenGLShader>(LOpenGLShader::ShaderType::Fragment); auto fshader = std::make_unique<LOpenGLShader>(LOpenGLShader::ShaderType::Fragment);
@@ -560,6 +643,17 @@ private:
unsigned int heatmapIbo_ = 0; unsigned int heatmapIbo_ = 0;
int heatmapIndexCount = 0; int heatmapIndexCount = 0;
std::unique_ptr<LOpenGLProgram> skirtProg_;
std::string skirtVertShaderPath_;
std::string skirtFragShaderPath_;
unsigned int skirtVao_ = 0;
unsigned int skirtVbo_ = 0;
unsigned int skirtIbo_ = 0;
std::vector<glm::vec2> skirtUVs;
std::vector<glm::vec3> skirtNormals;
int skirtIndexCount_ = 0;
std::vector<float> skirtVertices;
ViewPort viewport_{800, 600}; ViewPort viewport_{800, 600};
Camera camera_{glm::vec3(0.0F, 0.0F, 2.0F)}; Camera camera_{glm::vec3(0.0F, 0.0F, 2.0F)};

View File

@@ -33,5 +33,51 @@ vec3 colorRamp(float t) {
} }
float maxNeighborValue(vec2 uv) { float maxNeighborValue(vec2 uv) {
vec2 texelSizeF = 1.0 / uTexelSize;
ivec2 texelSizeI = ivec2(max(1.0, floor(uTexelSize + 0.5)));
ivec2 maxCoord = texelSizeI - 1;
vec2 texelF = vec2(clamp(uv * maxCoord, vec2(0.0), vec2(maxCoord)));
ivec2 base = ivec2(floor(texelF));
ivec2 base10 = min(base + ivec2(1, 0), maxCoord);
ivec2 base01 = min(base + ivec2(0, 1), maxCoord);
ivec2 base11 = min(base + ivec2(1, 1), maxCoord);
float v00 = texelFetch(uColorHeigh, base, 0).r;
float v10 = texelFetch(uColorHeigh, base10, 0).r;
float v01 = texelFetch(uColorHeigh, base01, 0).r;
float v11 = texelFetch(uColorHeigh, base11, 0).r;
return max(max(v00, v10), max(v01, v11));
}
vec3 colorRampWithZero(float t) {
const float zeroW = 0.005;
float blend = smoothstep(0.0, zeroW, t);
float tRamp = saturate(t - zeroW) / max(1.0 - zeroW, 1e-6);
vec3 ramp = colorRamp(tRamp);
return mix(uColorZero, ramp, blend);
}
void main() {
vec3 N = normalize(vNormal);
vec3 L = normalize(uLightDir);
vec3 V = normalize(uCameraPos - vWorldPos);
vec3 H = normalize(L + V);
float diff = saturate(dot(N, L));
float spec = pow(saturate(dot(N, H)), 24.0);
float vC = texture(uHeightTex, vUV).r;
bool isZero = abs(vC) <= 1e-6;
float t = value01(vC);
float m = maxNeighborValue(vUV);
float eps = max(1e-4, 0.001 * (uMaxV - uMinV));
float force = smoothstep(uMaxV - eps, uMaxV, m);
t = max(t, force);
vec3 base = isZero ? uColorZero : colorRampWithZero(t);
vec3 col = base * (0.35 + 0.65 * diff);
col += vec3(1.0) * spec * 0.10;
FragColor = vec4(clamp(col, 0.0, 1.0), 1.0);
} }