【问题标题】:how a VBO position would change sampler2D value?VBO 位置如何改变 sampler2D 值?
【发布时间】:2021-10-26 17:02:21
【问题描述】:

我有时要弄清楚我的问题出在哪里,当我这样做时,我已经尝试了所有我想的...但我找不到解决方案,这个问题对我来说看起来很奇怪。

我已将我的问题归结为几乎完整的直接 opengl 代码,供您在这里帮助我。

这个想法是,我在“层”(帧缓冲区+纹理)中绘制一个带有白色纹理的四边形

然后我使用这个层作为纹理来绘制一个(相同的)四边形到窗口,

在每个绘制调用中使用相同的着色器。

问题是:

只要我的 VBO“位置”(顶点的前两个浮点数)范围从 -1 到 +1 ,我就会得到一个漂亮的全白帧,

std::vector<float> vertices = { 1,1, 1,1,   1,-1, 1,0,   -1,-1, 0,0,  -1,1, 0,1 };

但是但是当 VBO“位置”范围从 -1 到 0.5 时,我希望屏幕的 75% 是全白的,但我得到了一半屏幕,一半强度

std::vector<float> vertices = { .5,.5, 1,1,   .5,-1, 1,0,   -1,-1, 0,0,  -1,.5, 0,1 };

和结局 scenration VBO“位置范围从 0 到 -1,我希望四分之一的 swreen 是白色的,但我得到全黑

std::vector<float> vertices = { 0,0, 1,1,   0,-1, 1,0,   -1,-1, 0,0,  -1,0, 0,1 };

// create framebuffer to draw in
GLuint buffer,fb;
glGenTextures(1, &buffer);
glBindTexture(GL_TEXTURE_2D, buffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WIDTH, HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
glGenerateMipmap(GL_TEXTURE_2D);
glGenFramebuffers(1, &fb);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);

// create white texture
GLuint white;
unsigned char white_data[4] = {255,255,255,255};
glGenTextures(1, &white);
glBindTexture(GL_TEXTURE_2D, white);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, &white_data[0]);
glGenerateMipmap(GL_TEXTURE_2D);

// create Quad
GLuint vao, vertices_buffer,indices_buffer;
std::vector<float> vertices = { 1,1, 1,1,   1,-1, 1,0,   -1,-1, 0,0,  -1,1, 0,1 };
std::vector<int> indices = {0,1,3,1,2,3};
glGenBuffers(1, &vertices_buffer); glGenBuffers(1, &indices_buffer); glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vertices_buffer);
glBufferData(GL_ARRAY_BUFFER,  vertices.size()*sizeof(float) , &vertices[0], GL_DYNAMIC_DRAW );
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(int) , &indices[0], GL_DYNAMIC_DRAW );
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), (GLvoid *) (0 * sizeof(float)));
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), (GLvoid *) (2 * sizeof(float)));
glEnableVertexAttribArray(1);

渲染循环

glBindFramebuffer(GL_FRAMEBUFFER, fb);
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);

glBindTexture(GL_TEXTURE_2D, white);
shader.use();

glBindVertexArray(vao);
glDrawElements ( GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);

glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, buffer);
shader.use();

glBindVertexArray(vao);
glDrawElements ( GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);

着色器

#version 330 core

// VERTEX 
layout (location = 0) in vec2 position;
layout (location = 1) in vec2 texCoord;

out vec2 texcoord;

void main() {

    texcoord = texCoord;
    
    gl_Position = vec4(position,0,1);

}

// FRAGMENT
in vec2 texcoord;
out vec4 color;
uniform sampler2D tex;

void main() {

  color = texture(tex,texcoord);

}

【问题讨论】:

  • 白色纹理glTexImage2D的格式参数不应该是GL_RGBA吗?
  • 是否有默认的帧缓冲和fb一样的大小?
  • @BDL 很好的观察,它必须不是,但它可以,在我的情况下它不会改变任何事情&@Rabbid76,是的,他们会
  • 下一个猜测:你在帧缓冲纹理上设置了一个缩小过滤器,它需要一个 mipmap (GL_NEAREST_MIPMAP_LINEAR),但是你在渲染到 FBO 后没有重新生成 mipmap。下采样时,白色级别 0 的 mipmap 使用(静止的)黑色级别 1 的 mipmap 进行插值。尝试将buffer 纹理上的GL_TEXTURE_MIN_FILTER 更改为GL_LINEAR
  • 获胜者是:BDL!是的,就是这样.....该死的,虽然我开始把头转向openGL,但现在我记得我实际上把mimap部分放在地毯下一段时间^^

标签: c++ opengl glsl


【解决方案1】:

@BDL found the solution:

您在需要 mipmap (GL_NEAREST_MIPMAP_LINEAR) 的帧缓冲区纹理上设置了缩小过滤器,但在渲染到 FBO 后您不会重新生成 mipmap。下采样时,白色级别 0 的 mipmap 使用(静止的)黑色级别 1 的 mipmap 进行插值。尝试将buffer 纹理上的GL_TEXTURE_MIN_FILTER 更改为GL_LINEAR

https://www.khronos.org/opengl/wiki/Common_Mistakes#Creating_a_complete_texture

默认的 GL_TEXTURE_MIN_FILTER 状态是 GL_NEAREST_MIPMAP_LINEAR。由于 OpenGL 将默认的 GL_TEXTURE_MAX_LEVEL 定义为 1000,因此 OpenGL 将期望定义 mipmap 级别

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-16
    • 1970-01-01
    • 2017-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-22
    • 2019-03-31
    相关资源
    最近更新 更多