![](/img/trans.png)
[英]Draw different objects with differents textures on the same VBO OpenGL
[英]Opengl 3+ draw lines with differents colors
我正在使用 SIFT 算法,我想在不同圖像的關鍵點之間畫線。 我做到了,但實際上,我所有的線條都具有相同的顏色,因此無法閱讀。
我想要實現的是為每條線設置一個隨機顏色,但一條線只有一種顏色。
我必須使用着色器來做到這一點,所以我將 LINES 和 POINTS(即顏色)發送到同一個着色器,但我不知道我的代碼有什么問題(我在嘗試執行代碼時崩潰了。編輯:並不是我的代碼有問題(好吧,顯然是的......)但錯誤導致崩潰,就像我有一個分段錯誤一樣。所以我認為我的錯誤是由於我的錯誤位置分配顏色數組(因為它沒有這個數組就可以工作))
我的代碼:
std::vector<GLfloat> points;
std::vector<glm::vec3> colors;
GLuint VAO, VBO[2];
void setupLines() {
glGenVertexArrays(1, &VAO);
glGenBuffers(2, &VBO[0]);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, points.size() * sizeof(GLfloat), &points[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(glm::vec3), &colors[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
}
void draw() {
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glDrawArrays(GL_LINES, 0, points.size());
//The error occurs here, it seems...
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glDrawArrays(GL_POINTS, 0, colors.size());
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
//for each points, we create the same colors 2by 2 so lines (that are 2 points) have the same colors
void addColor() {
for (int i = 0; i < points.size()/2; ++i) {
float a = rand() / (float)RAND_MAX;
float b = rand() / (float)RAND_MAX;
float c = rand() / (float)RAND_MAX;
colors.push_back(glm::vec3(a, b, c));
colors.push_back(glm::vec3(a, b, c));
}
}
和我的頂點着色器:
#version 330 core
layout (location = 0) in vec2 aTexCoord;
layout (location = 1) in vec3 color;
out vec2 TexCoord;
out vec3 Col;
void main()
{
TexCoord = vec2(aTexCoord.xy);
Col = color;
}
然后我在片段着色器中使用 Col 進行着色。
我必須這樣做嗎?
您必須在頂點着色器中設置當前位置gl_Position
。
頂點坐標必須是一個屬性:
in vec3 aVertCoord;
並且您必須將坐標分配給gl_Position
:
gl_Position = vec4(aVertCoord.xyz, 1.0);
請注意,對於 2D 坐標,它應該是這樣的:
in vec2 aVertCoord;
void main()
{
.....
gl_Position = vec4(aVertCoord.xy, 0.0, 1.0);
}
最后你有 2 個頂點屬性。 頂點坐標和顏色。 您不需要任何紋理坐標,因為您繪制了線條 ( GL_LINES
)。
但我猜你所說的aTexCoord
是頂點位置,所以你必須這樣做:
#version 330 core
layout (location = 0) in vec2 aTexCoord;
layout (location = 1) in vec3 color;
out vec3 TexCoord;
out vec3 Col;
void main()
{
gl_Position = vec4(aTexCoord.xy, 0.0, 1.0);
TexCoord = aTexCoord.xy;
Col = color;
}
頂點數組對象VAO
存儲通用頂點屬性( glVertexAttribPointer
、 glEnableVertexAttribArray
)的狀態。 頂點屬性狀態可以指頂點數組緩沖區。 當您繪制對象(線)時,您必須僅綁定頂點數組對象VAO
:
void draw() {
glBindVertexArray(VAO);
int numberOfPoints = points.size() / 2; // Number of points, not the number of floats
glDrawArrays(GL_LINES, 0, numberOfPoints );
glBindVertexArray(0);
}
請注意,一次調用glDrawArrays
就足夠了。
此外, glVertexAttribPointer
的第一個參數是屬性索引:
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(glm::vec3), &colors[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(
1, // <---------------------------- attribute index
3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
由於每個頂點坐標需要一種顏色,但您希望每條線都以單一顏色繪制,因此您必須這樣做:
void addColor()
{
int numberOfPoints = points.size() / 2;
for (int i = 0; i < numberOfPoints/2; ++i)
{
glm::vec3 col(
rand() / (float)RAND_MAX,
rand() / (float)RAND_MAX,
rand() / (float)RAND_MAX);
colors.push_back(col);
colors.push_back(col);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.