如何摆脱 OpenGL 圆圈中的红线
How do I get rid of the red line in my OpenGL circle
这是我程序的output。
这是我的代码
#include <cstdio> // for C++ i/o
#include <iostream>
using namespace std; // to avoid having to use std::
#define GLEW_STATIC // include GLEW as a static library
#include <GLEW/glew.h> // include GLEW
#include <GLFW/glfw3.h> // include GLFW (which includes the OpenGL header)
#include <glm/glm.hpp> // include GLM (ideally should only use the GLM headers that are actually used)
using namespace glm; // to avoid having to use glm::
#include "shader.h"
#define PI 3.14159265
#define MAX_SLICES 32
#define MIN_SLICES 8
#define MAX_VERTICES (MAX_SLICES+2)*3 // a triangle fan should have a minimum of 3 vertices
#define CIRCLE_RADIUS 0.5
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
// global variables
GLfloat g_vertices[MAX_VERTICES] = {
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f
};
GLuint g_slices = MAX_SLICES; // number of circle slices
GLuint g_VBO = 0; // identifiers
GLuint g_VAO = 0;
GLuint g_shaderProgramID = 0;
void generate_circle()
{
float angle = PI*2 / static_cast<float>(g_slices); // used to generate x and y coordinates
float scale_factor = static_cast<float>(WINDOW_HEIGHT) / WINDOW_WIDTH; // scale to make it a circle instead of an elipse
int index = 0; // vertex index
g_vertices[3] = CIRCLE_RADIUS * scale_factor; // set x coordinate of vertex 1
// generate vertex coordinates for triangle fan
for (int i = 2; i < g_slices+2; i++)
{
// multiply by 3 because a vertex has x, y, z coordinates
index = i * 3;
g_vertices[index] = CIRCLE_RADIUS * cos(angle) * scale_factor;
g_vertices[index + 1] = CIRCLE_RADIUS * sin(angle);
g_vertices[index + 2] = 0.0f;
// update to next angle
angle += PI*2 / static_cast<float>(g_slices);
}
}
static void init()
{
glClearColor(0.0, 0.0, 0.0, 1.0); // set clear background colour
// create and compile our GLSL program from the shader files
g_shaderProgramID = loadShaders("SimpleVS.vert", "SimpleFS.frag");
// generate vertices of triangle fan
generate_circle();
// create VBO and buffer the data
glGenBuffers(1, &g_VBO);
glBindBuffer(GL_ARRAY_BUFFER, g_VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*(g_slices + 2), g_vertices, GL_STATIC_DRAW);
// create VAO and specify VBO data
glGenVertexArrays(1, &g_VAO);
glBindVertexArray(g_VAO);
glBindBuffer(GL_ARRAY_BUFFER, g_VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); // specify the form of the data
glEnableVertexAttribArray(0); // enable vertex attributes
}
// function used to render the scene
static void render_scene()
{
glClear(GL_COLOR_BUFFER_BIT); // clear colour buffer
glUseProgram(g_shaderProgramID); // use the shaders associated with the shader program
glBindVertexArray(g_VAO); // make VAO active
glDrawArrays(GL_LINE_LOOP, 0, g_slices+2); // display the vertices based on the primitive type
glFlush(); // flush the pipeline
}
int main(void)
{
GLFWwindow* window = NULL; // pointer to a GLFW window handle
glfwSetErrorCallback(error_callback); // set error callback function
// initialise GLFW
if(!glfwInit())
{
// if failed to initialise GLFW
exit(EXIT_FAILURE);
}
// minimum OpenGL version 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
// create a window and its OpenGL context
window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "DemoCode", NULL, NULL);
// if failed to create window
if(window == NULL)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window); // set window context as the current context
glfwSwapInterval(1); // swap buffer interval
// initialise GLEW
if(glewInit() != GLEW_OK)
{
// if failed to initialise GLEW
cerr << "GLEW initialisation failed" << endl;
exit(EXIT_FAILURE);
}
// set key callback function
glfwSetKeyCallback(window, key_callback);
// initialise rendering states
init();
// the rendering loop
while(!glfwWindowShouldClose(window))
{
render_scene(); // render the scene
glfwSwapBuffers(window); // swap buffers
glfwPollEvents(); // poll for events
}
// clean up
glDeleteProgram(g_shaderProgramID);
glDeleteBuffers(1, &g_VBO);
glDeleteVertexArrays(1, &g_VAO);
// close the window and terminate GLFW
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}
我想摆脱从轴出来的红线。我只想要一个空心圆。
我正在使用 GL_LINE_LOOP 绘制数组。我使用了错误的原语吗?
我试过调整g_vertices中的坐标,它确实使线变小了,但是当我增加圆的半径时,线又出现了。
这里
GLfloat g_vertices[MAX_VERTICES] = {
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f
};
这里:
g_vertices[3] = CIRCLE_RADIUS * scale_factor; // set x coordinate of vertex 1
// generate vertex coordinates for triangle fan
for (int i = 2; i < g_slices+2; i++)
顶点 0 始终为 (0, 0, 0)。
您正在绘制 GL_LINE_LOOP
:
查看 Khronos 组 OGL Primitive 文档:
GL_LINE_LOOP
: As line strips, except that the first and last vertices are also used as a line.
Thus, you get n lines for n input vertices. If the user only specifies 1 vertex, the drawing command is ignored.
The line between the first and last vertices happens after all of the previous lines in the sequence.
你用 (0, 0, 0):
初始化第一个和第二个顶点位置
GLfloat g_vertices[MAX_VERTICES] = {
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f
};
然后添加圆的顶点,因为循环从索引 2 开始:
for (int i = 2; i < g_slices+2; i++)
{
......
}
你画的是从圆心到圆上第一个点的线。
然后画圆。最后一个顶点位置(在圆上)连接到第一个顶点位置,即圆的中心点。
您必须跳过列表开头的 2 个顶点。您不必初始化前两个顶点,您可以从 0 开始循环。
见上面的代码:
定义和全局变量:
#define MAX_SLICES 32
#define MAX_VERTICES MAX_SLICES*3
GLfloat g_vertices_circle[MAX_VERTICES];
GLuint g_slices = MAX_SLICES;
创建顶点位置和颜色属性数组
for (int i = 0; i < g_slices; i++)
{
float angle = (float)PI * 2.0f * (float)i / float(g_slices);
int index = i * 3;
g_vertices_circle[index] = CIRCLE_RADIUS * cos(angle) * scale_factor;
g_vertices_circle[index + 1] = CIRCLE_RADIUS * sin(angle);
g_vertices_circle[index + 2] = 0.0f;
}
设置顶点缓冲区对象:
glGenBuffers(1, &g_VBO);
glBindBuffer(GL_ARRAY_BUFFER, g_VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * g_slices, g_vertices, GL_STATIC_DRAW);
最后是绘图:
glDrawArrays( GL_LINE_LOOP, 0, g_slices );
这是我程序的output。
这是我的代码
#include <cstdio> // for C++ i/o
#include <iostream>
using namespace std; // to avoid having to use std::
#define GLEW_STATIC // include GLEW as a static library
#include <GLEW/glew.h> // include GLEW
#include <GLFW/glfw3.h> // include GLFW (which includes the OpenGL header)
#include <glm/glm.hpp> // include GLM (ideally should only use the GLM headers that are actually used)
using namespace glm; // to avoid having to use glm::
#include "shader.h"
#define PI 3.14159265
#define MAX_SLICES 32
#define MIN_SLICES 8
#define MAX_VERTICES (MAX_SLICES+2)*3 // a triangle fan should have a minimum of 3 vertices
#define CIRCLE_RADIUS 0.5
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
// global variables
GLfloat g_vertices[MAX_VERTICES] = {
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f
};
GLuint g_slices = MAX_SLICES; // number of circle slices
GLuint g_VBO = 0; // identifiers
GLuint g_VAO = 0;
GLuint g_shaderProgramID = 0;
void generate_circle()
{
float angle = PI*2 / static_cast<float>(g_slices); // used to generate x and y coordinates
float scale_factor = static_cast<float>(WINDOW_HEIGHT) / WINDOW_WIDTH; // scale to make it a circle instead of an elipse
int index = 0; // vertex index
g_vertices[3] = CIRCLE_RADIUS * scale_factor; // set x coordinate of vertex 1
// generate vertex coordinates for triangle fan
for (int i = 2; i < g_slices+2; i++)
{
// multiply by 3 because a vertex has x, y, z coordinates
index = i * 3;
g_vertices[index] = CIRCLE_RADIUS * cos(angle) * scale_factor;
g_vertices[index + 1] = CIRCLE_RADIUS * sin(angle);
g_vertices[index + 2] = 0.0f;
// update to next angle
angle += PI*2 / static_cast<float>(g_slices);
}
}
static void init()
{
glClearColor(0.0, 0.0, 0.0, 1.0); // set clear background colour
// create and compile our GLSL program from the shader files
g_shaderProgramID = loadShaders("SimpleVS.vert", "SimpleFS.frag");
// generate vertices of triangle fan
generate_circle();
// create VBO and buffer the data
glGenBuffers(1, &g_VBO);
glBindBuffer(GL_ARRAY_BUFFER, g_VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*(g_slices + 2), g_vertices, GL_STATIC_DRAW);
// create VAO and specify VBO data
glGenVertexArrays(1, &g_VAO);
glBindVertexArray(g_VAO);
glBindBuffer(GL_ARRAY_BUFFER, g_VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); // specify the form of the data
glEnableVertexAttribArray(0); // enable vertex attributes
}
// function used to render the scene
static void render_scene()
{
glClear(GL_COLOR_BUFFER_BIT); // clear colour buffer
glUseProgram(g_shaderProgramID); // use the shaders associated with the shader program
glBindVertexArray(g_VAO); // make VAO active
glDrawArrays(GL_LINE_LOOP, 0, g_slices+2); // display the vertices based on the primitive type
glFlush(); // flush the pipeline
}
int main(void)
{
GLFWwindow* window = NULL; // pointer to a GLFW window handle
glfwSetErrorCallback(error_callback); // set error callback function
// initialise GLFW
if(!glfwInit())
{
// if failed to initialise GLFW
exit(EXIT_FAILURE);
}
// minimum OpenGL version 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
// create a window and its OpenGL context
window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "DemoCode", NULL, NULL);
// if failed to create window
if(window == NULL)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window); // set window context as the current context
glfwSwapInterval(1); // swap buffer interval
// initialise GLEW
if(glewInit() != GLEW_OK)
{
// if failed to initialise GLEW
cerr << "GLEW initialisation failed" << endl;
exit(EXIT_FAILURE);
}
// set key callback function
glfwSetKeyCallback(window, key_callback);
// initialise rendering states
init();
// the rendering loop
while(!glfwWindowShouldClose(window))
{
render_scene(); // render the scene
glfwSwapBuffers(window); // swap buffers
glfwPollEvents(); // poll for events
}
// clean up
glDeleteProgram(g_shaderProgramID);
glDeleteBuffers(1, &g_VBO);
glDeleteVertexArrays(1, &g_VAO);
// close the window and terminate GLFW
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}
我想摆脱从轴出来的红线。我只想要一个空心圆。 我正在使用 GL_LINE_LOOP 绘制数组。我使用了错误的原语吗? 我试过调整g_vertices中的坐标,它确实使线变小了,但是当我增加圆的半径时,线又出现了。
这里
GLfloat g_vertices[MAX_VERTICES] = {
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f
};
这里:
g_vertices[3] = CIRCLE_RADIUS * scale_factor; // set x coordinate of vertex 1
// generate vertex coordinates for triangle fan
for (int i = 2; i < g_slices+2; i++)
顶点 0 始终为 (0, 0, 0)。
您正在绘制 GL_LINE_LOOP
:
查看 Khronos 组 OGL Primitive 文档:
GL_LINE_LOOP
: As line strips, except that the first and last vertices are also used as a line. Thus, you get n lines for n input vertices. If the user only specifies 1 vertex, the drawing command is ignored. The line between the first and last vertices happens after all of the previous lines in the sequence.
你用 (0, 0, 0):
初始化第一个和第二个顶点位置GLfloat g_vertices[MAX_VERTICES] = {
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f
};
然后添加圆的顶点,因为循环从索引 2 开始:
for (int i = 2; i < g_slices+2; i++)
{
......
}
你画的是从圆心到圆上第一个点的线。 然后画圆。最后一个顶点位置(在圆上)连接到第一个顶点位置,即圆的中心点。
您必须跳过列表开头的 2 个顶点。您不必初始化前两个顶点,您可以从 0 开始循环。 见上面的代码:
定义和全局变量:
#define MAX_SLICES 32
#define MAX_VERTICES MAX_SLICES*3
GLfloat g_vertices_circle[MAX_VERTICES];
GLuint g_slices = MAX_SLICES;
创建顶点位置和颜色属性数组
for (int i = 0; i < g_slices; i++)
{
float angle = (float)PI * 2.0f * (float)i / float(g_slices);
int index = i * 3;
g_vertices_circle[index] = CIRCLE_RADIUS * cos(angle) * scale_factor;
g_vertices_circle[index + 1] = CIRCLE_RADIUS * sin(angle);
g_vertices_circle[index + 2] = 0.0f;
}
设置顶点缓冲区对象:
glGenBuffers(1, &g_VBO);
glBindBuffer(GL_ARRAY_BUFFER, g_VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * g_slices, g_vertices, GL_STATIC_DRAW);
最后是绘图:
glDrawArrays( GL_LINE_LOOP, 0, g_slices );