Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在OpenGL中使用顶点缓冲区对象为原语着色_C_Opengl_Shader - Fatal编程技术网

C 在OpenGL中使用顶点缓冲区对象为原语着色

C 在OpenGL中使用顶点缓冲区对象为原语着色,c,opengl,shader,C,Opengl,Shader,我正在用C语言编写一个程序,使用OpenGL绘制一些基本体(直线、圆等)。我已经成功地使用缓冲区对象来存储基本体的顶点,从而绘制它们。但我现在似乎被卡住了,因为我不知道如何设置它们的颜色。我的老师给了我一部分程序,因此我知道必须使用以下结构指定颜色属性: typedef struct { float r; float g; float b; float a; } vec4; 我知道我应该使用vec4数组来存储颜色值,所以我声明了一个这样的变量。第一个是用于存储基

我正在用C语言编写一个程序,使用OpenGL绘制一些基本体(直线、圆等)。我已经成功地使用缓冲区对象来存储基本体的顶点,从而绘制它们。但我现在似乎被卡住了,因为我不知道如何设置它们的颜色。我的老师给了我一部分程序,因此我知道必须使用以下结构指定颜色属性:

typedef struct {
    float r;
    float g;
    float b;
    float a;
} vec4;
我知道我应该使用vec4数组来存储颜色值,所以我声明了一个这样的变量。第一个是用于存储基本体顶点的vec2数组

vec2 vertices[10000];
vec4 colours[10000];
据我所知,用于设置顶点缓冲区限制的函数如下所示:

void initShaders(void) 
{
    GLuint buffer;
    GLuint loc;
    GLuint vao;

    /*Create and initialize a program object with shaders */ 
  idProgram = initProgram("ass1vshader.glsl", "ass1fshader.glsl");

    /*installs the program object as part of current rendering state */ 
   glUseProgram(idProgram);

   /*Creat a vertex array object */ 
   glGenVertexArrays(1, &vao);
   glBindVertexArray(vao);

    /*Create buffer in the shared display list space and */ 
     /* bind it as GL_ARRAY_BUFFER */ 
    glGenBuffers( 1, &buffer);
    glBindBuffer( GL_ARRAY_BUFFER, buffer);
    glBufferData( GL_ARRAY_BUFFER, sizeof(vertex)+sizeof(colours), NULL,GL_STATIC_DRAW);

    /*Initialize attribute vPosition in program */ 
    loc = glGetAttribLocation( idProgram, "vPosition");
    glEnableVertexAttribArray(loc);
    glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)BUFFER_OFFSET(0));

    /*Get location of the uniform attribute 'u_proj_matrix' */ 
    idProjection = glGetUniformLocation(idProgram, "u_proj_matrix");

    /*Set graphics attributes */ 
    glLineWidth(3.0);
    glPointSize(1.0);
    glClearColor(1.0, 1.0, 1.0, 1.0);

}
#version 140

in vec4 color;
out vec4  fColor;

void
main()
{    
    fColor = color;
}
如您所见,我已将顶点缓冲区大小初始化为“顶点”和“颜色”的组合大小

我还了解到片段着色器在着色过程中起着重要作用。看起来是这样的:

void initShaders(void) 
{
    GLuint buffer;
    GLuint loc;
    GLuint vao;

    /*Create and initialize a program object with shaders */ 
  idProgram = initProgram("ass1vshader.glsl", "ass1fshader.glsl");

    /*installs the program object as part of current rendering state */ 
   glUseProgram(idProgram);

   /*Creat a vertex array object */ 
   glGenVertexArrays(1, &vao);
   glBindVertexArray(vao);

    /*Create buffer in the shared display list space and */ 
     /* bind it as GL_ARRAY_BUFFER */ 
    glGenBuffers( 1, &buffer);
    glBindBuffer( GL_ARRAY_BUFFER, buffer);
    glBufferData( GL_ARRAY_BUFFER, sizeof(vertex)+sizeof(colours), NULL,GL_STATIC_DRAW);

    /*Initialize attribute vPosition in program */ 
    loc = glGetAttribLocation( idProgram, "vPosition");
    glEnableVertexAttribArray(loc);
    glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)BUFFER_OFFSET(0));

    /*Get location of the uniform attribute 'u_proj_matrix' */ 
    idProjection = glGetUniformLocation(idProgram, "u_proj_matrix");

    /*Set graphics attributes */ 
    glLineWidth(3.0);
    glPointSize(1.0);
    glClearColor(1.0, 1.0, 1.0, 1.0);

}
#version 140

in vec4 color;
out vec4  fColor;

void
main()
{    
    fColor = color;
}

有人能告诉我怎样才能给我的原语着色吗?我希望我提供的信息足够了。

一种方法是使用颜色数组。您可以使用与调用
glvertexinter()
相同的方法调用

另外,我不知道这是否只是一个打字错误,或者你是否真的有这个错误,但你写道:

glBufferData( GL_ARRAY_BUFFER, sizeof(vertex)+sizeof(colours), NULL,GL_STATIC_DRAW);
但是,顶点数组的名称为“顶点”而不是“顶点”(至少根据前面的语句)。如果它编译正常,则可能意味着您有另一个名为vertex的变量或数据结构,但它并没有按照您的想法执行


