You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

添加纹理背景时GLSL程序崩溃的问题求助

添加纹理背景时GLSL程序崩溃的问题求助

大家好,我最近在开发一个基于光线步进SDF的OpenGL项目,原本基础渲染逻辑是正常的,但当我尝试给场景添加纹理背景后,程序直接崩溃了。自己排查了好一阵也没定位到问题,只好来求助各位大佬了。

下面是我的核心C++代码,包含着色器加载、编译、纹理加载以及主程序初始化逻辑:

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <cmath>
#include <string>

// Including stb_image for image loading
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

int WIDTH = 1920;
int HEIGHT = 1080;

std::string loadShaderSource(const char* filepath) {
    std::ifstream file(filepath);
    if (!file.is_open()) {
        std::cerr << "[ERROR] Failed to open shader file: " << filepath << std::endl;
        return "";
    }
    std::stringstream ss;
    ss << file.rdbuf();
    std::string src = ss.str();
    std::cout << "[INFO] Shader loaded from " << filepath << ", size: " << src.size() << " bytes\n";
    std::cout << "------- " << filepath << " -------\n";
    std::cout << src << "\n";
    std::cout << "----------------------------------\n";
    return src;
}

GLuint compileShader(GLenum type, const char* source, const std::string& name) {
    GLuint shader = glCreateShader(type);
    glShaderSource(shader, 1, &source, nullptr);
    glCompileShader(shader);

    GLint success;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
    if (!success) {
        char info[2048];
        glGetShaderInfoLog(shader, 2048, nullptr, info);
        std::cerr << "[ERROR] Compilation failed for " << name << ":\n" << info << std::endl;
    } else {
        std::cout << "[INFO] " << name << " compiled successfully.\n";
    }
    return shader;
}

GLuint createShaderProgram(const char* vertexPath, const char* fragPath) {
    std::string vsrc = loadShaderSource(vertexPath);
    std::string fsrc = loadShaderSource(fragPath);

    GLuint vShader = compileShader(GL_VERTEX_SHADER, vsrc.c_str(), vertexPath);
    GLuint fShader = compileShader(GL_FRAGMENT_SHADER, fsrc.c_str(), fragPath);

    GLuint program = glCreateProgram();
    glAttachShader(program, vShader);
    glAttachShader(program, fShader);
    glLinkProgram(program);

    GLint success;
    glGetProgramiv(program, GL_LINK_STATUS, &success);
    if (!success) {
        char info[2048];
        glGetProgramInfoLog(program, 2048, nullptr, info);
        std::cerr << "[ERROR] Program link failed:\n" << info << std::endl;
    } else {
        std::cout << "[INFO] Shader program linked successfully.\n";
    }

    glDeleteShader(vShader);
    glDeleteShader(fShader);
    return program;
}

GLuint loadTexture(const char* path) {
    std::cout << "[DEBUG] Attempting to load texture: " << path << "\n";
    int w, h, channels;
    stbi_set_flip_vertically_on_load(true); // For OpenGL's UVs
    unsigned char* data = stbi_load(path, &w, &h, &channels, 0);

    if (!data) {
        std::cerr << "[ERROR] Failed to load image: " << path << "\n";
        return 0;
    }

    GLenum format = (channels == 3)? GL_RGB : GL_RGBA;
    std::cout << "[DEBUG] Image loaded. Size: " << w << "x" << h << ", Channels: " << channels << "\n";

    GLuint texID;
    glGenTextures(1, &texID);
    glBindTexture(GL_TEXTURE_2D, texID);

    glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, GL_UNSIGNED_BYTE, data);
    glGenerateMipmap(GL_TEXTURE_2D);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    stbi_image_free(data);
    return texID;
}

int main() {
    if (!glfwInit()) {
        std::cerr << "[ERROR] Failed to initialize GLFW\n";
        return -1;
    }

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

    GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "Raymarching SDF", nullptr, nullptr);
    if (!window) {
        std::cerr << "[ERROR] Failed to create GLFW window\n";
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);
    glewExperimental = true;
    GLenum glewErr = glewInit();
    if (glewErr != GLEW_OK) {
        std::cerr << "[ERROR] Failed to initialize GLEW: " << glewGetErrorString(glewErr) << "\n";
        return -1;
    }

    std::cout << "[INFO] OpenGL Version: " << glGetString(GL_VERSION) << "\n";

    GLuint shaderProgram = createShaderProgram("../src/shaders/basic.vert", "../src/shaders/background.frag");

    float quad[] = {
        -1, -1,
         1, -1,
        -1,  1,
        -1,  1,
         1, -1,
         1,  1
    };

    GLuint VAO, VBO;
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), 0);
    glEnableVertexAttribArray(0);

    float startTime = glfwGetTime();

    // 实际代码里有完整渲染循环,但崩溃发生在第一次绑定纹理并执行glDrawArrays的时候
}

补充说明:程序崩溃时没有输出明确的错误日志,只有初始化阶段的INFO/DEBUG信息。我怀疑可能是纹理加载逻辑有疏漏,或者是着色器中使用纹理的方式不对?但目前完全摸不着头绪,麻烦各位帮我排查一下可能的问题点。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 09:09:32