OpenGL импорт PNG темнее - PullRequest
       40

OpenGL импорт PNG темнее

0 голосов
/ 05 декабря 2018

Я делаю игру в OpenGL для проекта.Я попытался импортировать PNG, а затем использую функцию glEnable2D, чтобы рисовать графический интерфейс поверх своей 3D-игры.функция

void glEnable2D()
{
    int vPort[4];

    glGetIntegerv(GL_VIEWPORT, vPort);

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();

    glOrtho(0, vPort[2], 0, vPort[3], -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();

}

И это работает.Затем у меня есть вторая функция, которая используется для возврата в трехмерную среду.Затем у меня есть эта функция, которая рисует квад с текстурой и рисует его на экране (читая также альфа) * ​​1004 *

void drawImage(GLuint file, float x, float y, float w, float h, float angle)
{
//    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
//    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND_SRC);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glPushMatrix();
    glTranslatef(x, y, 0.0);
    glRotatef(angle, 0.0, 0.0, 1.0);

    glBindTexture(GL_TEXTURE_2D, file);


    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0); glVertex3f(x, y, 0.0f);
    glTexCoord2f(0.0, 1.0); glVertex3f(x, y + h, 0.0f);
    glTexCoord2f(1.0, 1.0); glVertex3f(x + w, y + h, 0.0f);
    glTexCoord2f(1.0, 0.0); glVertex3f(x + w, y, 0.0f);
    glEnd();

    glFlush();
    glPopMatrix();
}

Если я запускаю функцию, странное поведение.Он работает с альфа-каналом, но сохраняет затемненные изображения до тех пор, пока они находятся ближе к нижнему правому углу enter image description here

Если я не прокомментирую строку, которая задает glTextEnvF, он на самом деле подсвечиваетвсе правильно, но Альфы больше не читает.Как сделать так, чтобы функция считывала также альфа-канал, не применяя странное освещение?

1 Ответ

0 голосов
/ 06 декабря 2018

Обратите внимание, что рисование последовательностями glBegin / glEnd, стек матрицы конвейеров с фиксированными функциями и конвейер с фиксированными функциями для каждой модели освещения вершин не рекомендуется с десятилетий.Прочитайте о конвейере с фиксированными функциями и посмотрите Спецификация вершин и Шейдер для современного способа рендеринга.


В любом случае,проблема в том, что в вашем графическом интерфейсе нет правильного освещения.У вас есть 2 варианта, либо вы отключите свет (glDisable(GL_LIGHTING)), прежде чем рисовать графический интерфейс.Или убедитесь, что свет освещает графический интерфейс пользователя.

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

Но этого недостаточно, вы также должны убедиться, что элемент GUI отражает свет.Наиболее важным для отражения света является нормальный вектор поверхности, поскольку стандартная модель освещения OpenGL Blinn-Phong рассчитывается следующим образом:

Ka ... ambient material
Kd ... difusse material
Ks ... specular material

La ... ambient light
Ld ... diffuse light
Ls ... specular light
sh ... shininess

N  ... norlmal vector 
L  ... light vector (from the vertex position to the light) 
V  ... view vector (from the vertex position to the eye)

Id    = max(dot(N, L), 0.0);

H     = normalize(V + L);
NdotH = max(dot(N, H), 0.0);
Is    = (sh + 2.0) * pow(NdotH, sh) / (2.0 * 3.14159265);

fs    = Ka*La + Id*Kd*Ld + Is*Ks*Ls;

Вы не установилилюбые нормальные векторы вообще.Поскольку OpenGL является механизмом состояний, вектор нормалей, который вы установили последним с помощью glNormal, все еще действует.Если координата вершины установлена ​​как glVertex, тогда этот вектор нормали связан с.Это может привести к произвольным результатам.

Поскольку геометрия графического интерфейса рисуется в плоскости xy области просмотра, а ось z области просмотра направлена ​​за пределы области просмотра (в Правосторонней системе координат), Я рекомендую определить вектор нормали, который направлен на ось z:

glBegin(GL_QUADS);

glNormal3f(0.0, 0.0, 1.0);

glTexCoord2f(0.0, 0.0); glVertex3f(x, y, 0.0f);
glTexCoord2f(0.0, 1.0); glVertex3f(x, y + h, 0.0f);
glTexCoord2f(1.0, 1.0); glVertex3f(x + w, y + h, 0.0f);
glTexCoord2f(1.0, 0.0); glVertex3f(x + w, y, 0.0f);
glEnd();

Конечно, положение освещения должно быть правильно установлено, чтобы это работало.Обратите внимание, что положение света (GL_POSITION) и направление пятна (GL_SPOT_DIRECTION) преобразуются матрицей вида текущей модели в момент их установки.

...