OpenGL'de bir renderbuffer'dan doku mı alıyorsunuz?


13

Bir FBO'da bir renderbuffer'ım var (DepthStencil) ve ondan bir doku almam gerekiyor. FBO'da hem DepthComponent dokusu hem de DepthStencil renderbuffer'a sahip olamıyorum, öyle görünüyor ki, daha sonra boru hattında daha sonra kullanmak için işlendikten sonra renderbuffer'ı bir DepthComponent dokusuna dönüştürmek için bir yol gerekiyor.

Haftalarca renderbuffer'dan derinlik bileşenini almak için birçok teknik denedim ama her zaman önemsiz çıkıyorum. Sonunda tek istediğim, bir renderbuffer kullanmasaydım bir FBO'dan alacağım aynı doku. Herkes bu görünüşte basit operasyonu kapsayan bazı kapsamlı talimatlar veya kod gönderebilir mi?

DÜZENLE:

Http://dl.dropbox.com/u/9279501/fbo.cs kodunun çıkarma sürümüne bağlantı

Alan etkili + FBO Derinliği ait Screeny - derinliği olmadan (!) Http://i.stack.imgur.com/Hj9Oe.jpg

Alan Derinliği Etkisi Olmayan Ekran + FBO - Derinlik iyi çalışıyor http://i.stack.imgur.com/boOm1.jpg

Yanıtlar:


2

Alternatif olarak, yalnızca bir FBO'dan diğerine renderbuffer tabanlı olandan doku tabanlı olana kadar yapıştırabilirsiniz. Bunu şu şekilde yaparım:

glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_renderBufferSurface->m_fbo);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_textureSurface->m_fbo);
glBlitFramebufferEXT(0, 0, m_renderBufferSurface->m_width, m_renderBufferSurface->m_height, 0, 0, m_textureSurface->m_width, m_textureSurface->m_height, GL_COLOR_BUFFER_BIT, GL_NEAREST);

(Derinlik arabelleği yapmak istediğiniz durumda, GL_COLOR_BUFFER_BIT yerine GL_DEPTH_BUFFER_BIT kullanabilirsiniz)

Doku tabanlı renderbuffer'a blide ettikten sonra, dokuyu normal olarak kullanabilirsiniz; bir üniforma veya istediğiniz gibi gölgelendiricilere geçirme.


1

Hayır, bu mümkün değil. En fazla verileri CPU'ya glReadPixels yapabilir ve bir doku oluşturabilirsiniz, ancak bu hantal ve yavaş olacaktır. Renderbuffers bunun için tasarlanmamıştır, bu işlevsellik sadece dokular tarafından sağlanır.


Buna göre, alternatif nedir? Çizim tamponunuzda derinliği nasıl koruyabilir ve ayrıca derinlik bileşenini bir doku olarak nasıl elde edebilirsiniz?
Rushyo

@Rushyo: Bir alternatif, şablon tamponundan kurtulmak (mümkünse!) Ve derinlik oluşturucuyu bir derinlik dokusu yapmak olabilir. Neden şablon kullanıyorsunuz?
Calvin1602

Temelde ne zaman derinlik dokusu elde edersem, derinlik testleri kırılır. FBO'ma bir derinlik eki eklersem, FBO başka bir yerde herhangi bir derinlik bilgisi yazmaz - bu yüzden renk ekini almaya çalıştığımda üzerinde derinlik testi yoktur (normalde bir derinlik eki yoksa ). Yukarıda bahsi geçen 'hantal ve yavaş' yöntemi de dahil olmak üzere aklıma gelen her kombinasyonu denedim. Ne yaparsam yapayım, sahnemin bir dokuda 'tipik' bir görüntüsünü, diğerinde ise sadece derinliği elde edemiyorum.
Rushyo

@ Calvin1602 Ben renderbuffer ile dabbling zaman, şablon eki olmadan derinlik eki kullanarak istenmeyen sonuçlar ürettiğini buldum.
Rushyo

@Rushyo Eminim, dokuyu doğru bir şekilde kurmuyorsunuz, posta kodu bize yardım etmemizi sağlayacaktır :)
Matias Valdenegro

1

Sorduğunuz şey OpenGL 3.2'de mümkündür. FBO'mun dağınık rengi bir renk dokusuna, normalleri başka bir renk dokusuna ve derinliği bir derinlik dokusuna tükürdüm - renderbuffer'a gerek yok. Aslında renderbuffers sadece bir sorundur, çünkü onlardan örnekleme yapamazsınız, bu nedenle glReadPixels(...)sadece GPU belleğindeki her şeyi korumak yerine verileri RBO'dan ve CPU üzerindeki bir dokuya kullanmanız veya bir şekilde kopyalamanız gerekir. Yani...

