现在的位置: 首页 > 综合 > 正文

OpenGL 3:画圆

2014年09月05日 ⁄ 综合 ⁄ 共 2197字 ⁄ 字号 评论关闭

这次使用OpenGL画圆,并且中间画一个实心的五角星。

1. 画实心五角:

因为之前使用Polygen画会出现问题,也许是各个GPU硬件也会不一样的,所以使用Polygen画实心五角星并不可靠;

所以这里直接使用三角形画出五角星,不需要Polygen。

2 画圆

因为GLEW里面没有现成的圆形,所以只能使用人工定顶点,然后画圆的方法;

其中的数学原理可以参考这里:http://slabode.exofire.net/circle_draw.shtml

最后得到效果:

很漂亮,很标准的五角星外加一个圆形。

注:本程序只使用Vertex Buffer,没使用Index Buffer

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

namespace Tutorial2_Tri_pentagram
{
	GLuint VBO;
	const static float PI = 3.1415926f;
	const static double toPI = PI/180.0;
	const static double penR = 0.8;
	const static double penInR = penR * sin(18.0*toPI) / sin(126.0*toPI);

	void DrawCircle(Vector3f *vers, int offset,
		float cx, float cy, float r, int num_segments) 
	{
		for(int i = 0; i < num_segments; i++) 
		{ 
			//get the current angle 
			float theta = 2.0f * PI * float(i) / float(num_segments);
			
			float x = r * cosf(theta);//calculate the x component 
			float y = r * sinf(theta);//calculate the y component 

			vers[offset+i] = Vector3f(x + cx, y + cy, 0.0f);//output vertex 
		}
	}

	void createGeometry()
	{
		Vector3f vers[10];
		
		for (int i = 0, k = 0; i < 10; i+=2, k++)
		{
			vers[i].x = (float)(penR * cos((18.0+72.0*k)*toPI));
			vers[i].y = (float)(penR * sin((18.0+72.0*k)*toPI));
			vers[i].z = 0.0f;
			vers[i+1].x = (float)(penInR * cos((72.0*k+54.0)*toPI));
			vers[i+1].y = (float)(penInR * sin((72.0*k+54.0)*toPI));
			vers[i+1].z = 0.0f;
		}

		Vector3f vers2[412] = 
		{
			vers[0], vers[4], vers[5], vers[0], vers[5], vers[6],
			vers[2], vers[6], vers[7], vers[2], vers[7], vers[8]
		};
		DrawCircle(vers2, 12, 0.0f, 0.0f, (float)penR, 400);

		glGenBuffers(1, &VBO);
		glBindBuffer(GL_ARRAY_BUFFER, VBO);
		glBufferData(GL_ARRAY_BUFFER, sizeof(vers2), vers2, 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_TRIANGLES, 0, 12);
		glDrawArrays(GL_LINE_LOOP, 12, 400);

		glDisableVertexAttribArray(0);

		glutSwapBuffers();
	}

	void initCallBack()
	{
		glutDisplayFunc(renderScene);
	}

	int run(int argc, char **argv)
	{
		glutInit(&argc, argv);
		glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
		glutInitWindowSize(800, 600);
		glutInitWindowPosition(50, 50);
		glutCreateWindow("Bill's Another Pentagram");

		initCallBack();

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

		createGeometry();

		glClearColor(0.0f, 0.6f, 0.2f, 0.0f);

		glutMainLoop();

		return 0;
	}
}

抱歉!评论已关闭.