【发布时间】:2018-03-10 11:31:13
【问题描述】:
我必须为大学做功课(在 OpenGL 中画一只蝴蝶)。目前我正在研究蝴蝶的身体,这是一个简单的椭圆(它将是一个 2D 游戏)。我必须用三角形绘制这个填充的椭圆,因为我们不能使用其他库(我假设有一个简单的 Circle() 或类似的函数)。
现在我可以画一个三角形了,但是从蝴蝶的 body 类创建一个三角形是行不通的。代码如下:
class Triangle {
unsigned int vao;
unsigned int vbo[2];
float phi;
float vertexCoords[6];
float vertexColors[9] = {1,0,0, 0,1,0, 0,0,1};
public:
Triangle(float x1,float y1,float x2,float y2,float x3, float y3) {
vertexCoords[0] = x1;
vertexCoords[1] = y1;
vertexCoords[2] = x2;
vertexCoords[3] = y2;
vertexCoords[4] = x3;
vertexCoords[5] = y3;
Animate(0);
}
void setTriangleColor(float r, float g, float b) {
for (int i = 0; i < 9; i+=3) {
vertexColors[i] = r;
vertexColors[i + 1] = g;
vertexColors[i + 2] = b;
}
Create();
}
void setPointColor(float r, float g, float b, int count) {
vertexColors[count * 3] = r;
vertexColors[count * 3 + 1] = g;
vertexColors[count * 3 + 2] = b;
Create();
}
void Create() {
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(2, &vbo[0]);
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertexCoords),vertexCoords,GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,2, GL_FLOAT,GL_FALSE,0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexColors), vertexColors, GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
}
void Animate(float t) { /*phi = t;*/ phi = 0; }
void Draw() {
mat4 ScaleSmaller(
0.01, 0 , 0 , 0,
0 , 0.01 , 0 , 0,
0 , 0 , 0.01 , 0,
0 , 0 , 0 , 1
);
mat4 MVPTransform1(1, 0, 0, 0,
0, cosf(phi), -sinf(phi), 0,
0, sinf(phi), cosf(phi), 0,
0, 0, 0, 1);
int location = glGetUniformLocation(shaderProgram, "MVP");
if (location >= 0) glUniformMatrix4fv(location, 1, GL_TRUE, (MVPTransform1*ScaleSmaller));
else printf("uniform MVP cannot be set\n");
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
};
struct Point {
float x, y;
Point(float x,float y):x(x),y(y){}
Point():x(0),y(0){}
};
class MyEllipse {
float width;
float height;
Point origo;
std::vector<Triangle> triangles = std::vector<Triangle>();
public:
MyEllipse() {}
MyEllipse(Point origo,float width, float height):origo(origo),width(width),height(height) {
float px = origo.x + (width / 2) * cosf(90);
float py = origo.y + (height / 2) * cosf(90);
float prevX = origo.x + (width / 2) * cosf(0);
float prevY = origo.y + (height / 2) * cosf(0);
Triangle elem1(origo.x, origo.y, px, py, prevX, prevY);
triangles.push_back(elem1);
}
void Create() {
for (Triangle value : triangles) {
value.Create();
}
}
void Draw() {
for (Triangle value : triangles) {
value.Draw();
}
}
};
在代码中,我在同一位置创建了具有相同参数的 Triangle 和 MyEllipse。
float px = 10 + (50 / 2) * cosf(90);
float py = 10 + (50 / 2) * cosf(90);
float prevX = 10 + (50 / 2) * cosf(0);
float prevY = 10 + (50 / 2) * cosf(0);
Triangle triangle(10, 0, px, py, prevX, prevY);
MyEllipse test1 = MyEllipse(Point(10, 0), 50, 50);
(稍后我将在向量中添加更多三角形,现在我只是在测试。)问题是我可以看到三角形,但如果我删除三角形创建线,我什么也看不到.当我调用 triangle.Create() 或 triangle.Draw() 时,我没有忘记在代码的另一部分中添加适当的 Draw() 和 Create() 函数调用,然后立即调用 test1。 Create() 和 test1.Draw() 函数。
谁能告诉我关于这个问题的任何事情,因为我担心我不知道如何解决这个问题。
【问题讨论】:
-
cosf 很可能会采用弧度,而不是度数,因此超过 90 看起来是错误的。
-
仅作记录:为每个三角形创建一个 vao/vbo 并不是使用现代 opengl 的预期方式。为所有三角形的所有位置创建一个 VBO,依此类推。然后一次将它们全部绘制出来。
-
我会尝试使用弧度数,但问题是我在直接创建 Triangle 类时使用 cosf() 并且它是可见的。
-
诀窍是
for (Triangle &value : triangles),关注&! (创建于Create)。 -
你修改了两个循环吗?在 Create 和 Draw 中?
标签: c++ opengl drawing draw freeglut