Установка цвета прозрачности на растровом изображении спрайта приводит к тому, что мои квадраты, не являющиеся спрайтами, исчезают!

Написание простой игры, помогающей изучить OpenGL. В текущей версии мой метод рендеринга рисует квадраты геометрии с определенными в коде цветами, а затем рендерит несколько спрайтов. Пока все нормально и работает как задумано. Мои спрайты имеют в качестве фона цвет Auqua, который я хотел сделать прозрачным, но еще не сделал этого. Так что на данный момент игра выглядит нормально, за исключением того факта, что все спрайты ограничены синим цветом. Я нахожусь в точке, где я хочу, чтобы синий цвет исчез и вместо этого был прозрачным, поэтому я изменяю свой метод OnLoad следующим образом:

...
Bitmap bitmap = new Bitmap("RockTexture.bmp"); // existing line
bitmap.MakeTransparent(Color.Aqua);  // new line
...  

Однако теперь, когда я запускаю игру, все квадраты геометрии исчезают с экрана! Мои спрайты остаются и выглядят достаточно прозрачными.

Я не уверен, почему это происходит. Вот мой метод рендеринга:

    protected override void OnRenderFrame(FrameEventArgs e)
    {
        base.OnRenderFrame(e);

        GL.Clear(ClearBufferMask.ColorBufferBit);

        GL.Begin(BeginMode.Quads);
        Color prevColor = default(Color);

        foreach (var quad in _view.GeomitryList)
        {

            if (prevColor != quad.Color)
            {
                GL.Color4(quad.Color);
                prevColor = quad.Color;
            }


            GL.Vertex2(quad.UpperLeftBound.X, quad.UpperLeftBound.Y);
            GL.Vertex2(quad.LowerRightBound.X, quad.UpperLeftBound.Y);
            GL.Vertex2(quad.LowerRightBound.X, quad.LowerRightBound.Y);
            GL.Vertex2(quad.UpperLeftBound.X, quad.LowerRightBound.Y);


        }


        GL.Color4(_unitColor); // reset color multiplier to not scew textures
        prevColor = _unitColor;

        GL.BindTexture(TextureTarget.Texture2D, _rockTextureId);

        foreach (var sprite in _view.SpriteList)
        {
            float ulX = sprite.UpperLeftBound.X;
            float ulY = sprite.UpperLeftBound.Y;
            float lrX = sprite.LowerRightBound.X;
            float lrY = sprite.LowerRightBound.Y;

            GL.TexCoord2(0, 0); GL.Vertex2(ulX, ulY);
            GL.TexCoord2(1, 0); GL.Vertex2(lrX, ulY);
            GL.TexCoord2(1, 1); GL.Vertex2(lrX, lrY);
            GL.TexCoord2(0, 1); GL.Vertex2(ulX, lrY);
        }

        RenderDashboard(ref prevColor);


        GL.End();

        GL.Flush();
        SwapBuffers();
    }

person Dejas    schedule 12.04.2011    source источник
comment
Почему вы используете этот грубый метод цветовой манипуляции? Просто используйте какой-нибудь формат файла, который поддерживает альфа-канал.   -  person datenwolf    schedule 12.04.2011
comment
@datenwolf Я получаю такое же поведение при использовании .png с альфа-компонентом (даже при исключении вызова make Transparent)   -  person Dejas    schedule 12.04.2011


Ответы (1)


Предположим, вы устанавливаете альфа-канал в своей функции MakeTransparent, вам также необходимо включить смешивание:

защищенное переопределение недействительным OnRenderFrame (FrameEventArgs e) { base.OnRenderFrame (e);

    GL.Clear(ClearBufferMask.ColorBufferBit);

    GL.Begin(BeginMode.Quads);
    Color prevColor = default(Color);

    foreach (var quad in _view.GeomitryList)
    {

        if (prevColor != quad.Color)
        {
            GL.Color4(quad.Color);
            prevColor = quad.Color;
        }


        GL.Vertex2(quad.UpperLeftBound.X, quad.UpperLeftBound.Y);
        GL.Vertex2(quad.LowerRightBound.X, quad.UpperLeftBound.Y);
        GL.Vertex2(quad.LowerRightBound.X, quad.LowerRightBound.Y);
        GL.Vertex2(quad.UpperLeftBound.X, quad.LowerRightBound.Y);


    }

ввв

    GL.Enable(GL_BLEND);

^^^

    GL.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    GL.Color4(_unitColor); // reset color multiplier to not scew textures
    prevColor = _unitColor;

    GL.BindTexture(TextureTarget.Texture2D, _rockTextureId);

    foreach (var sprite in _view.SpriteList)
    {
        float ulX = sprite.UpperLeftBound.X;
        float ulY = sprite.UpperLeftBound.Y;
        float lrX = sprite.LowerRightBound.X;
        float lrY = sprite.LowerRightBound.Y;

        GL.TexCoord2(0, 0); GL.Vertex2(ulX, ulY);
        GL.TexCoord2(1, 0); GL.Vertex2(lrX, ulY);
        GL.TexCoord2(1, 1); GL.Vertex2(lrX, lrY);
        GL.TexCoord2(0, 1); GL.Vertex2(ulX, lrY);
    }

    GL.End(); // I think this should go here.

    GL.Disable(GL_BLEND); // enable and disable on a as-needed base

    RenderDashboard(ref prevColor);


    GL.Flush();
    SwapBuffers();

BTW: вы используете здесь немедленные вызовы режима (glBegin(...), glVertex(...), glEnd()), вы должны отказаться от них и вместо этого использовать массивы вершин и объекты буфера вершин. Немедленный режим устарел, больше не доступен в OpenGL-3 и более поздних версиях вне профиля совместимости.

person datenwolf    schedule 12.04.2011
comment
Спасибо за совет. К сожалению, добавление этих строк не изменило поведение программы. :( У вас есть еще предложения? Спасибо. - person Dejas; 12.04.2011
comment
@Dejas: можешь опубликовать скриншот? - person datenwolf; 12.04.2011