首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OPENGL:绘制多点灯

OPENGL:绘制多点灯
EN

Stack Overflow用户
提问于 2014-03-08 22:13:48
回答 2查看 1.2K关注 0票数 0

我有一个问题,在我的场景中绘制多点灯光。我正在OpenGL做一个简单的迷宫式的游戏,迷宫是随机生成的。迷宫中的每个“房间”都用一个房间结构来表示,如下所示:

代码语言:javascript
复制
struct Room
{
    int x, z;
    bool already_visited, n, s, e, w;
    GLuint vertex_buffer, texture, uv_buffer, normal_buffer;
    std::vector<glm::vec3>vertices, normals;
    std::vector<glm::vec2>uvs;
    glm::vec3 light_pos; //Stores the position of a light in the room
};

每个房间都有一盏灯,这个灯的位置存储在light_pos中。此灯用于简单的每顶点着色器,如下所示:

代码语言:javascript
复制
layout(location = 0) in vec3 pos;
layout(location = 1) in vec2 uv_coords;
layout(location = 2) in vec3 normal;
uniform mat4 mvpMatrix;
uniform mat4 mvMatrix;
uniform vec3 lightpos;
out vec2 vs_uv;
out vec3 vs_normal;
out vec3 color;
void main()
{
    gl_Position = mvpMatrix * vec4(pos,1.0);
    vs_normal = normal;
    vs_uv = uv_coords;
    vec3 lightVector = normalize(lightpos - pos);
    float diffuse = clamp(dot(normal,lightVector),0.0,1.0);
    color = vec3(diffuse,diffuse,diffuse);
}

我的片段着色器看起来如下(忽略"vs_normal",它现在还未使用):

代码语言:javascript
复制
in vec2 vs_uv;
in vec3 vs_normal;
in vec3 color;
uniform sampler2D tex;
out vec4 frag_color;

void main()
{
    frag_color = vec4(color,1.0) * texture(tex,vs_uv).rgba;
}

我的绘图代码是这样的:

代码语言:javascript
复制
mat4 mvMatrix = view_matrix*model_matrix;
mat4 mvpMatrix = projection_matrix * mvMatrix;
glBindVertexArray(vertexBufferObjectID);
glUseProgram(shaderProgram);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
for (int x = 0; x < NUM_ROOMS_X; x++)
{
   for (int z = 0; z < NUM_ROOMS_Z; z++)
   {
      //int x = int(std::round(position.x / ROOM_SIZE_X_MAX));
      //int z = int(std::round(position.z / ROOM_SIZE_Z_MAX));
      Room rm = room_array[x][z];
      glBindBuffer(GL_ARRAY_BUFFER, rm.vertex_buffer);
      glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);

      glBindBuffer(GL_ARRAY_BUFFER, rm.uv_buffer);
      glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*) 0);

      glBindBuffer(GL_ARRAY_BUFFER, rm.normal_buffer);
      glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);

      glUniformMatrix4fv(mvpMatrixID, 1, GL_FALSE, &mvpMatrix[0][0]);
      glUniformMatrix4fv(mvMatrixID, 1, GL_FALSE, &mvMatrix[0][0]);
      glUniform3fv(light_ID, 3, &rm.light_pos[0]); //Here is where I'm setting the new light position. It looks like this is ignored

      glActiveTexture(GL_TEXTURE0);
      glBindTexture(GL_TEXTURE_2D, rm.texture);
      glUniform1i(texture_ID, 0);

      glDrawArrays(GL_QUADS, 0, rm.vertices.size());
   }
}
glUseProgram(0);
glBindVertexArray(0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glBindTexture(GL_TEXTURE_2D, 0);

但是,结果是这样的(我修改了我的绘图代码,绘制了每个光线所在的方框,并在(0,0)位置圈出了房间):

http://imgur.com/w4uPMD6

正如你所看到的,看起来只有位置(0,0)的灯会影响到地图上的任何房间,其他的灯光就会被忽略。我知道灯的位置是正确的,因为我用来显示位置的盒子是正确的。我想,尽管我正在设置新的light_pos,但由于某种原因,它并没有通过。有什么想法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-21 13:49:58

解决了我的问题。我把这个函数叫做:

代码语言:javascript
复制
glUniform3fv(light_ID, 3, &rm.light_pos[0]);

我本应该这么说的:

代码语言:javascript
复制
glUniform3fv(light_ID, 1, &rm.light_pos[0]);
票数 0
EN

Stack Overflow用户

发布于 2014-03-08 22:43:49

您正在做的一件事,这不是很常见,是传递光的位置作为一个顶点属性。最优情况下,您应该将它作为一个统一变量传递给着色器,就像处理矩阵一样。但我怀疑这就是问题所在。

我相信你的问题是你在不同的空间里做光计算。您所绘制的曲面的顶点位于对象/模型空间中,而我猜,您的光线位于world空间中定义的一个点上。尝试将你的光线位置乘以你要应用到顶点的模型矩阵的逆值。我不熟悉GLM,但我认为其中肯定有一个逆()函数:

代码语言:javascript
复制
vec3 light_pos_object_space = inverse(model_matrix) * rm.light_pos;
glVertexAttrib3fv(light_ID, &light_pos_object_space[0]);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22275750

复制
相关文章

相似问题

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