Last active
November 21, 2022 09:22
-
-
Save zwzmzd/0195733fa1210346b00d to your computer and use it in GitHub Desktop.
[OpenGL] An example to draw a sphere with vao and vbo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "sphere.h" | |
#include <vector> | |
#include <iostream> | |
#include <glm/gtc/matrix_inverse.hpp> | |
#include <glm/gtc/type_ptr.hpp> | |
#include <glm/gtx/string_cast.hpp> | |
Sphere::Sphere() | |
{ | |
isInited = false; | |
m_vao = 0; | |
m_vboVertex = 0; | |
m_vboIndex = 0; | |
lats = 40; | |
longs = 40; | |
} | |
Sphere::~Sphere() | |
{ | |
} | |
void Sphere::init(GLuint vertexPositionID) | |
{ | |
int i, j; | |
std::vector<GLfloat> vertices; | |
std::vector<GLuint> indices; | |
int indicator = 0; | |
for(i = 0; i <= lats; i++) { | |
double lat0 = glm::pi<double>() * (-0.5 + (double) (i - 1) / lats); | |
double z0 = sin(lat0); | |
double zr0 = cos(lat0); | |
double lat1 = glm::pi<double>() * (-0.5 + (double) i / lats); | |
double z1 = sin(lat1); | |
double zr1 = cos(lat1); | |
for(j = 0; j <= longs; j++) { | |
double lng = 2 * glm::pi<double>() * (double) (j - 1) / longs; | |
double x = cos(lng); | |
double y = sin(lng); | |
vertices.push_back(x * zr0); | |
vertices.push_back(y * zr0); | |
vertices.push_back(z0); | |
indices.push_back(indicator); | |
indicator++; | |
vertices.push_back(x * zr1); | |
vertices.push_back(y * zr1); | |
vertices.push_back(z1); | |
indices.push_back(indicator); | |
indicator++; | |
} | |
indices.push_back(GL_PRIMITIVE_RESTART_FIXED_INDEX); | |
} | |
// 创建并绑定环境 | |
glGenVertexArrays(1, &m_vao); | |
glBindVertexArray(m_vao); | |
glGenBuffers(1, &m_vboVertex); | |
glBindBuffer(GL_ARRAY_BUFFER, m_vboVertex); | |
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), &vertices[0], GL_STATIC_DRAW); | |
glVertexAttribPointer(vertexPositionID, 3, GL_FLOAT, GL_FALSE, 0, NULL); | |
glEnableVertexAttribArray (vertexPositionID); | |
glGenBuffers(1, &m_vboIndex); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vboIndex); | |
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), &indices[0], GL_STATIC_DRAW); | |
numsToDraw = indices.size(); | |
isInited = true; | |
} | |
void Sphere::cleanup() | |
{ | |
if (!isInited) { | |
return; | |
} | |
if(m_vboVertex) { | |
glDeleteBuffers(1, &m_vboVertex); | |
} | |
if(m_vboIndex) { | |
glDeleteBuffers(1, &m_vboIndex); | |
} | |
if (m_vao) { | |
glDeleteVertexArrays(1, &m_vao); | |
} | |
isInited = false; | |
m_vao = 0; | |
m_vboVertex = 0; | |
m_vboIndex = 0; | |
} | |
void Sphere::draw() | |
{ | |
if (!isInited) { | |
std::cout << "please call init() before draw()" << std::endl; | |
} | |
// draw sphere | |
glBindVertexArray(m_vao); | |
glEnable(GL_PRIMITIVE_RESTART); | |
glPrimitiveRestartIndex(GL_PRIMITIVE_RESTART_FIXED_INDEX); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vboIndex); | |
glDrawElements(GL_QUAD_STRIP, numsToDraw, GL_UNSIGNED_INT, NULL); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef SPHERE_H | |
#define SPHERE_H | |
#include <GL/glew.h> | |
class Sphere | |
{ | |
public: | |
Sphere(); | |
~Sphere(); | |
void init(GLuint vertexPositionID); | |
void cleanup(); | |
void draw(); | |
private: | |
int lats, longs; | |
bool isInited; | |
GLuint m_vao, m_vboVertex, m_vboIndex; | |
int numsToDraw; | |
}; | |
#endif // SPHERE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 120 | |
void main(){ | |
// Output color = color of the texture at the specified UV | |
gl_FragColor = vec4 (1.0, 0.0, 0.0, 1.0); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 120 | |
// Input vertex data, different for all executions of this shader. | |
attribute vec3 vertexPosition_modelspace; | |
// Output data ; will be interpolated for each fragment. | |
varying vec2 UV; | |
uniform mat4 projMatrix; | |
uniform mat4 mvMatrix; | |
void main() | |
{ | |
gl_Position = projMatrix * mvMatrix * vec4(vertexPosition_modelspace, 1); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void initializeGL() | |
{ | |
// Load shaders, link program for drawing sphere | |
m_sphereProgramID = LoadShaders("shader/sphereShader.vert", "shader/sphereShader.frag"); | |
GLuint vertexPosition_modelspaceID = glGetAttribLocation(m_sphereProgramID, "vertexPosition_modelspace"); | |
// load OpenGL resources needed by the sphere | |
// pass the vertex position id to it | |
sphere.init(vertexPosition_modelspaceID); | |
} | |
void paintGL() { | |
// use corresponding shader program, and set the transformation matrices | |
glUseProgram(m_sphereProgramID); | |
GLuint projMatrixID = glGetUniformLocation(m_sphereProgramID, "projMatrix"); | |
GLuint mvMatrixID = glGetUniformLocation(m_sphereProgramID, "mvMatrix"); | |
glUniformMatrix4fv(projMatrixID, 1, GL_FALSE, glm::value_ptr(m_projMatrix)); | |
glUniformMatrix4fv(mvMatrixID, 1, GL_FALSE, glm::value_ptr(m_mvMatrix)); | |
sphere.draw(); | |
} | |
void cleanUp() { | |
sphere.cleanup(); | |
} |
That's not how you use GL_PRIMITIVE_RESTART_FIXED_INDEX.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice code, but how to set up the UV coordinates, I tried to add uv, but nothings draws.