首页 > 代码库 > OpenGL 4 : 一个美丽的心 For you, My Love

OpenGL 4 : 一个美丽的心 For you, My Love

画一个心形有很多公式可以使用,下面这个公式我认为最完美了:

float x = R * 16 * pow(sin(theta), 3);
float y = R * (13 * cos(theta) - 5*cos(2*theta)	- 2*cos(3*theta) - cos(4*theta));

画出来的心形最漂亮,最原始的笛卡尔的心形是个肥心,没这个好看,呵呵。

效果如下:



数学参考:

http://mathworld.wolfram.com/HeartCurve.html

http://www.mathematische-basteleien.de/heart.htm


#pragma once
#include <stdio.h>
#include <gl\glew.h>
#include <GL\freeglut.h>
#include "math_3d.h"
#include <cmath>

namespace Tutorial2_Heart
{
	const static float PI = 3.1415926f;
	int gSegments;
	GLuint VBO;

	void genHeart_2(Vector3f *vers, int offset, int segments,
		float ox, float oy, float R = 0.05)
	{
		for (int i = 0; i < segments; i++)
		{
			float theta = 2.0f * PI * float(i) / float(segments);

			float x = R * 16 * pow(sin(theta), 3);
			float y = R * (13 * cos(theta) - 5*cos(2*theta)
				- 2*cos(3*theta) - cos(4*theta));

			vers[offset+i] = Vector3f(ox+x, oy+y, 0.0f);
		}
	}

	void genGeometry()
	{
		const int segments = 360;
		Vector3f vers[segments];
		gSegments = segments;
		genHeart_2(vers, 0, segments, 0.f, 0.f);

		glGenBuffers(1, &VBO);
		glBindBuffer(GL_ARRAY_BUFFER, VBO);
		glBufferData(GL_ARRAY_BUFFER, sizeof(vers), vers, GL_STATIC_DRAW);
	}

	static void renderScene()
	{
		glClear(GL_COLOR_BUFFER_BIT);

		glEnableVertexAttribArray(0);
		glBindBuffer(GL_ARRAY_BUFFER, VBO);
		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

		glDrawArrays(GL_LINE_LOOP, 0, gSegments);

		glDisableVertexAttribArray(0);

		glutSwapBuffers();
	}

	void initCallBack()
	{
		glutDisplayFunc(renderScene);
	}

	int run(int argv, char **argc)
	{
		glutInit(&argv, argc);
		glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
		glutInitWindowSize(600, 600);
		glutInitWindowPosition(50, 50);
		glutCreateWindow("Heart Shape");

		initCallBack();

		GLenum res = glewInit();
		if (res != GLEW_OK)
		{
			fprintf(stderr, "Error:'%s'\n", glewGetErrorString(res));
			return 1;
		}

		genGeometry();

		glClearColor(0.8f, 0.1f, 0.1f, 0.0f);

		glutMainLoop();

		return 0;
	}
}