首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenGL进口PNG暗灯

OpenGL进口PNG暗灯
EN

Stack Overflow用户
提问于 2018-12-05 14:52:18
回答 1查看 156关注 0票数 2

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

代码语言:javascript
复制
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)。

代码语言:javascript
复制
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();
}

如果我运行这个函数,会有一个奇怪的行为。它适用于阿尔法,但只要它们靠近右下角,就能保持较暗的图像。

如果我不评论设置glTextEnvF的行,它实际上以正确的方式点亮这些东西,但不再读Alphas。如何使功能读取同时也是阿尔法通道,而不使用奇怪的照明?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-05 21:18:58

注意,用glBegin/glEnd序列绘制的固定函数流水线矩阵堆栈和每顶点光模型的固定函数流水线是几十年来不推荐的。阅读有关固定功能管道的信息,并查看顶点规范着色器的最新呈现方式。

无论如何,问题是在您的GUI没有适当的灯光。在绘制图形用户界面之前,您有两种可能性,要么禁用光线(glDisable(GL_LIGHTING))。或者确保灯光照亮GUI。

要做到这一点,您必须确保光源在GUI元素的前面,这意味着光的位置必须比GUI更靠近摄像机,甚至在摄像机后面。

但这还不够,您还必须确保GUI元素反射光线。光的反射最重要的是表面的法线矢量,因为标准的OpenGL 布林光模型是这样计算的:

代码语言:javascript
复制
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设置时,则将此法向量关联到。这可能导致任意的结果。

由于GUI几何是在视口的xy平面上绘制的,视图空间z轴从视口(在右撇子坐标系中)中指出,我建议定义一个指向z轴的法线向量:

代码语言:javascript
复制
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)在设置时由当前的模型视图矩阵进行转换。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53634975

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档