仅使用顶点着色器有效渲染

时间:2014-01-20 19:29:55

标签: c++ opengl

我有一个文件,我从中读取顶点位置/ -uvs / -normals以及索引。我想以最有效的方式呈现它们。那不是问题。我还想使用顶点着色器来替换骨骼和动画中的椎体。

当然,我希望以最有效的方式实现这一目标。纹理是外部绑定的,我不应该关心。

我的第一个想法是使用glVertexAttribute *和glBindBuffer *等。但我无法找到一种方法来完成我的法线,就像我做glNormal一样,glTexCoord它们会被OpenGl自动处理。

就像我说过,我只能使用顶点着色器,片段等已被“阻止”。

2 个答案:

答案 0 :(得分:2)

您使用的是什么版本的GLSL?

这可能无法回答您的问题,但它显示了如何正确设置通用顶点属性,而不依赖于非标准属性别名。

对于所有版本(使用通用顶点属性),一般的想法是相同的,但在GLSL中声明它们的语法不同。无论您使用的是哪个版本,都需要将顶点着色器中的命名属性与传递给glVertexAttribPointer (...)时的相同索引绑定。

GLSL前1.30(GL 2.0 / 2.1):

#version 110

attribute vec4 vtx_pos_NDC;
attribute vec2 vtx_tex;
attribute vec3 vtx_norm;

varying   vec2 texcoords;
varying   vec3 normal;

void main (void)
{
  gl_Position = vtx_pos_NDC;
  texcoords   = vtx_tex;
  normal      = vtx_norm;
}

GLSL 1.30(GL 3.0):

#version 130

in  vec4 vtx_pos_NDC;
in  vec2 vtx_tex;
in  vec3 vtx_norm;

out vec2 texcoords;
out vec3 normal;

void main (void)
{
  gl_Position = vtx_pos_NDC;
  texcoords   = vtx_tex;
  normal      = vtx_norm;
}

对于这两个着色器,您可以为每个输入设置属性位置(在链接之前),如下所示:

glBindAttribLocation (<GLSL_PROGRAM>, 0, "vtx_pos_NDC");
glBindAttribLocation (<GLSL_PROGRAM>, 1, "vtx_tex");
glBindAttribLocation (<GLSL_PROGRAM>, 2, "vtx_norm");

如果您足够幸运,可以使用支持的实现 GL_ARB_explicit_attrib_location(或GLSL 3.30),你也可以这样做:

GLSL 3.30(GL 3.3)

#version 330

layout (location = 0) in vec4 vtx_pos_NDC;
layout (location = 1) in vec2 vtx_tex;
layout (location = 2) in vec3 vtx_norm;

out vec2 texcoords;
out vec3 normal;

void main (void)
{
  gl_Position = vtx_pos_NDC;
  texcoords   = vtx_tex;
  normal      = vtx_norm;
}

答案 1 :(得分:0)

以下是如何在GL 3中使用压缩顶点数据设置顶点缓冲区的示例:位置,颜色,法线和一组纹理坐标

typedef struct ccqv {
    GLfloat Pos[3];
    unsigned int Col;
    GLfloat Norm[3];
    GLfloat Tex2[4];
} Vertex;

...

glGenVertexArrays( 1, _vertexArray );
glBindVertexArray(_vertexArray);

glGenBuffers( 1, _vertexBuffer );
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, _arraySize*sizeof(Vertex), NULL, GL_DYNAMIC_DRAW  );

glEnableVertexAttribArray(0); // vertex
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex,Pos));
glEnableVertexAttribArray(3); // primary color
glVertexAttribPointer( 3, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex,Col));
glEnableVertexAttribArray(2); // normal
glVertexAttribPointer( 2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex,Tex1));
glEnableVertexAttribArray(8); // texcoord0
glVertexAttribPointer( 8, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex,Tex2));

glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);

Attrib函数的第一个参数是属性的索引。为简单起见,我使用为NVIDIA CG定义的别名:http://http.developer.nvidia.com/Cg/gp4gp.html

如果您正在使用GLSL着色器,则需要使用glBindAttribLocation()来定义这些索引,如Andon M. Coleman的回答中所述。