[컴퓨터그래픽스] 실습: MySphere

Serun1017·2024년 10월 23일
0

컴퓨터그래픽스

목록 보기
20/31

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;
}

0개의 댓글