我有这个简单的着色器代码,我想一步一步地完成。我在RenderDoc中启动程序。我选择了一个像素,但调试选项显示为灰色。为什么?我该如何修复它?
我猜测这可能与glsl版本不受支持有关?
我在Windows 11上使用AMD Radeon RX 6650 XT
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <string>
// Vertex Shader Source
const char* vertexShaderSource = R"(
#version 330 core
layout (location = 0) in vec3 aPos;
void main() {
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}
)";
// Fragment Shader Source
const char* fragmentShaderSource = R"(
#version 330 core
out vec4 FragColor;
const int emax = 127;
int floorLog2(float x) {
if (x == 0.) return -emax;
for (int e = emax; e >= 1 - emax; --e)
if (x >= exp2(float(e))) return e;
return emax + 1;
}
int biasedExp(float x) {
return emax + floorLog2(abs(x));
}
float significand(float x) {
float expo = float(floorLog2(abs(x)));
return abs(x) / exp2(expo);
}
int part(float x, int N) {
const float byteShift = 256.;
for (int n = 0; n < N; ++n)
x *= byteShift;
float q = fract(x);
float c = floor(byteShift * q);
return int(c);
}
ivec3 significandAsIVec3(float x) {
ivec3 result;
float sig = significand(x) / 2.;
result.x = part(sig, 0);
result.y = part(sig, 1);
result.z = part(sig, 2);
return result;
}
ivec4 unpackIEEE754binary32(float x) {
int e = biasedExp(x);
int s = x < 0. ? 128 : 0;
ivec4 binary32;
binary32.yzw = significandAsIVec3(x);
if (binary32.y >= 128) {
binary32.y -= 128;
}
binary32.y += 128 * int(mod(float(e), 2.));
e /= 2;
binary32.x = e + s;
binary32.x -= 1;
binary32.y -= 1;
binary32.z -= 1;
binary32.w -= 1;
return binary32;
}
void main() {
float testValue = 3.0;
ivec4 result = unpackIEEE754binary32(testValue);
// Normalize the result to see the output
vec4 color = vec4(
float(result.x) / 255.0,
float(result.y) / 255.0,
float(result.z) / 255.0,
float(result.w) / 255.0
);
FragColor = color;
}
)";
GLFWwindow* createWindow() {
if (!glfwInit()) {
std::cerr << "Failed to initialize GLFW" << std::endl;
return nullptr;
}
// Request OpenGL Debug Context
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(800, 600, "Shader Debug", NULL, NULL);
if (!window) {
std::cerr << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return nullptr;
}
glfwMakeContextCurrent(window);
return window;
}
void APIENTRY openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity,
GLsizei length, const GLchar* message, const void* userParam) {
std::cerr << "OpenGL Debug Message: " << message << std::endl;
}
GLuint compileShader(const char* shaderSource, GLenum shaderType) {
GLuint shader = glCreateShader(shaderType);
// Provide the shader source code
glShaderSource(shader, 1, &shaderSource, nullptr);
// Compile the shader with debug info (if supported)
glCompileShader(shader);
// Check for compile errors
GLint success;
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success) {
// Retrieve and print the error log
GLchar infoLog[1024];
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
const char* shaderTypeStr = shaderType == GL_VERTEX_SHADER ? "VERTEX" : "FRAGMENT";
std::cerr << "ERROR::SHADER_COMPILATION_ERROR of type: " << shaderTypeStr << "\n"
<< infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
}
return shader;
}
GLuint createShaderProgram() {
GLuint vertexShader = compileShader(vertexShaderSource, GL_VERTEX_SHADER);
GLuint fragmentShader = compileShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
// Create the shader program
GLuint shaderProgram = glCreateProgram();
// Attach shaders
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
// Link the program
glLinkProgram(shaderProgram);
// Check for linking errors
GLint success;
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
// Retrieve and print the error log
GLchar infoLog[1024];
glGetProgramInfoLog(shaderProgram, 1024, NULL, infoLog);
std::cerr << "ERROR::PROGRAM_LINKING_ERROR\n"
<< infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
}
// Delete the shaders as they're linked into our program now and no longer needed
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
return shaderProgram;
}
int main() {
GLFWwindow* window = createWindow();
if (!window) return -1;
// Initialize GLEW with experimental features enabled
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
std::cerr << "Failed to initialize GLEW" << std::endl;
return -1;
}
// Enable OpenGL debug output if available
GLint flags;
glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
if (flags & GL_CONTEXT_FLAG_DEBUG_BIT) {
std::cout << "Debug context active" << std::endl;
glEnable(GL_DEBUG_OUTPUT);
glDebugMessageCallback(openglDebugCallback, nullptr);
}
// Vertex data for a full-screen quad
float vertices[] = {
// positions
-1.0f, 1.0f, 0.0f, // top left
-1.0f, -1.0f, 0.0f, // bottom left
1.0f, 1.0f, 0.0f, // top right
1.0f, -1.0f, 0.0f // bottom right
};
// Set up vertex data and buffers
GLuint VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
// Bind Vertex Array Object
glBindVertexArray(VAO);
// Bind and set vertex buffer(s)
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Configure vertex attributes
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// Create shader program
GLuint shaderProgram = createShaderProgram();
// Render loop
while (!glfwWindowShouldClose(window)) {
// Clear the screen
glClear(GL_COLOR_BUFFER_BIT);
// Use shader program and draw
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// Swap buffers and poll IO events
glfwSwapBuffers(window);
glfwPollEvents();
}
// Cleanup resources
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(shaderProgram);
// Terminate GLFW
glfwTerminate();
return 0;
}