-
-
Save chris-zen/12c3e6bb8dd85af507d742eccc799e05 to your computer and use it in GitHub Desktop.
[OpenGL] An example to draw a sphere with vao and vbo
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment