简单概括就是把圆分成很多份
上代码:
为圆创建一个类
#pragma once
#include <vector>
#include <glm\glm.hpp>
using namespace std;
class Circle
{
private:
//顶点个数
int numVertices;
//索引个数
int numIndices;
//存储顶点
vector<glm::vec3> vertices;
//索引
vector<int> indices;
float toRadians(float degrees);
void init(int prec);
public:
Circle();
Circle(int prec);
int getNumVertices();
int getNumIndices();
std::vector<int> getIndices();
std::vector<glm::vec3> getVertices();
};
#include "Circle.h"
#include <math.h>
float Circle::toRadians(float degrees) {
float pi = acos(-1.0);
return (degrees * 2.0f * pi) / 360.0f;
}
void Circle::init(int prec)
{
numVertices = prec + 1;
numIndices = prec * 3;
for (int i = 0; i < numVertices; i++)
{
vertices.push_back(glm::vec3());
}
for (int i = 0; i < numIndices; i++)
{
indices.push_back(0);
}
for (int i = 0; i < prec; i++)
{
float degrees = i * 360.0f / prec;
float radians = toRadians(degrees);
float y = sin(radians);
float x = cos(radians);
vertices[i] = glm::vec3(x, y, 0.0f);
}
//计算索引坐标
for (int i = 0; i < prec; i++)
{
if (i == prec - 1)
{
indices[3 * i + 0] = i;
indices[3 * i + 1] = 0;
indices[3 * i + 2] = prec;
break;
}
indices[3 * i + 0] = i;
indices[3 * i + 1] = i + 1;
indices[3 * i + 2] = prec;
}
}
Circle::Circle(){}
Circle::Circle(int prec) { init(prec); }
vector<int> Circle::getIndices() { return indices; }
vector<glm::vec3> Circle::getVertices() { return vertices; }
vector<glm::vec2> Circle::getTexCoords() { return texCoords; }
vector<glm::vec3> Circle::getNormals() { return normals; }
int Circle::getNumIndices() { return numIndices; }
int Circle::getNumVertices() { return numVertices; }
运行代码
#define GLEW_STATIC
#include <iostream>
#include "Camera.h"
#include "Circle.h"
#include "Shader.h"
#include <GL/glew.h>
#include <glm/glm.hpp>
#include <glm\gtc\type_ptr.hpp> // glm::value_ptr
#include <glm\gtc\matrix_transform.hpp>
#include <GLFW/glfw3.h>
#include <SOIL2/SOIL2.h>
using namespace std;
Circle myCircle = Circle(48);
GLuint VAO, VBO[3];
GLuint texture;
Shader myShader;
Camera myCamera(glm::vec3(0.0f, 0.0f, 2.0f));
GLFWwindow* window;
float deltaTime = 0.0f; // time between current frame and last frame
float lastFrame = 0.0f;
float lastX = 400.f;
float lastY = 300.f;
bool firstMouse = true;
void processInput(GLFWwindow* window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, true);
}
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
{
myCamera.ProcessKeyboard(FORWARD, deltaTime);
}
else if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
{
myCamera.ProcessKeyboard(BACKWARD, deltaTime);
}
else if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
{
myCamera.ProcessKeyboard(LEFT, deltaTime);
}
else if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
{
myCamera.ProcessKeyboard(RIGHT, deltaTime);
}
}
void mouse_callback(GLFWwindow* window, double xPos, double yPos)
{
if (firstMouse)
{
lastX = xPos;
lastY = yPos;
firstMouse = false;
}
float deltaX, deltaY;
deltaX = xPos - lastX;
deltaY = lastY - yPos;
lastX = xPos;
lastY = yPos;
myCamera.ProcessMouseMovement(deltaX, deltaY);
}
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
myCamera.ProcessMouseScroll(yoffset);
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
// make sure the viewport matches the new window dimensions; note that width and
// height will be significantly larger than specified on retina displays.
glViewport(0, 0, width, height);
}
void setupVertices()
{
vector<float> pvalues; //顶点坐标
vector<float> tvalues; //纹理坐标
vector<float> nvalues; //法线
vector<int> ind = myCircle.getIndices();
vector<glm::vec3> verts = myCircle.getVertices();
vector<glm::vec2> tex = myCircle.getTexCoords();
vector<glm::vec3> norm = myCircle.getNormals();
for (int i = 0; i < myCircle.getNumIndices(); i++)
{
pvalues.push_back(verts[ind[i]].x);
pvalues.push_back(verts[ind[i]].y);
pvalues.push_back(verts[ind[i]].z);
tvalues.push_back(tex[ind[i]].s);
tvalues.push_back(tex[ind[i]].t);
nvalues.push_back(norm[ind[i]].x);
nvalues.push_back(norm[ind[i]].y);
nvalues.push_back(norm[ind[i]].z);
}
glGenVertexArrays(1, &VAO);
glGenBuffers(3, VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, pvalues.size() * 4, &pvalues[0], GL_STATIC_DRAW);
}
void init(GLFWwindow* window)
{
myShader = Shader("circleVert.vert", "circleFrag.frag");
glfwSetCursorPosCallback(window, mouse_callback);
glfwSetCursorPosCallback(window, mouse_callback);
glfwSetScrollCallback(window, scroll_callback);
setupVertices();
}
void display(GLFWwindow* window, double currentTime)
{
float currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//输入
processInput(window);
myShader.use();
glm::mat4 projection = glm::perspective(glm::radians(myCamera.Zoom), 800.0f / 600.0f, 0.1f, 100.0f);
glm::mat4 view = myCamera.GetViewMatrix();
glm::mat4 model = glm::mat4(1.0f);
myShader.setMat4("projection", projection);
myShader.setMat4("view", view);
myShader.setMat4("model", model);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, myCircle.getNumIndices());
}
int main() {
if(!glfwInit()) {
exit(EXIT_FAILURE);
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
GLFWwindow* window = glfwCreateWindow(800, 600, "Circle", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK) { exit(EXIT_FAILURE); }
//glfwSwapInterval(1);
glViewport(0, 0, 800, 600);
//glEnable(GL_DEPTH_TEST);
init(window);
while (!glfwWindowShouldClose(window)) {
display(window, glfwGetTime());
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}
着色器
#version 330
layout (location = 0) in vec3 aPos;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
}
#version 330
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}