OpenGL 渲染到纹理
OpenGL Render to a texture
如何使用帧缓冲区对象渲染纹理并将该纹理用作我的着色器的输入。
我需要为可编程混合执行此操作。
我能够单独创建 FBO 和纹理,但无法渲染到该纹理并附加我的帧缓冲区对象。
我需要渲染到纹理,因为我想将此纹理传递到我的着色器,以便我能够编写我自己的可编程混合方程。
#include <glad/glad.h>
#include <GLFW\glfw3.h>
#include <iostream>
#include "shader.h"
#include "std_image.h"
using namespace std;
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
int main()
{
glfwInit();
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, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
cout << "Failed to create GLFW window" <<endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
cout << "Failed to initialize GLAD" <<endl;
return -1;
}
glViewport(0, 0, 800, 600);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
///////////////////////////////////////////////////////////////////////////////////
Shader ourShader("Shader.vs", "Shader.fs");
Shader ourShader2("Shader.vs", "Shader2.fs");
unsigned int FBO;
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
unsigned int attachment_index_color_texture = 0;
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachment_index_color_texture, GL_UNSIGNED_BYTE, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0); //unbind framebuffer
float vertices[] = {
// positions // colors // texture coords
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f // top left
};
unsigned int indices[] = {
0, 1, 3, // first triangle
1, 2, 3 // second triangle
};
float vertices2[] = {
// positions // colors // texture coords
0.75f, 0.75f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top right
0.75f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right
0.0f, 0.0f, 0.0f, 0.0f,1.0f, 0.0f, 0.0f, 0.0f, // bottom left
0.0f, 0.75f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
};
unsigned int indices2[] = {
0, 1, 2, // first triangle
0, 2, 3 // second triangle
};
unsigned int VBO[2],VAO[2],EBO[2];
glGenVertexArrays(2, VAO);
glGenBuffers(2, VBO);
glGenBuffers(2, EBO);
glBindVertexArray(VAO[0]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO[0]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
glBindVertexArray(0);
glBindVertexArray(VAO[1]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices2), indices2, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
while (!glfwWindowShouldClose(window))
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
ourShader.use();
glBindVertexArray(VAO[0]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
ourShader2.use();
glBindVertexArray(VAO[1]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
/*glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);*/
glfwTerminate();
return 0;
}
编辑 1:
我现在将我的纹理附加到 fbo,也在我的 texttrue 上渲染,如下所示:
while (!glfwWindowShouldClose(window))
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
ourShader.use();
glBindVertexArray(VAO[0]);
unsigned int FBO, color, depth;
glGenFramebuffers(1, &FBO);
glGenTextures(1, &color);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glBindTexture(GL_TEXTURE_2D, color);
glGenRenderbuffers(1, &depth);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
800, 600,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, color, 0);
GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
return false;
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glViewport(0, 0, 800, 600); // Render on the whole framebuffer, complete from the lower left corner to the upper right
glBindFramebuffer(GL_FRAMEBUFFER, 0);
ourShader2.use();
glBindVertexArray(VAO[1]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
剩下的一个问题是如何在我的着色器中传递纹理 "color"。
感谢帮助
编辑2:
我附上了我的全部代码,你能检查一下为什么我没有在屏幕上看到任何东西吗?
main.cpp:
#include <glad/glad.h>
#include <GLFW\glfw3.h>
#include <iostream>
#include "shader.h"
#include "std_image.h"
using namespace std;
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
int main()
{
glfwInit();
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, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
cout << "Failed to create GLFW window" <<endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
cout << "Failed to initialize GLAD" <<endl;
return -1;
}
glViewport(0, 0, 800, 600);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
///////////////////////////////////////////////////////////////////////////////////
Shader ourShader("Shader.vs", "Shader.fs");
Shader ourShader2("Shader.vs", "Shader2.fs");
//glBindFramebuffer(GL_FRAMEBUFFER, 0); //unbind framebuffer
float vertices[] = {
// positions // colors // texture coords
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f // top left
};
unsigned int indices[] = {
0, 1, 3, // first triangle
1, 2, 3 // second triangle
};
float vertices2[] = {
// positions // colors // texture coords
0.75f, 0.75f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top right
0.75f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right
0.0f, 0.0f, 0.0f, 0.0f,1.0f, 0.0f, 0.0f, 0.0f, // bottom left
0.0f, 0.75f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
};
unsigned int indices2[] = {
0, 1, 2, // first triangle
0, 2, 3 // second triangle
};
unsigned int VBO[2],VAO[2],EBO[2];
glGenVertexArrays(2, VAO);
glGenBuffers(2, VBO);
glGenBuffers(2, EBO);
glBindVertexArray(VAO[0]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO[0]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
glBindVertexArray(0);
glBindVertexArray(VAO[1]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices2), indices2, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
while (!glfwWindowShouldClose(window))
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
ourShader.use();
glBindVertexArray(VAO[0]);
unsigned int FBO, color, depth;
glGenFramebuffers(1, &FBO);
glGenTextures(1, &color);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glBindTexture(GL_TEXTURE_2D, color);
glGenRenderbuffers(1, &depth);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
800, 600,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, color, 0);
unsigned int decalTexLocation;
decalTexLocation = glGetUniformLocation(ourShader.ID, "DecalTex");
glUniform1i(decalTexLocation, 0);
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(GL_TEXTURE_2D, color);
GLenum DrawBuffers[2] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, &DrawBuffers[0]); // "1" is the size of DrawBuffers
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
return false;
glViewport(0, 0, 800, 600); // Render on the whole framebuffer, complete from the lower left corner to the upper right
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
ourShader2.use();
glBindVertexArray(VAO[1]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
/*glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);*/
glfwTerminate();
return 0;
}
片段着色器1:
#version 330 core
out vec4 FragColor;
in vec3 ourColor;
void main()
{
// vec4 dst = getCurrentColorAtOutputFragmentPosition();
FragColor = vec4(ourColor, 1.0);
}
片段着色器2:
#version 330 core
out vec4 FragColor;
uniform sampler2D DecalTex;
in vec3 ourColor;
void main()
{
vec2 coords = gl_TexCoord[0].xy;
vec3 normalColor = texture2D(DecalTex, coords).rgb; //original color
FragColor = vec4(normalColor.x,normalColor.y,normalColor.z, 1.0);
}
顶点着色器:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;
out vec3 ourColor;
out vec2 TexCoord;
void main()
{
gl_Position = vec4(aPos, 1.0);
ourColor = aColor;
TexCoord = aTexCoord;
}
编辑 3:
在下面的代码中,我正在渲染 2 个矩形,一个使用 FBO(帧缓冲区对象)的纹理,第二个在屏幕上。
我可以在屏幕上呈现两者。
我写了2个片段着色器和2个顶点着色器。
一对片段和顶点着色器用于纹理渲染,另一对用于屏幕渲染。
我的主文件:
#include <glad/glad.h>
#include <GLFW\glfw3.h>
#include <iostream>
#include "shader.h"
#include "std_image.h"
using namespace std;
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
int main()
{
glfwInit();
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, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
cout << "Failed to create GLFW window" <<endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
cout << "Failed to initialize GLAD" <<endl;
return -1;
}
glViewport(0, 0, 800, 600);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
///////////////////////////////////////////////////////////////////////////////////
Shader ourShader("Shader.vs", "Shader.fs");
Shader ourShader2("Shader2.vs", "Shader2.fs");
//glBindFramebuffer(GL_FRAMEBUFFER, 0); //unbind framebuffer
float vertices[] = {
// positions // colors // texture coords
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f // top left
};
unsigned int indices[] = {
0, 1, 3, // first triangle
1, 2, 3 // second triangle
};
float vertices2[] = {
// positions // colors // texture coords
1.0, 1.0, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top right
1.0, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right
0.0f, 0.0f, 0.0f, 0.0f,1.0f, 0.0f, 0.0f, 0.0f, // bottom left
0.0f, 1.0, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
};
unsigned int indices2[] = {
0, 1, 2, // first triangle
0, 2, 3 // second triangle
};
unsigned int VBO[2],VAO[2],EBO[2];
glGenVertexArrays(2, VAO);
glGenBuffers(2, VBO);
glGenBuffers(2, EBO);
glBindVertexArray(VAO[0]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO[0]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
glBindVertexArray(0);
glBindVertexArray(VAO[1]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices2), indices2, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
/*glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE)*/;
unsigned int color;
glGenTextures(1, &color);
glBindTexture(GL_TEXTURE_2D, color);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
800, 600,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
unsigned int FBO;
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
while (!glfwWindowShouldClose(window))
{
ourShader.use();
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(VAO[0]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
ourShader2.use();
int texturehandle = glGetUniformLocation(ourShader.ID, "DecalTex");
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, color);
glUniform1i(texturehandle, 0);
glBindVertexArray(VAO[1]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
Veretx 着色器 1:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;
out vec3 ourColor;
out vec2 TexCoord;
void main()
{
gl_Position = vec4(aPos, 1.0);
ourColor = aColor;
TexCoord = aTexCoord;
}
片段着色器 1
#version 330 core
out vec4 FragColor;
in vec3 ourColor;
void main()
{
// vec4 dst = getCurrentColorAtOutputFragmentPosition();
FragColor = vec4(ourColor, 1.0);
}
顶点着色器 2
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;
out vec3 ourColor;
out vec2 myUV;
void main()
{
gl_Position = vec4(aPos, 1.0);
ourColor = aColor;
myUV = vec2(aPos.x,aPos.y);
}
片段着色器 2
#version 330 core
out vec4 FragColor;
uniform sampler2D DecalTex;
in vec3 ourColor;
in vec2 UV;
void main()
{
vec2 outUV = vec2(0.26,0.26);
vec4 myFragColor = texture2D(DecalTex,outUV);
//vec4 myFragColor = texture2D(DecalTex,UV);
//FragColor = vec4(ourColor,1.0);
vec4 tempFragColor = vec4(ourColor, 1.0);
//FragColor = myFragColor;
FragColor = myFragColor + tempFragColor;
//FragColor = (1.0,1.0,1.0,1.0);//tempFragColor;
}
这里的问题是当我使用这条线时:
vec4 myFragColor = texture2D(DecalTex,UV);
我无法在 myFragColor 中获取任何值,因此出现正常渲染。
但是如果我改成
vec2 outUV = vec2(0.26,0.26);
vec4 myFragColor = texture2D(DecalTex,outUV);
我能够获取目标像素的值,因此根据我的需要完成渲染。
你能告诉我为什么我不能从:
vec4 myFragColor = texture2D(DecalTex,UV);
编辑 4
现在我可以访问我的目标像素,但只剩下 1 个问题:
第一个矩形坐标 (-0.5,-0.5) <-----> (0.5,0.5)
第二个矩形坐标 (0,0) <----> (1,1)
相交区域 (0,0) <----> (0.5,0.5) --------> 这应该是黄色(红色 + 绿色)
但是区域 (0.26,0.26) <--------> (0.74,0.74) ------> 这个是黄色的,很奇怪是什么原因..?
最新的片段着色器:
#version 330 core
out vec4 FragColor;
uniform sampler2D DecalTex;
in vec3 ourColor;
in vec2 myUV;
void main()
{
vec4 myFragColor = texture2D(DecalTex,myUV);
FragColor = vec4(ourColor,1.0);
vec4 tempFragColor = vec4(ourColor, 1.0);
FragColor = myFragColor + tempFragColor;
}
预期结果:
现在你的纹理应该有一个 ID "color",它已经被填充,这样你就可以绑定并将它传递给着色器了。
int texturehandle = glGetUniformLocation(program, "MaTextureInShader");
glActiveTexture(GLES20.GL_TEXTURE0);
glBindTexture(GLES20.GL_TEXTURE_2D, color);
glUniform1i(textureHandle, 0);
如果要存储在数组中
glBindTexture(GLES20.GL_TEXTURE_2D, color);
GL::glGetTexImage(GL::GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, myArray);
当你编译Fragment Shader 2时,你会得到这样的错误信息(取决于显卡驱动);
0(12) : error C7616: global variable gl_TexCoord
is removed after version 140
这意味着您不能将 gl_TexCoord
与 #version 330 core
结合使用。
您已经为顶点着色器中的纹理坐标定义了一个可变的 out
变量。
out vec2 myUV;
在片段着色器中定义对应的in
变量并使用,而不是gl_TexCoord
:
#version 330 core
out vec4 FragColor;
uniform sampler2D DecalTex;
in vec3 ourColor;
in vec2 myUV;
void main()
{
vec4 myFragColor = texture2D(DecalTex,myUV);
FragColor = myFragColor;
}
答案的扩展:
为了 link 着色器程序正确并使其正常工作,out
变量的名称必须与 in
变量的名称完全匹配。
这意味着在顶点着色器中名为 myUV
的纹理坐标的输出变量:
out vec2 myUV;
片段着色器中相应的输入变量也必须命名为myUV
:
in vec2 myUV;
我需要为可编程混合执行此操作。
我能够单独创建 FBO 和纹理,但无法渲染到该纹理并附加我的帧缓冲区对象。
我需要渲染到纹理,因为我想将此纹理传递到我的着色器,以便我能够编写我自己的可编程混合方程。
#include <glad/glad.h>
#include <GLFW\glfw3.h>
#include <iostream>
#include "shader.h"
#include "std_image.h"
using namespace std;
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
int main()
{
glfwInit();
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, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
cout << "Failed to create GLFW window" <<endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
cout << "Failed to initialize GLAD" <<endl;
return -1;
}
glViewport(0, 0, 800, 600);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
///////////////////////////////////////////////////////////////////////////////////
Shader ourShader("Shader.vs", "Shader.fs");
Shader ourShader2("Shader.vs", "Shader2.fs");
unsigned int FBO;
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
unsigned int attachment_index_color_texture = 0;
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachment_index_color_texture, GL_UNSIGNED_BYTE, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0); //unbind framebuffer
float vertices[] = {
// positions // colors // texture coords
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f // top left
};
unsigned int indices[] = {
0, 1, 3, // first triangle
1, 2, 3 // second triangle
};
float vertices2[] = {
// positions // colors // texture coords
0.75f, 0.75f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top right
0.75f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right
0.0f, 0.0f, 0.0f, 0.0f,1.0f, 0.0f, 0.0f, 0.0f, // bottom left
0.0f, 0.75f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
};
unsigned int indices2[] = {
0, 1, 2, // first triangle
0, 2, 3 // second triangle
};
unsigned int VBO[2],VAO[2],EBO[2];
glGenVertexArrays(2, VAO);
glGenBuffers(2, VBO);
glGenBuffers(2, EBO);
glBindVertexArray(VAO[0]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO[0]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
glBindVertexArray(0);
glBindVertexArray(VAO[1]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices2), indices2, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
while (!glfwWindowShouldClose(window))
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
ourShader.use();
glBindVertexArray(VAO[0]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
ourShader2.use();
glBindVertexArray(VAO[1]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
/*glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);*/
glfwTerminate();
return 0;
}
编辑 1:
我现在将我的纹理附加到 fbo,也在我的 texttrue 上渲染,如下所示:
while (!glfwWindowShouldClose(window))
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
ourShader.use();
glBindVertexArray(VAO[0]);
unsigned int FBO, color, depth;
glGenFramebuffers(1, &FBO);
glGenTextures(1, &color);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glBindTexture(GL_TEXTURE_2D, color);
glGenRenderbuffers(1, &depth);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
800, 600,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, color, 0);
GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
return false;
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glViewport(0, 0, 800, 600); // Render on the whole framebuffer, complete from the lower left corner to the upper right
glBindFramebuffer(GL_FRAMEBUFFER, 0);
ourShader2.use();
glBindVertexArray(VAO[1]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
剩下的一个问题是如何在我的着色器中传递纹理 "color"。
感谢帮助
编辑2:
我附上了我的全部代码,你能检查一下为什么我没有在屏幕上看到任何东西吗?
main.cpp:
#include <glad/glad.h>
#include <GLFW\glfw3.h>
#include <iostream>
#include "shader.h"
#include "std_image.h"
using namespace std;
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
int main()
{
glfwInit();
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, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
cout << "Failed to create GLFW window" <<endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
cout << "Failed to initialize GLAD" <<endl;
return -1;
}
glViewport(0, 0, 800, 600);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
///////////////////////////////////////////////////////////////////////////////////
Shader ourShader("Shader.vs", "Shader.fs");
Shader ourShader2("Shader.vs", "Shader2.fs");
//glBindFramebuffer(GL_FRAMEBUFFER, 0); //unbind framebuffer
float vertices[] = {
// positions // colors // texture coords
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f // top left
};
unsigned int indices[] = {
0, 1, 3, // first triangle
1, 2, 3 // second triangle
};
float vertices2[] = {
// positions // colors // texture coords
0.75f, 0.75f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top right
0.75f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right
0.0f, 0.0f, 0.0f, 0.0f,1.0f, 0.0f, 0.0f, 0.0f, // bottom left
0.0f, 0.75f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
};
unsigned int indices2[] = {
0, 1, 2, // first triangle
0, 2, 3 // second triangle
};
unsigned int VBO[2],VAO[2],EBO[2];
glGenVertexArrays(2, VAO);
glGenBuffers(2, VBO);
glGenBuffers(2, EBO);
glBindVertexArray(VAO[0]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO[0]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
glBindVertexArray(0);
glBindVertexArray(VAO[1]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices2), indices2, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
while (!glfwWindowShouldClose(window))
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
ourShader.use();
glBindVertexArray(VAO[0]);
unsigned int FBO, color, depth;
glGenFramebuffers(1, &FBO);
glGenTextures(1, &color);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glBindTexture(GL_TEXTURE_2D, color);
glGenRenderbuffers(1, &depth);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
800, 600,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, color, 0);
unsigned int decalTexLocation;
decalTexLocation = glGetUniformLocation(ourShader.ID, "DecalTex");
glUniform1i(decalTexLocation, 0);
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(GL_TEXTURE_2D, color);
GLenum DrawBuffers[2] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, &DrawBuffers[0]); // "1" is the size of DrawBuffers
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
return false;
glViewport(0, 0, 800, 600); // Render on the whole framebuffer, complete from the lower left corner to the upper right
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
ourShader2.use();
glBindVertexArray(VAO[1]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
/*glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);*/
glfwTerminate();
return 0;
}
片段着色器1:
#version 330 core
out vec4 FragColor;
in vec3 ourColor;
void main()
{
// vec4 dst = getCurrentColorAtOutputFragmentPosition();
FragColor = vec4(ourColor, 1.0);
}
片段着色器2:
#version 330 core
out vec4 FragColor;
uniform sampler2D DecalTex;
in vec3 ourColor;
void main()
{
vec2 coords = gl_TexCoord[0].xy;
vec3 normalColor = texture2D(DecalTex, coords).rgb; //original color
FragColor = vec4(normalColor.x,normalColor.y,normalColor.z, 1.0);
}
顶点着色器:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;
out vec3 ourColor;
out vec2 TexCoord;
void main()
{
gl_Position = vec4(aPos, 1.0);
ourColor = aColor;
TexCoord = aTexCoord;
}
编辑 3:
在下面的代码中,我正在渲染 2 个矩形,一个使用 FBO(帧缓冲区对象)的纹理,第二个在屏幕上。
我可以在屏幕上呈现两者。
我写了2个片段着色器和2个顶点着色器。
一对片段和顶点着色器用于纹理渲染,另一对用于屏幕渲染。
我的主文件:
#include <glad/glad.h>
#include <GLFW\glfw3.h>
#include <iostream>
#include "shader.h"
#include "std_image.h"
using namespace std;
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
int main()
{
glfwInit();
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, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
cout << "Failed to create GLFW window" <<endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
cout << "Failed to initialize GLAD" <<endl;
return -1;
}
glViewport(0, 0, 800, 600);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
///////////////////////////////////////////////////////////////////////////////////
Shader ourShader("Shader.vs", "Shader.fs");
Shader ourShader2("Shader2.vs", "Shader2.fs");
//glBindFramebuffer(GL_FRAMEBUFFER, 0); //unbind framebuffer
float vertices[] = {
// positions // colors // texture coords
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f // top left
};
unsigned int indices[] = {
0, 1, 3, // first triangle
1, 2, 3 // second triangle
};
float vertices2[] = {
// positions // colors // texture coords
1.0, 1.0, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top right
1.0, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right
0.0f, 0.0f, 0.0f, 0.0f,1.0f, 0.0f, 0.0f, 0.0f, // bottom left
0.0f, 1.0, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
};
unsigned int indices2[] = {
0, 1, 2, // first triangle
0, 2, 3 // second triangle
};
unsigned int VBO[2],VAO[2],EBO[2];
glGenVertexArrays(2, VAO);
glGenBuffers(2, VBO);
glGenBuffers(2, EBO);
glBindVertexArray(VAO[0]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO[0]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
glBindVertexArray(0);
glBindVertexArray(VAO[1]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices2), indices2, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
/*glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE)*/;
unsigned int color;
glGenTextures(1, &color);
glBindTexture(GL_TEXTURE_2D, color);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
800, 600,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
unsigned int FBO;
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
while (!glfwWindowShouldClose(window))
{
ourShader.use();
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(VAO[0]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
ourShader2.use();
int texturehandle = glGetUniformLocation(ourShader.ID, "DecalTex");
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, color);
glUniform1i(texturehandle, 0);
glBindVertexArray(VAO[1]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
Veretx 着色器 1:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;
out vec3 ourColor;
out vec2 TexCoord;
void main()
{
gl_Position = vec4(aPos, 1.0);
ourColor = aColor;
TexCoord = aTexCoord;
}
片段着色器 1
#version 330 core
out vec4 FragColor;
in vec3 ourColor;
void main()
{
// vec4 dst = getCurrentColorAtOutputFragmentPosition();
FragColor = vec4(ourColor, 1.0);
}
顶点着色器 2
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;
out vec3 ourColor;
out vec2 myUV;
void main()
{
gl_Position = vec4(aPos, 1.0);
ourColor = aColor;
myUV = vec2(aPos.x,aPos.y);
}
片段着色器 2
#version 330 core
out vec4 FragColor;
uniform sampler2D DecalTex;
in vec3 ourColor;
in vec2 UV;
void main()
{
vec2 outUV = vec2(0.26,0.26);
vec4 myFragColor = texture2D(DecalTex,outUV);
//vec4 myFragColor = texture2D(DecalTex,UV);
//FragColor = vec4(ourColor,1.0);
vec4 tempFragColor = vec4(ourColor, 1.0);
//FragColor = myFragColor;
FragColor = myFragColor + tempFragColor;
//FragColor = (1.0,1.0,1.0,1.0);//tempFragColor;
}
这里的问题是当我使用这条线时:
vec4 myFragColor = texture2D(DecalTex,UV);
我无法在 myFragColor 中获取任何值,因此出现正常渲染。
但是如果我改成
vec2 outUV = vec2(0.26,0.26);
vec4 myFragColor = texture2D(DecalTex,outUV);
我能够获取目标像素的值,因此根据我的需要完成渲染。
你能告诉我为什么我不能从:
vec4 myFragColor = texture2D(DecalTex,UV);
编辑 4
现在我可以访问我的目标像素,但只剩下 1 个问题:
第一个矩形坐标 (-0.5,-0.5) <-----> (0.5,0.5)
第二个矩形坐标 (0,0) <----> (1,1)
相交区域 (0,0) <----> (0.5,0.5) --------> 这应该是黄色(红色 + 绿色)
但是区域 (0.26,0.26) <--------> (0.74,0.74) ------> 这个是黄色的,很奇怪是什么原因..?
最新的片段着色器:
#version 330 core
out vec4 FragColor;
uniform sampler2D DecalTex;
in vec3 ourColor;
in vec2 myUV;
void main()
{
vec4 myFragColor = texture2D(DecalTex,myUV);
FragColor = vec4(ourColor,1.0);
vec4 tempFragColor = vec4(ourColor, 1.0);
FragColor = myFragColor + tempFragColor;
}
预期结果:
现在你的纹理应该有一个 ID "color",它已经被填充,这样你就可以绑定并将它传递给着色器了。
int texturehandle = glGetUniformLocation(program, "MaTextureInShader");
glActiveTexture(GLES20.GL_TEXTURE0);
glBindTexture(GLES20.GL_TEXTURE_2D, color);
glUniform1i(textureHandle, 0);
如果要存储在数组中
glBindTexture(GLES20.GL_TEXTURE_2D, color);
GL::glGetTexImage(GL::GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, myArray);
当你编译Fragment Shader 2时,你会得到这样的错误信息(取决于显卡驱动);
0(12) : error C7616: global variable
gl_TexCoord
is removed after version 140
这意味着您不能将 gl_TexCoord
与 #version 330 core
结合使用。
您已经为顶点着色器中的纹理坐标定义了一个可变的 out
变量。
out vec2 myUV;
在片段着色器中定义对应的in
变量并使用,而不是gl_TexCoord
:
#version 330 core
out vec4 FragColor;
uniform sampler2D DecalTex;
in vec3 ourColor;
in vec2 myUV;
void main()
{
vec4 myFragColor = texture2D(DecalTex,myUV);
FragColor = myFragColor;
}
答案的扩展:
为了 link 着色器程序正确并使其正常工作,out
变量的名称必须与 in
变量的名称完全匹配。
这意味着在顶点着色器中名为 myUV
的纹理坐标的输出变量:
out vec2 myUV;
片段着色器中相应的输入变量也必须命名为myUV
:
in vec2 myUV;