OpenGL渲染到纹理看起来参差不齐

阿司匹林67

我正在使用OpenGL编写一个程序,以在GPU中渲染帧,然后将其传输到内存中,以便可以在其他程序中使用它们。我不需要窗口或渲染到屏幕,因此我正在使用GLFW,但具有隐藏的窗口和上下文。在opengl-tutorial.com之后,我设置了带有纹理和深度渲染缓冲区的帧缓冲区,以便可以渲染到纹理,然后读取其像素。只是为了检查事物,我可以使窗口可见,然后将纹理渲染回屏幕上的四边形并使用直通着色器。

我的问题是,当我直接渲染到屏幕(没有帧缓冲区或纹理)时,图像看起来非常平滑。但是,当我渲染到纹理然后再将纹理渲染到屏幕时,它看起来参差不齐。我不认为问题出在将纹理渲染到屏幕上时,因为我还将将读取的像素保存到.jpg中,并且该像素看上去也呈锯齿状。

窗口和纹理的大小均为512x512像素。

这是我设置帧缓冲区的代码:

FramebufferName = 0;
glGenFramebuffers(1, &FramebufferName);
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);

//GLuint renderedTexture;
glGenTextures(1, &renderedTexture);
glBindTexture(GL_TEXTURE_2D, renderedTexture);
glTexImage2D(GL_TEXTURE_2D, 0, textureFormat, textureWidth, textureHeight, 0, textureFormat, GL_UNSIGNED_BYTE, 0);

numBytes = textureWidth * textureHeight * 3; // RGB
pixels = new unsigned char[numBytes]; // allocate image data into RAM

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

//GLuint depthrenderbuffer;
glGenRenderbuffers(1, &depthrenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, textureWidth, textureHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthrenderbuffer);

glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderedTexture, 0);

DrawBuffers[0] = GL_COLOR_ATTACHMENT0;
glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers

if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
    std::cout << "Couldn't set up frame buffer" << std::endl;
}

g_quad_vertex_buffer_data.push_back(-1.0f);
g_quad_vertex_buffer_data.push_back(-1.0f);
g_quad_vertex_buffer_data.push_back(0.0f);

g_quad_vertex_buffer_data.push_back(1.0f);
g_quad_vertex_buffer_data.push_back(-1.0f);
g_quad_vertex_buffer_data.push_back(0.0f);

g_quad_vertex_buffer_data.push_back(-1.0f);
g_quad_vertex_buffer_data.push_back(1.0f);
g_quad_vertex_buffer_data.push_back(0.0f);

g_quad_vertex_buffer_data.push_back(-1.0f);
g_quad_vertex_buffer_data.push_back(1.0f);
g_quad_vertex_buffer_data.push_back(0.0f);

g_quad_vertex_buffer_data.push_back(1.0f);
g_quad_vertex_buffer_data.push_back(-1.0f);
g_quad_vertex_buffer_data.push_back(0.0f);

g_quad_vertex_buffer_data.push_back(1.0f);
g_quad_vertex_buffer_data.push_back(1.0f);
g_quad_vertex_buffer_data.push_back(0.0f);

//GLuint quad_vertexbuffer;
glGenBuffers(1, &quad_vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, g_quad_vertex_buffer_data.size() * sizeof(GLfloat), &g_quad_vertex_buffer_data[0], GL_STATIC_DRAW);

// PBOs
glGenBuffers(cantPBOs, pboIds);
for(int i = 0; i < cantPBOs; ++i) {
    glBindBuffer(GL_PIXEL_PACK_BUFFER, pboIds[i]);
    glBufferData(GL_PIXEL_PACK_BUFFER, numBytes, 0, GL_DYNAMIC_READ);
}
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

index = 0;
nextIndex = 0;

这是我渲染到纹理的代码:

glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
glViewport(0,0,textureWidth,textureHeight); // Render on the whole framebuffer, complete from the lower left corner to the upper right

// Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

for(int i = 0; i < geometriesToDraw.size(); ++i) {
    geometriesToDraw[i]->draw(program);
}

其中draw(ShaderProgram)是调用glDrawArrays的函数。这是我将纹理渲染到屏幕上的代码:

