Программа LWJGL Circle создает овальную форму
Я пытаюсь нарисовать круг в LWJGL, но когда я пытаюсь нарисовать его, он создает форму, которая больше похожа на овал, чем на круг. Кроме того, когда я меняю свой круг VertexCount 350+, форма, как будто, переворачивается. Я действительно не уверен, как работает код, который создает вершины (я взял Geometry, и я знаю основные триггерные отношения). Я действительно не нашел столько хороших уроков по созданию кругов. Вот мой код:
public class Circles {
// Setup variables
private int WIDTH = 800;
private int HEIGHT = 600;
private String title = "Circle";
private float fXOffset;
private int vbo = 0;
private int vao = 0;
int circleVertexCount = 300;
float[] vertexData = new float[(circleVertexCount + 1) * 4];
public Circles() {
setupOpenGL();
setupQuad();
while (!Display.isCloseRequested()) {
loop();
adjustVertexData();
Display.update();
Display.sync(60);
}
Display.destroy();
}
public void setupOpenGL() {
try {
Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
Display.setTitle(title);
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
System.exit(-1);
}
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
}
public void setupQuad() {
float r = 0.1f;
float x;
float y;
float offSetX = 0f;
float offSetY = 0f;
double theta = 2.0 * Math.PI;
vertexData[0] = (float) Math.sin(theta / circleVertexCount) * r + offSetX;
vertexData[1] = (float) Math.cos(theta / circleVertexCount) * r + offSetY;
for (int i = 2; i < 400; i += 2) {
double angle = theta * i / circleVertexCount;
x = (float) Math.cos(angle) * r;
vertexData[i] = x + offSetX;
}
for (int i = 3; i < 404; i += 2) {
double angle = Math.PI * 2 * i / circleVertexCount;
y = (float) Math.sin(angle) * r;
vertexData[i] = y + offSetY;
}
FloatBuffer vertexBuffer = BufferUtils.createFloatBuffer(vertexData.length);
vertexBuffer.put(vertexData);
vertexBuffer.flip();
vao = glGenVertexArrays();
glBindVertexArray(vao);
vbo = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER,vertexBuffer, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
public void loop() {
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLE_FAN, 0, vertexData.length / 2);
glDisableVertexAttribArray(0);
glBindVertexArray(0);
}
public static void main(String[] args) {
new Circles();
}
private void adjustVertexData() {
float newData[] = new float[vertexData.length];
System.arraycopy(vertexData, 0, newData, 0, vertexData.length);
if(Keyboard.isKeyDown(Keyboard.KEY_W)) {
fXOffset += 0.05f;
} else if(Keyboard.isKeyDown(Keyboard.KEY_S)) {
fXOffset -= 0.05f;
}
for(int i = 0; i < vertexData.length; i += 2) {
newData[i] += fXOffset;
}
FloatBuffer newDataBuffer = BufferUtils.createFloatBuffer(newData.length);
newDataBuffer.put(newData);
newDataBuffer.flip();
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferSubData(GL_ARRAY_BUFFER, 0, newDataBuffer);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}
300 Vertex Count (это моя главная проблема)
400 Vertex Count - Я удалил это изображение, оно вылезло, должно быть крошечный осколок справа, как секущий
500 вершин
Каждые 100 он удаляет все больше и больше круга и так далее.
1 ответ
Одна из ваших проблем заключается в следующем:
for (int i = 2; i < 400; i += 2) {
double angle = theta * i / circleVertexCount;
x = (float) Math.cos(angle) * r;
vertexData[i] = x + offSetX;
}
for (int i = 3; i < 404; i += 2) {
double angle = Math.PI * 2 * i / circleVertexCount;
y = (float) Math.sin(angle) * r;
vertexData[i] = y + offSetY;
}
Вы используете другое значение угла для положения x и y каждой вершины.
Вы можете попробовать это вместо этого:
for (int i = 0; i <= circleVertexCount; i++) {
double angle = i * theta / circleVertexCount;
x = (float) Math.cos(angle) * r;
y = (float) Math.sin(angle) * r;
vertexData[i * 2] = x + offSetX;
vertexData[i * 2 + 1] = y + offSetY;
}
Причиной того, что часть вашего круга была вырезана при большем числе вершин, была i < 400
в ваших циклах, поэтому я изменил его на i <= circleVertexCount
,
Другая проблема заключается в том, что ваше окно не квадратное, и вы не используете шейдер (или устаревшие встроенные матрицы) для исправления этого. Это означает, что одна единица вверх выглядит иначе, чем одна единица вправо, что приводит к овалу вместо круга. Чтобы исправить это, вы могли бы умножить свою позицию вершины х на высоту вашего дисплея, деленную на ширину вашего дисплея, предпочтительно в шейдере.