2016-11-03 10 views
1

GPU에서 프레임을 렌더링하는 OpenGL을 사용하여 프로그램을 만들고 있는데,이 프로그램을 다른 프로그램에서 사용할 수 있도록 메모리로 전송합니다. 창이나 렌더링 화면이 필요하지 않으므로 GLFW를 사용하고 있지만 숨겨진 창과 컨텍스트가 있습니다. OpenGL-tutorial.com에 이어 텍스쳐와 렌더 버퍼로 Framebuffer를 설정 했으므로 텍스처에 렌더링 한 다음 픽셀을 읽을 수 있습니다. 그냥 창을 보이게 할 수있는 것들을 확인하기 위해 쿼드의 화면에서 텍스처를 다시 렌더링하고 패스 스루 쉐이더를 사용합니다.텍스처에 대한 OpenGL 렌더링이 들쭉날쭉하게 보입니다.

내 문제는 직접 (프레임 버퍼 또는 텍스처없이) 화면에 렌더링 할 때 이미지가 멋지고 매끄럽게 보입니다. 그러나 텍스처로 렌더링 한 다음 텍스처를 화면에 렌더링하면 들쭉날쭉 해 보입니다. .jpg로 읽은 픽셀을 저장하고 있기 때문에 화면에 텍스처를 렌더링 할 때 문제가 있다고 생각하지 않습니다. 너무 거친 것처럼 보입니다.

창과 텍스처 모두 512x512 픽셀입니다.

은 무승부 (ShaderProgram)를 호출하는 기능
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); 
} 

입니다 : 여기

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; 

내가 텍스처에 렌더링하는 코드입니다 : 여기

내가 프레임 버퍼를 설정하는 코드입니다 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); 

이 직접 화면에 장면을 렌더링 할 때 내가 무엇을 얻을 수 있습니다 :

direct

을 그리고 이것은 내가 무엇을 얻을

texture

,369 : 텍스처 장면을 렌더링 할 때

텍스쳐를 화면에 표현하는데 사용 된 버텍스와 프래그먼트 쉐이더에 대한 코드를 포함 할 수 있습니다.하지만 텍스쳐에서 바로 픽셀 데이터를 읽고 파일에 쓰는 것과 같이 들쭉날쭉하게 보입니다. 그게 문제라고 생각해. 내가 포함시키고 자하는 것이 있다면, 알려주세요!

텍스처에 렌더링을 할 때 숨겨진 스케일링이있을 수 있으므로 GL_NEAREST는보기가 안좋을 수 있습니다. 그러나 실제로 픽셀 대 픽셀 (두 윈도우와 텍스처가 같은 크기 임)이면 shouldn 바로 거기에 문제가되지 않습니까?

+1

GPU 드라이버에서 멀티 샘플링을 강제 설정합니까? – genpfault

+0

다음은 Nvidia 제어판의 설정입니다. http://imgur.com/UYnAh8i – aspirino67

+0

Welp, 그러면 [mcve] 시간입니다. – genpfault

답변

1

genpfault 및 Frischer Hering에 의해 지적 되었 듯이 일반적인 질감으로 렌더링 할 때는 앤티 앨리어싱이 없습니다. 그러나 멀티 샘플 텍스처로 렌더링 할 수 있습니다. 멀티 샘플 텍스처는 요청한만큼의 샘플에 대한 정보를 보유합니다. 이것을 스크린에 렌더링하려면 텍스처를 샘플링하여 각 픽셀마다 하나의 색상을 얻고 glBlitFramebuffer를 호출하여 수행 할 수 있어야합니다. glBlitFramebuffer에 OpenGL의 기준에 따르면

SAMPLE_BUFFERS는 판독 프레임 버퍼보다 ​​제로 SAMPLE_BUFFERS가 연신 프레임 버퍼가 제로를 들어, 소스의 각각의 픽셀 위치에 대응하는 샘플 전에 단일 샘플로 변환이면 목적지에 기록됩니다.

이 두 링크도 매우 도움이되었다 :

/// 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; 
} 

그리고 렌더링 프로세스 : 여기

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

는, 객체의 생성 내 솔루션입니다 :

// 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); 

또한 여기에 내가 놓친 유래의 주제에 대한 자세한 질문을 찾을 수 있기 때문에 대신 멀티 샘플링의 "톱니"같은 용어에 대한 I 검색 : P

도와 주셔서 감사합니다 많이!