// Render to the screen
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Render on the whole framebuffer, complete from the lower left corner to the upper right
glViewport(0,0,textureWidth,textureHeight);

// Clear the screen
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shaderTexToScreen.getProgramID());

// Bind our texture in Texture Unit 0
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, renderedTexture);
// Set our "renderedTexture" sampler to user Texture Unit 0
glUniform1i(shaderTexToScreen.getUniformLocation("renderedTexture"), 0);

// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer);
glVertexAttribPointer(
    0,                  
    3,                  
    GL_FLOAT,           
    GL_FALSE,           
    0,                  
    (void*)0            
);

glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(0);

这是将场景直接渲染到屏幕时得到的:

直接的

这是将场景渲染为纹理时得到的:

质地

I can include the code for the vertex and fragment shaders used in rendering the texture to screen, but as I am reading the pixel data straight from the texture and writing it to a file and that still looks jagged, I don't think that is the problem. If there is anything else you want me to include, let me know!

I thought maybe it could be that there is some hidden scaling when doing the rendering to texture and so GL_NEAREST makes it look bad, but if it really is pixel to pixel (both windows and texture are the same size) there shouldn't be a problem there right?

aspirino67

As pointed out by genpfault and Frischer Hering, there is no antialiasing when rendering to a normal texture. However, you can render to a Multisample texture, which will hold information for as many samples as you request. To render this to screen you need to sample the texture to get one color for each pixel, which can be done by calling glBlitFramebuffer. According to the OpenGL reference on glBlitFramebuffer:

If SAMPLE_BUFFERS for the read framebuffer is greater than zero and SAMPLE_BUFFERS for the draw framebuffer is zero, the samples corresponding to each pixel location in the source are converted to a single sample before being written to the destination.

These two links were very helpful too:

http://www.learnopengl.com/#!Advanced-OpenGL/Anti-aliasing http://ake.in.th/2013/04/02/offscreening-and-multisampling-with-opengl/

这是我的解决方案,对象的创建:

/// FRAMEBUFFER MULTISAMPLE

framebufferMS = 0;
glGenFramebuffers(1, &framebufferMS);
glBindFramebuffer(GL_FRAMEBUFFER, framebufferMS);

glGenTextures(1, &renderedTextureMS);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, renderedTextureMS);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, SAMPLES, textureFormat, textureWidth, textureHeight, GL_TRUE);

glGenRenderbuffers(1, &depthrenderbufferMS);
glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbufferMS);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, SAMPLES, GL_DEPTH24_STENCIL8, textureWidth, textureHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthrenderbufferMS);

glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderedTextureMS, 0);
DrawBuffersMS[0] = GL_COLOR_ATTACHMENT0;
glDrawBuffers(1, DrawBuffersMS);

if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
    std::cout << "Couldn't set up frame buffer" << std::endl;
}

/// FRAMEBUFFER SIMPLE

framebuffer = 0;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

glGenTextures(1, &renderedTexture);
glBindTexture(GL_TEXTURE_2D, renderedTexture);
glTexImage2D(GL_TEXTURE_2D, 0, textureFormat, textureWidth, textureHeight, 0, textureFormat, GL_UNSIGNED_BYTE, 0);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderedTexture, 0);
DrawBuffers[0] = GL_COLOR_ATTACHMENT0;
glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers

if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
    std::cout << "Couldn't set up frame buffer" << std::endl;
}

以及渲染过程:

// Render to framebuffer multisample
glBindFramebuffer(GL_FRAMEBUFFER, framebufferMS);
glViewport(0,0,textureWidth,textureHeight);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

for(int i = 0; i < geometriesToDraw.size(); ++i) {
    geometriesToDraw[i]->draw(program);
}

// Sample to normal texture
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferMS);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
glBlitFramebuffer(0, 0, textureWidth, textureHeight, 0, 0, textureWidth, textureHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);

您还可以在此处找到关于stackoverflow的更多问题,我错过了这个问题,因为我搜索的是“锯齿状”之类的术语,而不是多重采样:P

非常感谢你的帮助!

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类常见问题

将密集的张量切成参差不齐的平面值

来自分类Dev

参差不齐的数组

