我需要一个着色程序,然后我需要一个着色程序。一旦我从我的着色器中获得COLOR_ATTACHMENT0
和COLOR_ATTACHMENT1
后,是否可以将它们作为采样器发送到着色器中,以便在屏幕上渲染到四元体上?
我需要将颜色附件发送到第二个着色器的原因是,我正在不同的监视器上渲染COLOR\u ATTACHMENT0
和COLOR\u ATTACHMENT1
COLOR_ATTACHMENT0
将出现在一个屏幕上,而COLOR_ATTACHMENT1
将出现在另一个屏幕上。。。
我正在做测试视力的心理实验。我的第一个着色器处理我的原始纹理集,但由于两个输出纹理所需的大部分处理是相同的,所以如果不需要,我基本上不想运行着色器两次。
我用的是GLFW,GLEW和GLM。因此,使用这些库的任何解决方案都是理想的
const GLchar* vertexSource =
"#version 150 core\n"
"in vec2 position;"
"in vec2 texcoord;"
"out vec2 Texcoord;"
"void main() {"
" Texcoord = texcoord;"
" gl_Position = vec4(position, 0.0, 1.0);"
"}";
const GLchar* fragmentSource =
"#version 150 core\n"
"in vec2 Texcoord;"
"out vec4 outColor0;"
"out vec4 outColor1;"
"uniform sampler2D texLite;"
"uniform sampler2D texDark;"
"void main() {"
" outColor0 = texture(texLite, Texcoord);"
" outColor1 = texture(texDark, Texcoord);"
"}";
const GLchar* vertexSourceDisp =
"#version 150 core\n"
"in vec2 position;"
"in vec2 texcoord;"
"out vec2 Texcoord;"
"void main() {"
" Texcoord = texcoord;"
" gl_Position = vec4(position, 0.0, 1.0);"
"}";
const GLchar* fragmentSourceDisp =
"#version 150 core\n"
"in vec2 Texcoord;"
"out vec4 outColor;"
"uniform sampler2D tex;"
"void main() {"
" outColor = texture(tex, Texcoord);"
"}";
当我运行glFrameBufferTexture 2D
时,它会将纹理图像附加到帧缓冲区,因此当着色器运行时,我的着色器输出的vec4是否存储回纹理以及颜色附件中?
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <iostream>
#include <stdio.h>
// Simple through-put vertex shader
const GLchar* vertexSource =
"#version 150 core\n"
"in vec2 position;"
"in vec2 texcoord;"
"out vec2 Texcoord;"
"void main() {"
" Texcoord = texcoord;"
" gl_Position = vec4(position, 0.0, 1.0);"
"}";
// Basic fragment shader for the moment
const GLchar* fragmentSource =
"#version 150 core\n"
"in vec2 Texcoord;"
"out vec4 outColor0;"
"out vec4 outColor1;"
"uniform sampler2D texLite;"
"uniform sampler2D texDark;"
"void main() {"
" vec4 colLena = texture(texLite, Texcoord);"
" vec4 colTex7 = texture(texDark, Texcoord);"
" outColor0 = mix(colLena, colTex7, 0.0);"
" outColor1 = mix(colLena, colTex7, 1.0);"
"}";
const GLchar* vertexSourceDisp =
"#version 150 core\n"
"in vec2 position;"
"in vec2 texcoord;"
"out vec2 Texcoord;"
"void main() {"
" Texcoord = texcoord;"
" gl_Position = vec4(position, 0.0, 1.0);"
"}";
const GLchar* fragmentSourceDisp =
"#version 150 core\n"
"in vec2 Texcoord;"
"out vec4 outColor;"
"uniform sampler2D tex;"
"void main() {"
" outColor = texture(tex, Texcoord);"
"}";
void printShaderInfoLog(GLuint obj)
{
int infologLength = 0;
int charsWritten = 0;
char *infoLog;
glGetShaderiv(obj, GL_INFO_LOG_LENGTH,&infologLength);
if (infologLength > 0)
{
infoLog = (char *)malloc(infologLength);
glGetShaderInfoLog(obj, infologLength, &charsWritten, infoLog);
printf("%s\n",infoLog);
free(infoLog);
}
}
void printProgramInfoLog(GLuint obj)
{
int infologLength = 0;
int charsWritten = 0;
char *infoLog;
glGetProgramiv(obj, GL_INFO_LOG_LENGTH,&infologLength);
if (infologLength > 0)
{
infoLog = (char *)malloc(infologLength);
glGetProgramInfoLog(obj, infologLength, &charsWritten, infoLog);
printf("%s\n",infoLog);
free(infoLog);
}
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
int main()
{
if (glfwInit() != GL_TRUE)
{
fprintf(stderr, "Failed to initialize GLFW\n");
return -1;
}
int count;
GLFWmonitor** monitors = glfwGetMonitors(&count);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* window0;
GLFWwindow* window1;
window0 = glfwCreateWindow(1680, 1050, "OpenGL", monitors[2], window1); // Front Screen
window1 = glfwCreateWindow(1280, 800, "OpenGL", monitors[1], window0); // Back Screen
glfwMakeContextCurrent(window0);
glfwSetKeyCallback(window0, key_callback);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
fprintf(stderr, "Failed to initialize GLEW\n");
return -1;
}
// Vertex array object - Contains all vertex information
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Vertex buffer object
GLuint vbo;
glGenBuffers(1, &vbo);
// Vertices to use inside my shader
GLfloat vertices[] = {
-1.0f, 1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 1.0f, 0.0f,
1.0f, -1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 1.0f
};
// Attached vertices to my GPU
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Element buffer object - allows me to reuse vertices
GLuint ebo;
glGenBuffers(1, &ebo);
// Index into the rows of vertices to use different vertices more than once
GLuint elements[] = {
0, 1, 2,
2, 3, 0
};
// Attach element array to use on GPU
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
// Set up shader
// Vertex Shader
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexSource, NULL);
glCompileShader(vertexShader);
printShaderInfoLog(vertexShader);
// Fragment shader
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);
printShaderInfoLog(fragmentShader);
// Shader program
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glBindFragDataLocation(shaderProgram, 0, "outColor0");
glBindFragDataLocation(shaderProgram, 1, "outColor1");
printProgramInfoLog(shaderProgram);
glLinkProgram(shaderProgram);
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), 0);
GLint texAttrib = glGetAttribLocation(shaderProgram, "texcoord");
glEnableVertexAttribArray(texAttrib);
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE,
4*sizeof(float), (void*)(2*sizeof(float)));
cv::VideoCapture cap("movie.mov");
cv::Mat image0;
cv::Mat image1;
int width = cap.get(CV_CAP_PROP_FRAME_WIDTH);
int height = cap.get(CV_CAP_PROP_FRAME_HEIGHT);
// float ratio = width/(float)height;
//Set up samplers
GLuint ldrTextures[2];
glGenTextures(2, ldrTextures);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, ldrTextures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
GL_BGR, GL_UNSIGNED_BYTE, NULL);
glUniform1i(glGetUniformLocation(shaderProgram, "texLite"), 0);
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);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, ldrTextures[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
GL_BGR, GL_UNSIGNED_BYTE, NULL);
glUniform1i(glGetUniformLocation(shaderProgram, "texDark"), 1);
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);
//Set up framebuffer
GLuint frameBuffer;
glGenFramebuffers(1, &frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
//Set up target textures
GLuint dispTextures[2];
glGenTextures(2, dispTextures);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, dispTextures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
GL_BGR, GL_UNSIGNED_BYTE, NULL);
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);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dispTextures[0], 0);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, dispTextures[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
GL_BGR, GL_UNSIGNED_BYTE, NULL);
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);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, dispTextures[1], 0);
GLenum bufs[2] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
glDrawBuffers(2, bufs);
bool success;
//Render loop
while(!glfwWindowShouldClose(window0) && !glfwWindowShouldClose(window1))
{
std::cout << "Loop" << std::endl;
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// glClear(GL_COLOR_BUFFER_BIT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Grab two frames from video
success = cap.read(image0);
if(!success)
{
std::cout << "Could not grab a frame" << std::endl;
exit(0);
}
success = cap.read(image1);
if(!success)
{
std::cout << "Could not grab a frame" << std::endl;
exit(0);
}
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, ldrTextures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
GL_BGR, GL_UNSIGNED_BYTE, image0.data);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, ldrTextures[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
GL_BGR, GL_UNSIGNED_BYTE, image1.data);
glfwMakeContextCurrent(window0);
glfwSetKeyCallback(window0, key_callback);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shaderProgram);
// glViewport(0,0,width,height);
// glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glActiveTexture(GL_TEXTURE2);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
glActiveTexture(GL_TEXTURE3);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, 0, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glfwMakeContextCurrent(window0);
glfwSetKeyCallback(window0, key_callback);
glViewport(0,0,width,height);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, dispTextures[0]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window0);
glfwPollEvents();
glfwMakeContextCurrent(window1);
glfwSetKeyCallback(window1, key_callback);
glViewport(0,0,width,height);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, dispTextures[1]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window1);
glfwPollEvents();
}
//Clean up memory, remember good coding practices
glDeleteTextures(1, ldrTextures);
glDeleteTextures(1, dispTextures);
glDeleteFramebuffers(1, &frameBuffer);
glDeleteProgram(shaderProgram);
glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);
glDeleteBuffers(1, &ebo);
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
glfwTerminate();
}
示例代码仅显示正在编译和链接的单个GLSL着色器程序。这里应该有两个不同的程序,一个用于第一遍,另一个用于第二遍(缺少)。
一旦你解决了这个问题,你就需要相应地设置采样器。根据你第一个窗口的代码(window0
)判断,它将使用采样器tex
=2。第二个窗口(window1
)将使用tex
=3。现在,如果您了解OpenGL中的每个渲染上下文都有自己的状态机,这实际上是完全没有必要的(换句话说,纹理绑定状态不会在您的两个窗口之间共享)。您可以在两个渲染上下文中将每个窗口使用的纹理绑定到2,然后不必将tex
采样器统一的值设置为2以外的任何值。
这里需要做的,也是真正困扰我的是,您试图使用一个渲染上下文的输出作为另一个渲染上下文的输入,而不进行同步。OpenGL中的渲染上下文是不同步的,不能保证在window0
中执行的第一步命令在window1
尝试读取其输出图像时完成。最简单的解决方法是在从window0
切换到window1
之前添加对glFinish()
的调用,这将导致OpenGL阻塞,直到所有这些命令完成。这不是最有效的解决方案(Geofence同步会更好),但它是最简单的。
我希望在2D OpenGL应用程序上实现着色器。我的计划是将场景渲染到帧缓冲区对象,然后使用着色器将该帧缓冲区对象渲染到屏幕。 这是我绘制到帧缓冲区对象的场景,然后从那里绘制到屏幕。使用箭头键可以让月亮四处移动(我很自豪!) 但是,当我尝试使用着色器程序将帧缓冲区对象渲染到屏幕上时,我得到以下结果: 这是非常可悲的。这个片段着色器是我从一个教程中得到的,我相信问题一定是统一变量。 以下是片段着色器
在一个简单的hello world OpenGL程序中,它只是在窗口上绘制一个静态三角形,当我将三角形的3个顶点设置为红色、绿色和蓝色时,三角形将填充渐变。 但是当我使用这样的着色器时: 顶点着色器: 其中属性和来自顶点缓冲区,通过的调用传递。 片段着色器: 三角形仍然充满了梯度,问题来了: 如果顶点着色器是按顶点计算的,则应为的每个实例指定顶点的颜色。顶点颜色应为红色、绿色或蓝色,如顶点缓冲区中
我创建了一个FBO,并有一个纹理绑定作为其颜色附件,我有多个着色器程序,对纹理做一些后处理,一切都很好,但它对我来说没有意义,纹理可以用作输入(sampler2D)以及同时着色器的输出。 以下是我采取的步骤: 创建一个FBO。 创建一个纹理,并将其绑定为的颜色附件。 调用将绑定到帧缓冲区目标。 调用使用着色器程序。 调用来绘制一些东西(最终在上绘制,因为当前绑定)。 调用使用shader程序,它在
假设我遇到这样的问题:现在我有一个帧缓冲区,一个纹理只包含一个颜色组件(例如,GL_RED)已经绑定到它。碎片着色器会是什么样子?我想答案是: ...浮出ex_color; 颜色=。。。; 我的问题来了:着色器会自动检测帧缓冲区的格式并向其写入值吗?如果片段着色器输出浮点值但帧缓冲区格式GL_RGBA怎么办? 顺便问一下,创建只有一个组件的纹理的正确方法是什么?我阅读了g-truc的示例,其示例如
WebGL的着色器代码分为顶点着色器代码和片元着色器代码两部分,顶点着色器代码会在GPU的顶点着色器单元执行,片元着色器代码会在GPU的片元着色器单元执行,在WebGL渲染管线流程中,或者说GPU的渲染流程中,顶点着色器代码先执行处理顶点,得到一系列片元,然后再执行片元着色器代码处理片元。 main()函数 顶点着色器和片元着色器代码都有一个唯一的主函数main(),attribute、varyi
片段着色器调用每个需要渲染的像素。我们将开发一个红色透镜,它将会增加图片的红色通道的值。 配置场景(Setting up the scene) 首先我们配置我们的场景,在区域中央使用一个网格显示我们的源图片(source image)。 import QtQuick 2.0 Rectangle { width: 480; height: 240 color: '#1e1e1e'