gpt4 book ai didi

c++ - OpenGL 导入 PNG 变暗

转载 作者:行者123 更新时间:2023-11-30 04:54:24 26 4
gpt4 key购买 nike

我正在为一个项目在 OpenGL 中制作游戏。我尝试导入 PNG,然后使用 glEnable2D 函数在我的 3D 游戏上绘制 GUI。函数是

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();

}

而且它有效。然后我有第二个函数用于返回 3D 环境。然后我有这个函数用纹理绘制四边形并将它绘制到屏幕上(也读取 alpha)

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();
}

如果我运行该函数会有奇怪的行为。它适用于 alpha,但只要图像靠近右下角,就会使图像变暗 enter image description here

如果我不评论设置 glTextEnvF 的行,它实际上会以正确的方式点亮事物,但不再读取 Alphas。如何在不应用奇怪光照的情况下使函数也读取 alpha channel ?

最佳答案

请注意,通过 glBegin/glEnd 序列绘制、固定功能流水线矩阵堆栈和每个顶点灯​​光模型的固定功能流水线已被弃用数十年。了解 Fixed Function Pipeline并查看 Vertex SpecificationShader最先进的渲染方式。


无论如何,问题在于您的 GUI 上没有合适的灯光。您有 2 种可能性,要么在绘制 GUI 之前禁用灯光(glDisable(GL_LIGHTING))。或者确保灯光照亮 GUI。

为此,您必须确保光源位于 GUI 元素前面,这意味着光源位置必须更靠近相机,然后是 GUI 甚至相机后面。

但这还不够,您还必须确保 GUI 元素反射光线。对于光的反射最重要的是表面的法 vector ,因为标准 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;

您根本没有设置任何法 vector 。由于 OpenGL 是一个状态引擎,您最后设置的法 vector glNormal仍然有效。当顶点坐标由glVertex设置时,那么这个法 vector 关联到。这可能会导致任意结果。

由于 GUI 几何图形是在视口(viewport)的 xy 平面上绘制的,而 View 空间的 z 轴指向视口(viewport)外(在 Right-handed 坐标系中),我建议定义一个法 vector ,指向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) 在设置时由当前模型 View 矩阵转换。

关于c++ - OpenGL 导入 PNG 变暗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53634975/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com