以下是我的计划的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中的坐标,它确实使线条变小,但是当我增加圆的半径时,线条会再次出现。
答案 0 :(得分:0)
下面
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)。
答案 1 :(得分:0)
您正在绘制GL_LINE_LOOP
:
请参阅Khronos小组OGL Primitive文档:
GL_LINE_LOOP
:作为线条,除了第一个和最后一个顶点也用作线条。 因此,n个输入顶点得到n行。如果用户仅指定1个顶点,则忽略绘图命令。 第一个和最后一个顶点之间的线发生在序列中的所有前一行之后。
使用(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 );