- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 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);
这是我将场景直接渲染到屏幕时得到的结果:
这就是我将场景渲染到纹理时得到的结果:
我可以包含用于将纹理渲染到屏幕的顶点和片段着色器的代码,但是当我直接从纹理读取像素数据并将其写入文件时仍然看起来参差不齐,我不这样做认为这是问题所在。如果您希望我包含任何其他内容,请告诉我!
我认为可能是在对纹理进行渲染时存在一些隐藏的缩放比例,因此 GL_NEAREST 使它看起来很糟糕,但如果它真的是像素到像素(窗口和纹理的大小相同),则不应该不会有问题吧?
最佳答案
正如 genpfault 和 Frischer Hering 所指出的,渲染到正常纹理时没有抗锯齿。但是,您可以渲染到多采样纹理,它将保存您请求的尽可能多的样本的信息。要将其渲染到屏幕上,您需要对纹理进行采样以获得每个像素的一种颜色,这可以通过调用 glBlitFramebuffer 来完成。根据 glBlitFramebuffer 上的 OpenGL 引用:
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.
这两个链接也很有帮助:
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
非常感谢您的帮助!
关于c++ - OpenGL 渲染到纹理看起来参差不齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40405614/
本学期我在计算机科学类(class)中遇到了一个挑战问题,这是上学期的复习题,但问题是:“给定一个参差不齐的数组,查找数组中是否有任何行的乘积为 48,如果是,则返回该行号。如果没有行包含 48 的乘
我正在尝试计算二维数组的按列求和。 对于这个二维数组: int[][] array = {{1,2,3,4},{5,6,7,8},{9,10,11,12}}; 我可以毫不费力地打印每列总和。 这是我的
我正在使用 Flash CS4,它具有绘制实线/虚线/虚线/参差不齐/点状线的功能。但是,我找不到用于绘制这些样式线的 API。 Graphics.lineStyle()不支持。如何以编程方式绘制样式
在 JavaScript 中,我有一个“线”列表,每一个都由不定数量的“点”组成,每个点的形式都是 [x, y] .所以它是一个 3D 参差不齐的数组。现在我需要在 emscripten ( embi
http://i.imgur.com/Uk1dc.jpg 这是我正在处理的网站上标题的一个小屏幕截图。我想使用谷歌网络字体 (quicksand),它在 firefox 中看起来很棒。然而,它看起来很
我是一名优秀的程序员,十分优秀!