2016-11-03 7 views
1

私はGPUにフレームをレンダリングするOpenGLを使ってプログラムを作っています。それをメモリに転送して、別のプログラムで使うことができます。ウィンドウやレンダリングの必要はないので、GLFWを使用していますが、ウィンドウとコンテキストを隠しています。 opengl-tutorial.comに続いて、テクスチャとレンダーバッファを持つFramebufferを設定して、テクスチャにレンダリングしてピクセルを読み取ることができます。チェックするだけで、ウィンドウを表示させることができ、テクスチャをクワッドの画面に戻し、パススルーシェーダを使用しています。テクスチャへのOpenGLレンダリングがギザギザに見える

私の問題は、直接(フレームバッファやテクスチャなしで)画面にレンダリングすると、画像が大きく滑らかに見えるということです。しかし、テクスチャにレンダリングしてテクスチャをスクリーンにレンダリングすると、ギザギザに見えます。私は問題がスクリーンにテクスチャをレンダリングするときではないと思います。なぜなら、私が読み込んだピクセルを.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; 

は、私はテクスチャにレンダリングコードです:

ドロー(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); 
} 

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

:テクスチャにシーンをレンダリングするとき

テクスチャをスクリーンにレンダリングするときに使用する頂点シェーダとフラグメントシェーダのコードを含めることができますが、テクスチャから直接ピクセルデータを読み込んでファイルに書き込む際に、ギザギザに見えますが、それが問題だと思う。あなたが私に含めたいものが他にもあるなら、教えてください!

テクスチャのレンダリングを行う際に隠れたスケーリングがある可能性がありますので、GL_NEARESTは見栄えが悪くなるかもしれないと思っていましたが、本当にピクセル(ピクセルとウィンドウの両方が同じサイズです)そこには問題はない?

+1

GPUドライバでマルチサンプリングが強制されていますか? – genpfault

+0

これらは、Nvidiaコントロールパネルの設定です。http://imgur.com/UYnAh8i – aspirino67

+0

Welp、おそらく[mcve]の時間です。 – genpfault

答えて

1

genpfaultとFrischer Heringによって指摘されているように、通常のテクスチャにレンダリングするとアンチエイリアスはありません。ただし、マルチサンプルテクスチャにレンダーすることができます。テクスチャには、要求する数のサンプルに関する情報が格納されます。これをスクリーンに描画するには、各ピクセルに1つの色を得るためにテクスチャをサンプリングする必要があります。これはglBlitFramebufferを呼び出すことで実行できます。 glBlitFramebufferにOpenGLの基準によれば:

SAMPLE_BUFFERSは、リードフレームバッファのためにゼロより大きいとSAMPLE_BUFFERSはドローフレームバッファがゼロであるため、ソース内の各画素位置に対応するサンプルは、前に単一のサンプルに変換されている場合宛先に書き込まれます。

これらの2つのリンクがあまりにも非常に有用だった:

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

また、私が代わりにマルチサンプリングの「ギザギザ」などの用語を検索するので、私は逃したstackoverflowの上、ここで、件名に多くの質問を見つけることができます:あなたの助けのためのP

おかげでたくさん!

関連する問題