Текстуры Skybox прозрачны - PullRequest
       63

Текстуры Skybox прозрачны

0 голосов
/ 09 апреля 2020

Мой скайбокс отображается, но не отображает текстуры, которые я загружаю из изображения. Вместо этого он показывает прозрачный цвет, если я установил glTexImage2D как GL_RGBA, или черный цвет, если я установил glTexImage2D как GL_RGB.

Я использую рендер с поддержкой MultisampledFbo .

Мой код загрузки текстуры выглядит следующим образом:

private int loadSkyboxTextures(){
         glGenBuffers(vbo);
         glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
         glBufferData(GL_ARRAY_BUFFER, POINTS, GL_STATIC_DRAW);
         glBindBuffer (GL_ARRAY_BUFFER, 0);
         glGenVertexArrays(vao);
         glBindVertexArray(vao[0]);
         glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
         glVertexPointer(3, GL_FLOAT, 3 * Float.BYTES, NULL);
         glTexCoordPointer (3, GL_FLOAT, 3 * Float.BYTES, NULL);        
         glBindBuffer (GL_ARRAY_BUFFER, 0);
         glEnableClientState(GL_VERTEX_ARRAY);
         glEnableClientState(GL_TEXTURE_COORD_ARRAY);

        int texID = glGenTextures();
        glBindTexture(GL_TEXTURE_CUBE_MAP, texID);
        for(int i = 0; i < TEXTURE_FILES.length; i++){
            InputStream file = getClass().getResourceAsStream(TEXTURE_FILES[i]);
            byte[] pixelData = new byte[0];
            try {
                pixelData = new byte[file.available()];
                file.read(pixelData);
            } catch (IOException e) {
                e.printStackTrace();
            }
            ByteBuffer byteBuffer = ByteBuffer.wrap(pixelData);
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, 512, 512, 0,
                    GL_RGB, GL_UNSIGNED_BYTE, byteBuffer);
        }

        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

        return texID;
    }

Код рендеринга куба:

    private void drawSkybox(){
        glColor4f(1,1,1,1);
        glDepthMask(false);
        glEnable(GL_TEXTURE_CUBE_MAP);
        glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
        glBindVertexArray(vao[0]);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_CUBE_MAP, texId);
        glDrawArrays(GL_TRIANGLES, 0, 36);
        glBindVertexArray(0);
        glBindBuffer (GL_ARRAY_BUFFER, 0);
        glDepthMask(true);
        glDisable(GL_TEXTURE_CUBE_MAP);
    }

Вызов рендеринга куба в основной функции рендеринга:

                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                view = viewX || viewY || viewZ;
                if(view)
                    glPushMatrix();

                int rot = 180;

                glDisable(GL_LIGHTING);
                glViewport(0, 0, WIDTH, HEIGHT);
                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                glOrtho(-max, max, -1, 1, 10, -10);
                glRotated(cameraX, 1f, 0f, 0);
                glRotated(cameraY, 0f, 1f, 0);
                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();
                drawSkybox(texId);

                glViewport(0, 0, WIDTH, HEIGHT);
                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                ...
                //render camera and other objects

1 Ответ

1 голос
/ 09 апреля 2020

Для текстур карты куба координаты текстуры являются трехмерными и обрабатываются как вектор, образующий центр карты куба.
Поскольку вы рисуете куб, который центрирован вокруг (0, 0, 0), вы также можно использовать координаты вершины для координат текстуры. Вы не используете шейдерную программу, поэтому вы должны использовать фиксированные атрибуты функции. Укажите координаты вершины glVertexPointer, а координаты текстуры - glTexCoordPointer. Включите возможность на стороне клиента (glEnableClientState) GL_VERTEX_ARRAY и GL_TEXTURE_COORD_ARRAY.

Укажите Vertex Array Object . Этого кода достаточно выполнить один раз при инициализации:

glGenBuffers(vbo);
glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, POINTS, GL_STATIC_DRAW);
glBindBuffer (GL_ARRAY_BUFFER, 0);

glGenVertexArrays(vao);
glBindVertexArray(vao[0]);

glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
glVertexPointer(3, GL_FLOAT, false, 3 * Float.BYTES, NULL);
glTexCoordPointer (3, GL_FLOAT, false, 3 * Float.BYTES, NULL);
glBindBuffer (GL_ARRAY_BUFFER, 0);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glBindVertexArray(0);

При рисовании скайбокса достаточно привязать текстуру кубической карты, чтобы включить текстурирование куба и связать VAO:

private void drawSkybox(){
    GL11.glColor4f(1,1,1,1);
    glDepthMask(false);        

    glEnable(GL_TEXTURE_CUBE_MAP);
    glBindTexture(GL_TEXTURE_CUBE_MAP, texID);

    glBindVertexArray(vao[0]);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glBindVertexArray(0);

    glDepthMask(true);
    glDisable(GL_TEXTURE_CUBE_MAP);
}

Есть еще некоторые проблемы:

...