2015-03-11 2 views
0

Я создаю тактическую RPG с использованием 2D-плитки с использованием OpenGL с использованием C++, и у меня возникают трудности с разбиением на фрагменты моих фрагментов/квадрациклов. Я хочу, чтобы можно было сказать, что текстурированный квадрат дерева, изображение из дерева с окружающим прозрачным альфа-слоем, поверх непрозрачного текстурированного квадрата. Мне нужно, чтобы дерево появилось поверх травы с травой, показывающей альфа-слой дерева.Наложение квадратов друг на друга в OpenGL

До сих пор я был в беспорядке с glDisable (GL_DEPTH_TEST), glEnable (GL_BLEND), andglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA), но пока не повезло. Я в конечном итоге с деревом на черном фоне, вместо травы. Может ли кто-нибудь указать мне в правильном направлении?

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

void View::initialize() { 
    updateProjection(window); 
    glDisable(GL_DEPTH_TEST); 
    glClearColor(0.0, 0.0, 0.0, 1.0); 
    camera = new Camera(Vector3(-1, -3, 25), Vector3(-1, -3, 0), Vector3(0, 1, 0)); 
    loadImages(); 
    initShaders(); 

    //needed for transparency? 
    glEnable(GL_BLEND); 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
} 

void View::render(World* worldTemp) 
{ 
    Matrix4 mvpMatrix, viewMatrix, modelMatrix; 
    Matrix4 XAxisRotationMatrix, YAxisRotationMatrix, ZAxisRotationMatrix; 

    input->handleInput(camera, worldTemp->getPlayer()); 

    worldTemp->timerTick(); 
    worldTemp->clearFog(); 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);   // Clear Screen and Depth Buffer 

    XAxisRotationMatrix = Matrix4::IDENTITY; 
    YAxisRotationMatrix = Matrix4::IDENTITY; 
    ZAxisRotationMatrix = Matrix4::IDENTITY; 
    XAxisRotationMatrix.rotate(Vector3(1.0, 0.0, 0.0), XAxisRotationAngle); 
    YAxisRotationMatrix.rotate(Vector3(0.0, 1.0, 0.0), YAxisRotationAngle); 
    ZAxisRotationMatrix.rotate(Vector3(0.0, 0.0, 1.0), ZAxisRotationAngle); 

    viewMatrix = camera->getViewMatrix(); 

    modelMatrix = translationMatrix(Vector3(-4, 2, 0)); 
    mvpMatrix = projectionMatrix * viewMatrix * modelMatrix; 

    //Spit out the map 
    for (int i = 0; i < 100; i++){ 
     for (int j = 0; j < 100; j++){ 
      for (int t = 0; t < 5; t++){ 
       if (worldTemp->getTile(i, j)->isOccupied() == true) { 
        if (worldTemp->getTile(i, j)->getOccupyingEntityIndexed(t)->getFog()){ 
        worldTemp->getTile(i, j)->getOccupyingEntityIndexed(t)->getEntityQuad()->render_self(mvpMatrix, true); 
        } 
        else{ 
        worldTemp->getTile(i, j)->getOccupyingEntityIndexed(t)->getEntityQuad()->render_self(mvpMatrix); 
        } 
       } 
      } 
     } 
    } 

    //Place the player 
    worldTemp->getPlayer()->getEntityQuad()->render_self(mvpMatrix); 
    renderEnemies(); 

    glutSwapBuffers(); //works with GL_DOUBLE. use glFlush(); instead, if using GL_SINGLE 
} 
+1

Вы уверены, что текстура вашего дерева фактически имеет альфа-компонент с правильной прозрачностью? И тогда деревья должны были быть последними. Мой ответ здесь объясняет различные варианты рендеринга прозрачности в деталях: http://stackoverflow.com/a/23283256/3530129. –

ответ

0

В принципе, в 2-х игровом слое выполняется путем заказа вызовов визуализации. Если вам нужен слой A поверх слоя B, вы должны сначала визуализировать слой B, а затем слой A.

Функция blend, которую вы используете, должна зависеть от формата текстур изображений. Есть два распространенных форматов для альфа:

  1. Предварительно умноженный альфа
  2. прямой альфа

    Более подробную информацию об этом: https://developer.nvidia.com/content/alpha-blending-pre-or-not-pre

opengl es2 premultiplied vs straight alpha + blending

glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPH А); для преувеличенной альфа, и он должен хорошо работать, если вы используете цвета как есть. glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); для прямой альфа.

Смежные вопросы