来自分类Dev

使SVG路径像一条平滑的线,而不是参差不齐

来自分类Dev

OpenGL应用程序移植到Qt5后看起来很奇怪

来自分类Dev

如何使用文件助手库读取参差不齐的正确文件

来自分类Dev

在CSS中生成参差不齐的边缘

来自分类Dev

如何使用MIDASR包在MIDAS模型中使用参差不齐的边缘数据进行预测?

来自分类Dev

OpenGL:经Gamma校正的图像看起来不是线性的

来自分类Dev

Flexbox在Safari中仍然参差不齐,flex-wrap无法正常工作

来自分类Dev

将参差不齐的文件读入二维数组-打印-并查找列的平均值

来自分类Dev

广播和连接参差不齐的张量

来自分类Dev

PyTorch中“参差不齐的张量”的解决方法是什么?

来自分类Dev

在Tensorflow中循环参差不齐的张量

来自分类Dev

参差不齐的张量作为LSTM的输入

来自分类Dev

张量参差不齐的广播

来自分类Dev

Tensorflow参差不齐的张量中的蒙版值

来自分类Dev

PR和BatchedCI触发器的结果参差不齐

来自分类Dev

如何使yEd看起来更集成到Ubuntu中?

来自分类Dev

检查数组是否参差不齐

来自分类Dev

谷歌地图参差不齐

来自分类Dev

在OpenGL中渲染到纹理

来自分类Dev

Java简单参差不齐的数组查询

来自分类Dev

处理参差不齐的2 dArray

来自分类Dev

如何使用NPOI获得不参差不齐的右列

来自分类Dev

在画布上渲染灰色文本看起来很糟糕

来自分类Dev

将纹理应用于OpenGL中的多边形后,纹理看起来有点模糊

来自分类Dev

在Windows 7和8中的Firefox上使用CSS转换进行字体渲染看起来非常粗糙,参差不齐

来自分类Dev

Microsoft Edge 渲染看起来很糟糕

来自分类Dev

为什么使用Processing 绘制的圆圈如此参差不齐?

Related 相关文章

  1. 1

    将密集的张量切成参差不齐的平面值

  2. 2

    参差不齐的数组

  3. 3

    使SVG路径像一条平滑的线,而不是参差不齐

  4. 4

    OpenGL应用程序移植到Qt5后看起来很奇怪

  5. 5

    如何使用文件助手库读取参差不齐的正确文件

  6. 6

    在CSS中生成参差不齐的边缘

  7. 7

    如何使用MIDASR包在MIDAS模型中使用参差不齐的边缘数据进行预测?

  8. 8

    OpenGL:经Gamma校正的图像看起来不是线性的

  9. 9

    Flexbox在Safari中仍然参差不齐,flex-wrap无法正常工作

  10. 10

    将参差不齐的文件读入二维数组-打印-并查找列的平均值

  11. 11

    广播和连接参差不齐的张量

  12. 12

    PyTorch中“参差不齐的张量”的解决方法是什么?

  13. 13

    在Tensorflow中循环参差不齐的张量

  14. 14

    参差不齐的张量作为LSTM的输入

  15. 15

    张量参差不齐的广播

  16. 16

    Tensorflow参差不齐的张量中的蒙版值

  17. 17

    PR和BatchedCI触发器的结果参差不齐

  18. 18

    如何使yEd看起来更集成到Ubuntu中?

  19. 19

    检查数组是否参差不齐

  20. 20

    谷歌地图参差不齐

  21. 21

    在OpenGL中渲染到纹理

  22. 22

    Java简单参差不齐的数组查询

  23. 23

    处理参差不齐的2 dArray

  24. 24

    如何使用NPOI获得不参差不齐的右列

  25. 25

    在画布上渲染灰色文本看起来很糟糕

  26. 26

    将纹理应用于OpenGL中的多边形后,纹理看起来有点模糊

  27. 27

    在Windows 7和8中的Firefox上使用CSS转换进行字体渲染看起来非常粗糙,参差不齐

  28. 28

    Microsoft Edge 渲染看起来很糟糕

  29. 29

    为什么使用Processing 绘制的圆圈如此参差不齐?

热门标签

归档