这是我的第一个OpenGL程序。我已经在WebGL中写了几乎相同的东西,它能起作用。我正在将其翻译为OpenGL。但是,我在许多地方都使用了示例代码,我不知道一切是否有意义。显然有什么错误我无法弄清楚,导致输出接近但仍然不同。
我正在创建一个2x2纹理,用数据{1.0,2.0,3.0,4.0}填充它,并使用一个简单的着色器将其复制到相同大小的输出纹理。得到的是: 结果:[1,2,0,4,]
下面,我还要粘贴代码和着色器脚本。感谢您对此进行审核。
顶点着色器:
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoord;
out vec2 TexCoord;
void main()
{
gl_Position = vec4(position, 1.0f);
TexCoord = texCoord;
}
碎片着色器:
#version 330 core
precision highp float;
in vec2 TexCoord;
out vec4 TexelValue;
// Texture samplers
uniform sampler2D A;
void main()
{
TexelValue = vec4(texture(A, TexCoord).r);
}
已删除错误检查的代码:
// Window dimensions
const GLuint WIDTH = 800, HEIGHT = 600;
void createTexture(GLuint texture, int width, int height, GLint internalFormat, GLenum format, GLenum type, const void *data)
{
glBindTexture(GL_TEXTURE_2D, texture);
// Set our texture parameters
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_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// set texenv to replace instead of the default modulate
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, data);
}
void uploadAndBindGeometry(const void* vertices, int verticesByteLength)
{
GLuint VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, verticesByteLength, vertices, GL_STATIC_DRAW);
// Position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid *)0);
glEnableVertexAttribArray(0);
// Texture Coordinate attribute
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid *)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
}
void bindInputTexture(int index, GLuint texture, GLint location)
{
glActiveTexture(GL_TEXTURE0 + index);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(location, index);
}
void initFBO(GLuint *fb, int width, int height) {
glGenFramebuffersEXT(1, fb);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, *fb);
glViewport(0, 0, width, height);
}
// The MAIN function, from here we start the application and run the game loop
int main()
{
glfwInit();
GLuint fb;
// Set all the required options for GLFW
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
// Create a GLFWwindow object that we can use for GLFW's functions
GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr);
int screenWidth, screenHeight;
glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
glfwMakeContextCurrent(window);
// Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions
glewExperimental = GL_TRUE;
glewGetExtension("GL_ARB_texture_float");
glewGetExtension("GL_EXT_framebuffer_object");
glewGetExtension("GL_ARB_color_buffer_float");
glDisable(GL_BLEND);
glDisable(GL_ALPHA);
glDisable(GL_DEPTH);
glDisable(GL_STENCIL);
// Build and compile our shader program
Shader ourShader("core.vs", "core.frag");
// Set up vertex data (and buffer(s)) and attribute pointers
GLfloat vertices[] =
{
// Positions // Texture Coords
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // Top Right
1.0f, -1.0f, 0.0f, 1.0f, 0.0f, // Bottom Right
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // Bottom Left
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f // Top Left
};
uploadAndBindGeometry(vertices, sizeof(vertices));
// Load and create textures
float adata[] = { 1.0,2.0,3.0,4.0 };
int adims[] = { 2, 2 };
int cdims[] = { 2, 2 };
float cdata[2 * 2] = { 0 };
// ===================
// Texture
// ===================
GLuint texture[2];
glGenTextures(2, &texture[0]);
createTexture(texture[0], adims[1], adims[0], GL_R32F, GL_RED, GL_FLOAT, (void*)adata);
createTexture(texture[1], cdims[1], cdims[0], GL_R32F, GL_RED, GL_FLOAT, (void*)NULL);
// Draw the triangle
ourShader.Use();
initFBO(&fb, cdims[1], cdims[0]);
glBindTexture(GL_TEXTURE_2D, texture[1]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[1], 0);
int locationA = glGetUniformLocation(ourShader.Program, "A");
bindInputTexture(0, texture[0], locationA);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glFlush();
// read output
glReadBuffer(GL_COLOR_ATTACHMENT0);
glReadPixels(0, 0, cdims[1], cdims[0], GL_RED, GL_FLOAT, cdata);
std::cout << "Result: [";
for (int i = 0; i < 2 * 2; ++i)
{
std::cout << cdata[i] << ",";
}
std::cout << "]" << std::endl;
// Terminate GLFW, clearing any resources allocated by GLFW.
glfwTerminate();
return EXIT_SUCCESS;
}