Rendering do mapy kostki

Zgodnie z ARB_geometry_shader4 możliwe jest renderowanie sceny na 6 powierzchniach mapy sześcianu za pomocą shadera geometrii i mapy sześcianu dołączonej do obiektu bufora ramki. W ten sposób chcę stworzyć mapę cienia. Jednak wydaje się, że istnieje konflikt, którego nie mogę rozwiązać: {]}

  1. mogę tylko dołączyć teksturę z gl_depth_component jako typem wewnętrznym do GL_DEPTH_ATTACHMENT_EXT.
  2. Tekstura głębi może być tylko 1D lub 2D.]}
  3. If I want aby dołączyć mapę sześcianu, wszystkie inne dołączone tekstury muszą być również mapami sześcianu.

Wygląda na to, że nie mogę użyć żadnego testu głębi, gdy chcę renderować mapę sześcianu. Albo co dokładnie mi umyka?

EDIT: wygląda na to, że nowsze sterowniki Nvidia (180.48) obsługują mapy kostki głębi.

Author: Maurice Gilden, 2009-01-20

1 answers

Ok, aby odpowiedzieć na kilka innych pytań tutaj:

Oczywiście możliwe jest użycie 6 FBO, po jednym dla każdej twarzy. Lub użyć jednego FBO i dołączyć każdą twarz przed rysowaniem do niego. W obu przypadkach twarz mapy sześcianu będzie traktowana jak każda inna Tekstura 2D i można jej używać razem z normalnymi teksturami 2D lub buforami Renderującymi. I prawdopodobnie nie ma dużej różnicy we wszystkich możliwych sposobach (jeśli sprzęt je obsługuje).

Jednak możliwe jest również narysowanie wszystkiego w jednym kroku a ponieważ byłem ciekaw, jak to się robi, zrobiłem kilka badań.

Aby stworzyć FBO ze wszystkimi powierzchniami mapy sześcianu dołączonej do jednego punktu załącznika użyłem tego kodu (napisanego w D):

// depth cube map
glGenTextures(1, &tDepthCubeMap);
glBindTexture(GL_TEXTURE_CUBE_MAP, tDepthCubeMap);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
for (uint face = 0; face < 6; face++) {
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_DEPTH_COMPONENT24,
        width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, null);
}

// color cube map
glGenTextures(1, &tColorCubeMap);
glBindTexture(GL_TEXTURE_CUBE_MAP, tColorCubeMap);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
for (uint face = 0; face < 6; face++) {
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA,
        width, height, 0, GL_RGBA, GL_FLOAT, null);
}

// framebuffer object
glGenFramebuffersEXT(1, &fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glFramebufferTextureARB(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, tDepthCubeMap, 0);
glFramebufferTextureARB(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, tColorCubeMap, 0);

glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);

if (!isValidFBO()) {
    glDeleteFramebuffersEXT(1, &fbo);
    fbo = 0;
}
  • jeśli chcesz mieć tylko mapę głębi, musisz zmienić glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT); na glDrawBuffer (GL_NONE); przed zatwierdzeniem (i przed rysowaniem do niej)
  • filtry MIN i MAG muszą być ustawione na coś ważnego (domyślnie GL_NEAREST_MIPMAP_LINEAR)
  • szerokość i wysokość wszystkich tekstur muszą być takie same

Do renderowania powierzchni mapy sześcianu potrzebny jest shader geometry. Poniższy shader pomija niektóre obroty, ale powinno być jasne, co robi. gl_Layer służy do kierowania prymitywnego do właściwej twarzy (0 = + X, 1 = - X,...).

#version 120
#extension GL_EXT_geometry_shader4 : enable

void main(void) {
    int i, layer;
    for (layer = 0; layer < 6; layer++) {
        gl_Layer = layer;
        for (i = 0; i < 3; i++) {
            gl_Position = gl_PositionIn[i];
            EmitVertex();
        }
        EndPrimitive();
    }
}
 11
Author: Maurice Gilden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-30 15:34:26