由于您的数据不是交错的(您有单独的顶点和颜色数据),我认为您应该为它们使用单独的缓冲区。如果它们在一个结构中,您可以使用单个数组,并适当地设置步幅,但由于它们不是交错的,我不确定您尝试执行的操作是否有效。

一种方法是使用颜色数组。您可以使用与调用
glvertexinter()
相同的方法调用

另外,我不知道这是否只是一个打字错误,或者你是否真的有这个错误,但你写道:

glBufferData( GL_ARRAY_BUFFER, sizeof(vertex)+sizeof(colours), NULL,GL_STATIC_DRAW);
但是,顶点数组的名称为“顶点”而不是“顶点”(至少根据前面的语句)。如果它编译正常,则可能意味着您有另一个名为vertex的变量或数据结构,但它并没有按照您的想法执行


由于您的数据不是交错的(您有单独的顶点和颜色数据),我认为您应该为它们使用单独的缓冲区。如果它们在一个结构中,您可以使用单个数组,并适当设置步长,但由于它们不是交错的,我不确定您尝试执行的操作是否有效。

首先,您没有显示顶点着色器,它负责接收逐顶点颜色,并将其输出到基本体上进行插值,然后发送到片段着色器。我猜它看起来(或应该看起来)像:

uniform mat4 u_proj_matrix;

in vec4 vPosition;
in vec4 vColor;

out color;

void main()
{
    gl_Position = u_proj_matrix * vPosition;
    color = vColor;
}
因此,我们有一个额外的逐顶点属性,名为
vColor
,我们需要为其指定一个源,就像我们对
vPosition
属性所做的那样:

loc = glGetAttribLocation(idProgram, "vColor");
glEnableVertexAttribArray(loc);
glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, 0, 
                      (GLvoid*)BUFFER_OFFSET(sizeof(vertices)));
这将指定在所有10000个顶点的坐标之后存储在缓冲区中的所有10000个顶点的颜色

vec2 vertices[10000];
vec4 colours[10000];

但正如user1118321已经指出的,将单个顶点的坐标和颜色存储在一起,从而交错属性可能是一个更好的主意(即使不是唯一可能的主意)。在这种情况下,您将拥有如下结构:

typedef struct {
    vec2 coords;
    vec4 color;
} vertex;
以及以下各项的单个阵列:

vertex vertices[10000];
但在这种情况下,我们必须告诉OpenGL,我们的数据是通过使用
glVertexAttributePointer
的步幅和偏移参数进行交错的:

//for position:
glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 
                      sizeof(vertex), (GLvoid*)offsetof(vertex, coords));

//for color:
glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, 
                      sizeof(vertex), (GLvoid*)offsetof(vertex, color));
这告诉OpenGL,两个连续顶点的属性值之间的跨距(从一个到下一个的偏移量)是自定义结构的大小。意味着要从一个顶点的坐标数据开始到下一个顶点的坐标数据开始,我们必须“跳过”
sizeof(顶点)
bytes(很可能是
sizeof(vec2)+sizeof(vec4)=24
),同样地,对于颜色也是如此


此外,我们告诉GL,我们的顶点数据从第一个顶点的coords成员的偏移量开始(很可能
0
),我们的颜色数据从第一个顶点的颜色成员的偏移量开始(很可能
sizeof(vec2)=8
)。

首先,您没有显示顶点着色器,它负责接收逐顶点颜色,并将其输出到基本体上进行插值,然后发送到片段着色器。我猜它看起来(或应该看起来)像:

uniform mat4 u_proj_matrix;

in vec4 vPosition;
in vec4 vColor;

out color;

void main()
{
    gl_Position = u_proj_matrix * vPosition;
    color = vColor;
}
因此,我们有一个额外的逐顶点属性,名为
vColor
,我们需要为其指定一个源,就像我们对
vPosition
属性所做的那样:

loc = glGetAttribLocation(idProgram, "vColor");
glEnableVertexAttribArray(loc);
glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, 0, 
                      (GLvoid*)BUFFER_OFFSET(sizeof(vertices)));
这将指定在所有10000个顶点的坐标之后存储在缓冲区中的所有10000个顶点的颜色

vec2 vertices[10000];
vec4 colours[10000];

但正如user1118321已经指出的,将单个顶点的坐标和颜色存储在一起,从而交错属性可能是一个更好的主意(即使不是唯一可能的主意)。在这种情况下,您将拥有如下结构:

typedef struct {
    vec2 coords;
    vec4 color;
} vertex;
以及以下各项的单个阵列:

vertex vertices[10000];
但在这种情况下,我们必须告诉OpenGL,我们的数据是通过使用
glVertexAttributePointer
的步幅和偏移参数进行交错的:

//for position:
glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 
                      sizeof(vertex), (GLvoid*)offsetof(vertex, coords));

//for color:
glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, 
                      sizeof(vertex), (GLvoid*)offsetof(vertex, color));
这告诉OpenGL,两个连续顶点的属性值之间的跨距(从一个到下一个的偏移量)是自定义结构的大小。意味着要从一个顶点的坐标数据开始到下一个顶点的坐标数据开始,我们必须“跳过”
sizeof(顶点)
bytes(很可能是
sizeof(vec2)+sizeof(vec4)=24
),同样地,对于颜色也是如此

此外,我们告诉GL,我们的顶点数据从的coords成员的偏移量开始