Gerçekten istiyorsanız, FBO'nuzdaki ayrı bir renk dokusu ekine manuel olarak derinlik gibi şeyler çıktısı almak için ilk geçiş gölgelendiricinize kod yazabilirsiniz. Yani tarafından kullanılmak üzere olurdu size Sonradan geçiren shader içinde. İçin OpenGL'ın iç derinlik-testinde kullanılmak, fazladan ya da fbo en GL_DEPTH_ATTACHMENT gibi bir RBO veya doku seti gerekir. Ancak her ikisine de hizmet etmek için tek bir doku ayarlayabilirsiniz - bu daha verimli ve kullanımı daha kolaydır.

Derinlik dokusu kurulum kodum şöyle görünüyor (Java, ByteBuffer öğelerini görmezden gel ...

        gBufferDepthTexture = new Texture();
        gBufferDepthTexture.id = glGenTextures();
        gBufferDepthTexture.unit = 2;
        gBufferDepthTexture.width = Display.getWidth();
        gBufferDepthTexture.height = Display.getHeight();
        gBufferDepthTexture.bytes = ByteBuffer.allocateDirect(Display.getWidth()*Display.getHeight() * 4);
        glActiveTexture(gBufferDepthTexture.unit + GL_TEXTURE0); //eg. 0 + 33984 = GL_TEXTURE0, while 31 + 33984 = GL_TEXTURE31.
        glBindTexture(GL_TEXTURE_2D, gBufferDepthTexture.id);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, gBufferDepthTexture.width, gBufferDepthTexture.height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, gBufferDepthTexture.bytes);
        //...GL_UNSIGNED_INT or GL_UNSIGNED_BYTE may work better for you, instead... YMMV.

        //glPixelStorei(GL_PACK_ALIGNMENT, 4);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

Ve sonra:

        glBindFrameBuffer(GL_DRAW_FRAMEBUFFER, fbo.id);
        //your existing glFramebufferTexture2D(...) calls here
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, gBufferDepthTexture.id, 0);

Artık gBufferDepthTextureikinci, üçüncü geçiş parçalı gölgelendiricilerinize üniforma olarak geçebilirsiniz (veya neye sahip olduğunuzu). Şablon arabelleği ile tam olarak aynı şeyi yapabileceğinizi güvenli bir şekilde varsayabiliriz.


0

GL_DEPTH_STENCIL biçimini kullanarak bir doku (RenderBuffer yerine) oluşturabilmelisiniz. Bir gölgelendirici programında (FBO'ları kullandığınız için kullandığınızı varsayıyorum) böyle bir dokudan derinliği kullanmak için tam bir işlem olduğundan emin değilim, ancak OpenGL spec hangi renk kanallarının hangi değerleri alacağını belirtmelidir ( tahminim R, G ve B'nin derinliğe, A'nın da şablona ayarlanmış olması).

Bugünlerde OpenGL 3.2'yi hedefliyorum, bu nedenle doku formatının sizin için uygulanabilir olduğunu doğrulamanız gerekebilir. Hangi sürümlerin farklı özellikler getirdiğini asla hatırlayamıyorum.


Bu durumda sorun GL_DEPTH_STENCIL bileşenini bir dokuda yakalamıyor, ancak bunu yaptığınızda FBO'da tüm derinlik bilgilerinin kaybolması gerçeği. FBO, sahneyi çizim arabelleğine dönüştürmek için işe yaramaz hale gelir. Bu yüzden bu sorunu atlamak umuduyla bir Renderbuffer kullanıyordum. Şimdilik bir seçeneğim yok, derinliği kapmak için iki geçiş yapmaktan + ayrı ayrı bilgi çizmek = (cehennem kadar pahalı bir yol bulana kadar)
Rushyo

@Rushyo Bu eski soruya bir cevap gönderdim :) Muhtemelen bu yıllar önce çözmüş olsanız da, bir göz atmak isteyebilirsiniz.
Mühendis

@NickWiggill Keşke! Bir şeyleri dolandırdı ve hayatımla devam etti. Bu prototipte kullandığım varlıkları yeniden oluşturana kadar cevabınızı gerçekten test edemiyorum. Bir noktada
oraya gelebilir
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.