使用gllightfv和glmaterialfv照明vbo

时间:2014-05-10 16:52:14

标签: opengl shader vertex-shader vertex-buffer

我创建了一个将3D数据绘制为曲面的程序。使用

定义3点照明[键/后退/填充]
glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
glLightfv(GL_LIGHT2, GL_POSITION, light2_position);
glLightfv(GL_LIGHT0, GL_DIFFUSE, white);
glLightfv(GL_LIGHT2, GL_DIFFUSE, light_grey);
glLightfv(GL_LIGHT1, GL_AMBIENT, amb_level);

然后使用

绘制表面
glBegin(GL_TRIANGLES);

    glColor4f(ct.v1.r,ct.v1.g,ct.v1.b,a);
    glNormal3f(ct.v1.nx,ct.v1.nz,ct.v1.ny);
    glVertex3f(ct.v1.x, ct.v1.z, ct.v1.y);

    glColor4f(ct.v2.r,ct.v2.g,ct.v2.b,a);
    glNormal3f(ct.v2.nx,ct.v2.nz,ct.v2.ny);
    glVertex3f(ct.v2.x, ct.v2.z, ct.v2.y);

    glColor4f(ct.v3.r,ct.v3.g,ct.v3.b,a);
    glNormal3f(ct.v3.nx,ct.v3.nz,ct.v3.ny);
    glVertex3f(ct.v3.x, ct.v3.z, ct.v3.y);

glEnd();

并创建了可爱的点亮场景,但带有锯齿

 3 point lighting

....所以转移到FFSA并立即使用VBO ...将三角形的颜色和顶点数据传递给简单的着色器

    void draw_triangle2(c_triangle ct,bool f)
{
    g_vertex_buffer_data[0][0]=ct.v1.x;
g_vertex_buffer_data[0][1]=ct.v1.z;
g_vertex_buffer_data[0][2]=ct.v1.y;
g_vertex_buffer_data[1][0]=ct.v2.x;
g_vertex_buffer_data[1][1]=ct.v2.z;
g_vertex_buffer_data[1][2]=ct.v2.y;
g_vertex_buffer_data[2][0]=ct.v3.x;
g_vertex_buffer_data[2][1]=ct.v3.z;
g_vertex_buffer_data[2][2]=ct.v3.y;


glBindBuffer(GL_ARRAY_BUFFER, my_gl_vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data[0][0])*9,   g_vertex_buffer_data, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, my_gl_vertexbuffer);

glVertexAttribPointer(
    0,                 
3,                  // size
GL_FLOAT,           // type
GL_FALSE,           // normalized?
0,                  // stride
(void*)0            // array buffer offset
);

g_color_buffer_data[0][0]=ct.v1.r;
g_color_buffer_data[0][1]=ct.v1.g;
g_color_buffer_data[0][2]=ct.v1.b;
g_color_buffer_data[1][0]=ct.v2.r;
g_color_buffer_data[1][1]=ct.v2.g;
g_color_buffer_data[1][2]=ct.v2.b;
g_color_buffer_data[2][0]=ct.v3.r;
g_color_buffer_data[2][1]=ct.v3.g;
g_color_buffer_data[2][2]=ct.v3.b;
glBindBuffer(GL_ARRAY_BUFFER, my_gl_colorbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data[0][0])*9, g_color_buffer_data, GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, my_gl_colorbuffer);   
glVertexAttribPointer(
        1,                                
        3,                                
        GL_FLOAT,                         
        GL_FALSE,                         
        0,                                
        (void*)0                          
    );

glDrawArrays(GL_TRIANGLES, 0, 3); // 3 indices starting at 0 -> 1 triangle

};

顶点着色器是

#version 330 core

layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec3 vertexColor;

out vec3 fragmentColor;
uniform mat4 MVP;

void main(){
gl_Position =  MVP * vec4(vertexPosition_modelspace,1);

fragmentColor = vertexColor;
}

片段着色器

#version 330 core

in vec3 fragmentColor;

out vec3 color;

void main(){

color = fragmentColor;
}

但失去了光线+正常传球。

拖网教程提供了一种使用着色器计算光照的方法,我很高兴使用固定的管道照明并保留glLighting代码块。并使着色器简单。

我需要做什么?我可以创建法线的第3个缓冲区 - 如果是这样,我如何将它们传递给固定的管道?在这两个着色器中的哪一个?

由于

1 个答案:

答案 0 :(得分:2)

您有两种选择:

  1. 在您自己的着色器中实施灯光计算。
  2. 坚持使用固定管道。
  3. 您无法使用自己的着色器,仍然可以利用固定功能的照明功能。

    我通常会建议选项1,因为固定管道在核心OpenGL中已弃用,并且使用自己的着色器增加了很多灵活性。但如果您之前没有进行着色器编程,那么肯定会有一些学习曲线。如果您尚未准备好进行跳转,则可以非常轻松地使用以前的固定管道代码和VBO。您需要改变的主要内容:

    • 为您的法线创建另一个VBO,就像您对位置和颜色所做的那样。或者将所有三个属性交错存储在同一个VBO中。
    • 而不是glVertexAttribPointer()glEnableVertexAttribArray(),使用等效的固定功能属性:glVertexPointer()glNormalPointer()glColorPointer()glEnableClientState(GL_[VERTEX|NORMAL|COLOR]_ARRAY)。< / LI>