MySphere.h
#ifndef _MY_SPHERE_H_
#define _MY_SPHERE_H_
#include <vgl.h>
#include <vec.h>
struct MySphereVertex {
vec4 position;
vec4 color;
};
class MySphere {
public :
int m_numLaSlice, m_numLoSlice; // latitude(위도=가로 단면의 갯수), longitude(경도=세로 단면의 갯수)
int m_numVertices;
GLuint m_vao;
GLuint m_vbo;
bool m_bInit;
MySphere() {
m_numLaSlice = 0;
m_numLaSlice = 0;
m_numVertices = 0;
m_bInit = false;
}
void init(int laSlice, int loSlice, float r = 1.0f) {
m_numLaSlice = laSlice;
m_numLoSlice = loSlice;
m_numVertices = loSlice * 2 * 3 + (laSlice - 2) * loSlice * 2 * 3; // 위 아래 뚜껑의 삼각형 갯수 + 뚜껑을 제외한 단면(사각형)의 갯수(laSlice - 2)
MySphereVertex* vertices = new MySphereVertex[m_numVertices];
float dphi = 3.141592f / laSlice;
float dtheta = 2 * 3.141592 / loSlice;
int cur = 0;
for (int j = 0; j < m_numLaSlice; j++) {
float y1 = r * cos(dphi * j);
float r1 = r * sin(dphi * j);
float y2 = r * cos(dphi * (j + 1));
float r2 = r * sin(dphi * (j + 1));
for (int i = 0; i < m_numLoSlice; i++) {
float x1 = cos(dtheta * i);
float z1 = sin(dtheta * i);
float x2 = cos(dtheta * (i + 1));
float z2 = sin(dtheta * (i + 1));
vec4 a = vec4(r1 * x1, y1, r1 * z1, 1);
vec4 b = vec4(r1 * x2, y1, r1 * z2, 1);
vec4 c = vec4(r2 * x1, y2, r2 * z1, 1);
vec4 d = vec4(r2 * x2, y2, r2 * z2, 1);
vec4 color = vec4(0.5, 0.5, 0.5, 1);
if ((i + j) % 2 == 1) color = vec4(0.8, 0.8, 0.8, 1);
if (j != 0) {
vertices[cur].position = a; vertices[cur].color = color; cur++;
vertices[cur].position = b; vertices[cur].color = color; cur++;
vertices[cur].position = c; vertices[cur].color = color; cur++;
}
if (j != laSlice - 1) {
vertices[cur].position = c; vertices[cur].color = color; cur++;
vertices[cur].position = d; vertices[cur].color = color; cur++;
vertices[cur].position = b; vertices[cur].color = color; cur++;
}
}
}
if (m_bInit == false) {
glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao);
glGenBuffers(1, &m_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
}
else {
glBindVertexArray(m_vao);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
}
glBufferData(GL_ARRAY_BUFFER, sizeof(MySphereVertex) * m_numVertices, vertices, GL_STATIC_DRAW);
delete[] vertices;
m_bInit = true;
}
void connectShader(GLuint prog) {
GLuint vPosition = glGetAttribLocation(prog, "vPosition");
glEnableVertexAttribArray(vPosition);
glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, sizeof(MySphereVertex), BUFFER_OFFSET(0));
GLuint vColor = glGetAttribLocation(prog, "vColor");
glEnableVertexAttribArray(vColor);
glVertexAttribPointer(vColor, 4, GL_FLOAT, GL_FALSE, sizeof(MySphereVertex), BUFFER_OFFSET(sizeof(vec4)));
}
void draw(GLuint prog) {
glBindVertexArray(m_vao);
glUseProgram(prog);
connectShader(prog);
glDrawArrays(GL_TRIANGLES, 0, m_numVertices);
}
};
#endif
MySphere.cpp
#include <vgl.h>
#include <vec.h>
#include <InitShader.h>
#include "MySphere.h"
GLuint program;
MySphere sphere;
void myInit() {
sphere.init(16, 16, 0.7);
// 3. load shaders
program = InitShader("vshader.glsl", "fshader.glsl");
glUseProgram(program);
}
float myTime = 0;
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glUseProgram(program);
GLuint uTime = glGetUniformLocation(program, "uTime");
glUniform1f(uTime, myTime);
sphere.draw(program);
glFlush();
}
bool bPlay = true;
void idle() {
if (bPlay) myTime += 0.0333f;
Sleep(33);
glutPostRedisplay();
}
void keyboard(unsigned char key, int x, int y) {
switch (key) {
case '1':
//sphere.increase();
break;
case '2':
//sphere.decrease();
break;
case ' ':
printf("stop or play! \n");
bPlay = !bPlay;
break;
default:
break;
}
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(800, 800);
glutCreateWindow("A Color Cube");
glewExperimental = true;
glewInit();
myInit();
glutDisplayFunc(display);
glutIdleFunc(idle);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
vshader.glsl
#version 330
uniform float uTime;
in vec4 vPosition;
in vec4 vColor;
out vec4 color;
out vec4 position;
void main() {
float scale = 1 + sin(uTime);
float ang = uTime*90/180.0f*3.141592f;
mat4 m1 = mat4(1.0f);
// x-rotation
m1[1][1] = cos(ang);
m1[2][1] = -sin(ang);
m1[1][2] = sin(ang);
m1[2][2] = cos(ang);
mat4 m2 = mat4(1.0f);
// z-rotation
/*m[0][0] = cos(ang);
m[1][0] = -sin(ang);
m[0][1] = sin(ang);
m[1][1] = cos(ang);*/
// x-rotation
/*m[1][1] = cos(ang);
m[2][1] = -sin(ang);
m[1][2] = sin(ang);
m[2][2] = cos(ang);*/
// y-rotation
m2[0][0] = cos(ang);
m2[2][0] = sin(ang);
m2[0][2] = -sin(ang);
m2[2][2] = cos(ang);
gl_Position = m2*m1*vPosition;
gl_Position.w = 1.0f;
color = vColor;
position = vPosition;
}
fshader.glsl
#version 330
in vec4 color;
in vec4 position;
out vec4 fColor;
void main() {
fColor = color;
}