Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Мультимедия, OpenGL/DirectX > Наложение текстур в -чернота вместо прозрачности


Автор: grecd 12.2.2014, 09:54
Загружаю текстуру при помощи ImageMagic++ как показано в этом туторе http://ogldev.atspace.co.uk/www/tutorial16/tutorial16.html

Код

Texture::Texture(GLenum TextureTarget, const std::string& FileName)
{
    m_textureTarget = TextureTarget;
    m_fileName      = FileName;
    m_pImage        = NULL;
}

bool Texture::Load()
{
    try {
        m_pImage = new Magick::Image(m_fileName);
        m_pImage->write(&m_blob, "RGBA");
    }
    catch (Magick::Error& Error) {
        std::cout << "Error loading texture '" << m_fileName << "': " << Error.what() << std::endl;
        return false;
    }

    glGenTextures(1, &m_textureObj);
    glBindTexture(m_textureTarget, m_textureObj);
    glTexImage2D(m_textureTarget, 0, GL_RGB, m_pImage->columns(), m_pImage->rows(), 0, GL_RGBA, GL_UNSIGNED_BYTE, m_blob.data());
    glTexParameterf(m_textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(m_textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    Width =(int) m_pImage->xResolution();
    Height =(int) m_pImage->yResolution();
    return true;
}

void Texture::Bind(GLenum TextureUnit)
{
    glActiveTexture(TextureUnit);
    glBindTexture(m_textureTarget, m_textureObj);
}

void Texture::render()
{
if (m_textureObj != 0)
    {
        glEnable(GL_TEXTURE_2D);
        glPushMatrix();
        //glColor4f(1, 1, 0, 1);
        glBindTexture(GL_TEXTURE_2D, m_textureObj);
        glBegin(GL_QUADS);
        glTexCoord2i(0, 0);
        glVertex2i(0, 0);
        glTexCoord2i(1, 0);
        glVertex2i(Width, 0);
        glTexCoord2i(1, 1);
        glVertex2i(Width, Height);
        glTexCoord2i(0, 1);
        glVertex2i(0, Height);
        glEnd();
        glPopMatrix();
        glDisable(GL_TEXTURE_2D);
        GLenum err;
        while ((err = glGetError()) != GL_NO_ERROR)
        {
            std::cerr << "OpenGL error: " << err << std::endl;
        }
        //SDL_GL_SwapWindow(win);
    }
}



далее рендер сцены, почему то после загрузки текстуры сцена становится черной и при отрисовке "флагов" на фоне другой текстуры там где должно быть прозрачно там чернота


Код


    // white background
    glColor4f(1, 1, 1, 1);
    glBegin(GL_QUADS);
    glVertex3f(0,0,0);
    glVertex3f(getWidth(),0,0);
    glVertex3f(getWidth(),getHeight(),0);
    glVertex3f(0,getHeight(),0);
    glEnd();

   // render loaded image
        glEnable(GL_DEPTH_TEST);
        glColor4f(1, 1, 1, 1);


       glEnable (GL_BLEND);
      glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
       glEnable     (GL_COLOR_MATERIAL);

        showflags = true;
        if (showflags)
        {
        //render flags
        glEnable(GL_TEXTURE_2D);
        for(int i=0;i<DrawnFlagsNum;i++)
        {
            glPushMatrix();
            glTranslated(DrawnFlags[i].x,DrawnFlags[i].y,0);
            switch(DrawnFlags[i].t)
            {
            case blue: blueflag->render();break;
            case yellow: yellowflag->render();break;
            case green: greenflag->render();break;
            }
            glPopMatrix();
        }
     glDisable(GL_TEXTURE_2D);
        }
    glColor4f(1, 1, 1, 1);
    glDisable(GL_BLEND);
        if (VideoTexture != 0)
        {
            glEnable(GL_TEXTURE_2D);
            glPushMatrix();
            glBindTexture(GL_TEXTURE_2D, VideoTexture);
            glBegin(GL_QUADS);
            glTexCoord2i(0, 0); glVertex2i(0, 0);
            glTexCoord2i(1, 0); glVertex2i(Width, 0);
            glTexCoord2i(1, 1); glVertex2i(Width, Height);
            glTexCoord2i(0, 1); glVertex2i(0, Height);
            glEnd();
            glPopMatrix();
            glDisable(GL_TEXTURE_2D);
        }



    //renderFirstFrame();
    glFlush();
    SwapBuffers();

Автор: tzirechnoy 12.2.2014, 15:37
Вообще, понять что-нибудь по некомпилирующемуся отрывку довольно сложно -- особенно учитывая, как важны в OpenGL всякие глобальные флаги. Но, как минимум:

Цитата
при отрисовке "флагов" на фоне другой текстуры там где должно быть прозрачно там чернота


В текстурах GL_RGB нет никакой прозрачности.

Автор: grecd 13.2.2014, 09:31
Цитата(tzirechnoy @ 12.2.2014,  15:37)
Вообще, понять что-нибудь по некомпилирующемуся отрывку довольно сложно -- особенно учитывая, как важны в OpenGL всякие глобальные флаги. Но, как минимум:

Цитата
при отрисовке "флагов" на фоне другой текстуры там где должно быть прозрачно там чернота


В текстурах GL_RGB нет никакой прозрачности.

поменял на GL_RGBA все равно чернота вместо прозрачности
Может мне проект линуксовый сюда скинуть?

Автор: tzirechnoy 13.2.2014, 15:01
Цитата
Может мне проект линуксовый сюда скинуть?


Возможно. Или вырежьте из него минимальный пример, демонстрирующий непонимание. Это вообще будет полезнее -- можэт, выпока будете вырещать сами разберётесь.

Автор: grecd 16.2.2014, 16:45
Вот файл с проектом codeblocks.
Методика отслеживания глюка -> FIle->Open file - открыть видео файл, появится его первый кадр. Затем нажать флажок и щёлкнуть на картинке.

Автор: tzirechnoy 17.2.2014, 09:08
1) Собирать пока лень, потому не тэстировал. И не понимаю, что такое "сцэна чёрная". Можэт, вечером.
2) Из очевидного: такой вид прозрачности требует, чтобы примитивы выдавались в Z-буфер от далёких к близким. У Вас кажэтся ровно наоборот -- сначала близкий флаг, затем непрозрачная далёкая видеотекстура.
Учитывая, что тут практически 2D -- просто попробуйте поменять местами. Если будет минимальное 3D -- то на пяти примитивах проще всего будет отсортировать их вручную.

Если с сортровкой совсем сложно -- можно попробовать что-то такое http://www.openglsuperbible.com/2013/08/20/is-order-independent-transparency-really-necessary/

Автор: grecd 17.2.2014, 17:39
Цитата(tzirechnoy @  17.2.2014,  09:08 Найти цитируемый пост)
"сцэна чёрная"

// white background нерисуется после загрузки текстур
Цитата(tzirechnoy @  17.2.2014,  09:08 Найти цитируемый пост)
просто попробуйте поменять местами

текстура VideoTexture рисуется поверх всего тогда непойму почему

Автор: tzirechnoy 17.2.2014, 19:21
Цитата
текстура VideoTexture рисуется поверх всего тогда непойму почему


А, тут ещё одна ошыбка и одна нестыковка, которых я с первого раза не заметил.
(я пока не скомпилировал, потому так, из анализа).

Во-первых, Вы пытаетесь всё сделать через двумерные координаты. Ну, в смысле, у Вас у всех примитивов Z-координата -- 0.

Это, в общем, можно, но вот DEPTH_TEST при этом можэт быть применять немного муторно и странно в связи с тем, что Z-буфер вроде как рассчитан как раз на наличие вменяемой третьей координаты (глубины). В частности, вопрос о том, как реально расположатся друг относительно друга два прямоугольника в одной плоскости с учётом ошыбок округления при проецыровании -- он, во многих случаях, решаемый, но требует отдельной проработки.

Так что если действительно зачем-то потребуется DEPTH_TEST -- то, возможно, надо будет отказаться от двумерности. Или заполнить глубины какими-то правильными значениями не из координат. Можэт, впрочем, для трёх прямоугольников с Idenitity transformation matrix ничего и не потребуется -- но и DEPTH_TEST тогда откровенно лишний, и только привносит тормозов и ошыбок.

А ошыбка -- в том, что Вы нигде не вызываете prepare3DViewport. В примерах от wxWindows он вызывается вручную изнутри ::render.
Соответственно, glDepthFunc у Вас остаётся GL_LESS, что означает, что из перекрывающихся частей двух примитивов в одной плоскости нарисуется только первый, второй по большэй части провалит DEPTH_TEST (насчёт меньшэй части -- см.про ошыбки округления). Соответственно, Вашу текстуру с альфой никто рисовать и не подумает.


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)