ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

OpenGL 平面圆绘制与贴图

2019-03-09 15:48:48  阅读:371  来源: 互联网

标签:贴图 1.0 OpenGL float vertex texcoord factor GL 绘制


分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net

两种画圆的方法,DrawCircle2()为一般的做法,利用GL_LINE_STRIP实现,
void DrawCircle2(float cx, float cy, float r, int num_segments)
{
	glBegin(GL_LINE_STRIP);
	for (int i = 0; i <= num_segments; i++)
	{
		glVertex2f(cx + r * cos((2 * M_PI * i) / num_segments), 
			   cy + r * sin((2 * M_PI * i) / num_segments));
	}
	glEnd();
}
DrawCircle1()则是利用GL_LINES_LOOP实现,
void DrawCircle1(float cx, float cy, float r, int num_segments) 
{ 
	float theta = 2 * M_PI / float(num_segments); 
	float tangetial_factor = tanf(theta);//calculate the tangential factor 
	float radial_factor = cosf(theta);//calculate the radial factor 
	float x = r;//we start at angle = 0 
	float y = 0; 

	glBegin(GL_LINE_LOOP); 
	for(int ii = 0; ii < num_segments; ii++) 
	{ 
		glVertex2f(x + cx, y + cy);//output vertex 
		//calculate the tangential vector 
		//remember, the radial vector is (x, y) 
		//to get the tangential vector we flip those coordinates and negate one of them 
		float tx = -y; 
		float ty = x; 
		//add the tangential vector 
		x += tx * tangetial_factor; 
		y += ty * tangetial_factor; 
		//correct using the radial factor 
		x *= radial_factor; 
		y *= radial_factor; 
	} 
	glEnd(); 
}

但是上面两个函数都只是画出了两个圆圈,想要给circle贴图,必须画出的是一个区域,所以可以利用GL_TRIANGLE_FAN绘制,要实现纹理映射,关键是纹理坐标的分配:

圆心纹理坐标为:(0.5, 0.5)选取图片的中心。

圆圈上的点的分配:

纹理坐标必须在0,1之间,而且这些纹理坐标和圆的半径没有关系,只和圆心角有关。

因为-1< cos(delta_angle*i) <1,则==> 0 <= (cos(delta_angle*i) + 1.0)*0.5 <= 1

同理:0 <= (sin(delta_angle*i) + 1.0)*0.5 <= 1

GLvoid draw_circle(const GLfloat radius,const GLuint num_vertex)
{
	GLfloat vertex[4]; 
	GLfloat texcoord[2];

	const GLfloat delta_angle = 2.0*M_PI/num_vertex;

	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D,texName);
	glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
	glBegin(GL_TRIANGLE_FAN);

	//draw the vertex at the center of the circle
	texcoord[0] = 0.5;
	texcoord[1] = 0.5;
	glTexCoord2fv(texcoord);
	vertex[0] = vertex[1] = vertex[2] = 0.0;
	vertex[3] = 1.0;        
	glVertex4fv(vertex);

	//draw the vertex on the contour of the circle
	for(int i = 0; i < num_vertex ; i++)
	{
		texcoord[0] = (std::cos(delta_angle*i) + 1.0)*0.5;
		texcoord[1] = (std::sin(delta_angle*i) + 1.0)*0.5;
		glTexCoord2fv(texcoord);

		vertex[0] = std::cos(delta_angle*i) * radius;
		vertex[1] = std::sin(delta_angle*i) * radius;
		vertex[2] = 0.0;
		vertex[3] = 1.0;
		glVertex4fv(vertex);
	}

	texcoord[0] = (1.0 + 1.0)*0.5;
	texcoord[1] = (0.0 + 1.0)*0.5;
	glTexCoord2fv(texcoord);

	vertex[0] = 1.0 * radius;
	vertex[1] = 0.0 * radius;
	vertex[2] = 0.0;
	vertex[3] = 1.0;
	glVertex4fv(vertex);
	glEnd();

	glDisable(GL_TEXTURE_2D);
}

最终的效果见下图:

 

完整代码如下:

#include <windows.h>
#include <GL/glut.h>
#include <math.h>

#pragma comment(lib,"glut32.lib")
#pragma comment(lib,"glu32.lib")
#pragma comment(lib,"opengl32.lib")

GLfloat spin = 0.0;

#define M_PI 3.1415926

#define checkImageWidth  64
#define checkImageHeight 64
GLubyte checkImage [checkImageWidth][checkImageHeight][4];
GLuint texName;

void DrawCircle2(float cx, float cy, float r, int num_segments)
{
	glBegin(GL_LINE_STRIP);
	for (int i = 0; i <= num_segments; i++)
	{
		glVertex2f(cx + r * cos((2 * M_PI * i) / num_segments), 
			cy + r * sin((2 * M_PI * i) / num_segments));
	}
	glEnd();
}
void DrawCircle1(float cx, float cy, float r, int num_segments) 
{ 
	float theta = 2 * M_PI / float(num_segments); 
	float tangetial_factor = tanf(theta);//calculate the tangential factor 
	float radial_factor = cosf(theta);//calculate the radial factor 
	float x = r;//we start at angle = 0 
	float y = 0; 

	glBegin(GL_LINE_LOOP); 
	for(int ii = 0; ii < num_segments; ii++) 
	{ 
		glVertex2f(x + cx, y + cy);//output vertex 
		//calculate the tangential vector 
		//remember, the radial vector is (x, y) 
		//to get the tangential vector we flip those coordinates and negate one of them 
		float tx = -y; 
		float ty = x; 
		//add the tangential vector 
		x += tx * tangetial_factor; 
		y += ty * tangetial_factor; 
		//correct using the radial factor 
		x *= radial_factor; 
		y *= radial_factor; 
	} 
	glEnd(); 
}
GLvoid draw_circle(const GLfloat radius,const GLuint num_vertex)
{
	GLfloat vertex[4]; 
	GLfloat texcoord[2];

	const GLfloat delta_angle = 2.0 * M_PI / num_vertex;

	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, texName);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

	glBegin(GL_TRIANGLE_FAN);
	{
		//draw the vertex at the center of the circle
		texcoord[0] = 0.5;
		texcoord[1] = 0.5;
		glTexCoord2fv(texcoord);
		vertex[0] = vertex[1] = vertex[2] = 0.0;
		vertex[3] = 1.0;        
		glVertex4fv(vertex);

		//draw the vertex on the contour of the circle
		for(GLuint i = 0; i < num_vertex ; i++)
		{
			texcoord[0] = (cos(delta_angle * i) + 1.0) * 0.5;
			texcoord[1] = (sin(delta_angle * i) + 1.0) * 0.5;
			glTexCoord2fv(texcoord);

			vertex[0] = cos(delta_angle * i) * radius;
			vertex[1] = sin(delta_angle * i) * radius;
			vertex[2] = 0.0;
			vertex[3] = 1.0;
			glVertex4fv(vertex);
		}

		texcoord[0] = (1.0 + 1.0) * 0.5;
		texcoord[1] = (0.0 + 1.0) * 0.5;
		glTexCoord2fv(texcoord);

		vertex[0] = 1.0 * radius;
		vertex[1] = 0.0 * radius;
		vertex[2] = 0.0;
		vertex[3] = 1.0;
		glVertex4fv(vertex);
	}
	glEnd();

	glDisable(GL_TEXTURE_2D);
}
void makeCheckImage()
{
	int i, j, c;
	for (i = 0; i < checkImageHeight; i++)
	{
		for (j = 0; j < checkImageWidth; j++)
		{
			c = (((i & 0x8) == 0) ^ ((j & 0x8)) == 0) * 255;
			checkImage[i][j][0] = (GLubyte)c;
			checkImage[i][j][1] = (GLubyte)c;
			checkImage[i][j][2] = (GLubyte)c;
			checkImage[i][j][3] = (GLubyte)255;
		}
	}
}
void init()
{
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glShadeModel(GL_SMOOTH);

// 	glEnable(GL_DEPTH_TEST);
// 	glClearDepth(1.0);
	makeCheckImage();
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

	glGenTextures(1, &texName);
	glBindTexture(GL_TEXTURE_2D, texName);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth, checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage);
}
void display(void)
{
	glLineWidth(3.0);
	glColor3f(1.0, 1.0, 1.0);
	DrawCircle2(0.0, 0.0, 2.0, 20);
	glColor3f(1.0, 1.0, 0.0);
	DrawCircle1(0.0, 0.0, 1.5, 20);
	glColor3f(1.0, 0.0, 1.0);
	draw_circle(1.0, 20);

    glFlush ();

    glutSwapBuffers();
}

void reshape (int w, int h)
{
	if (h == 0)
	{
		h = 1;
	}
    glViewport (0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0, (GLfloat)w / (GLfloat)h, 1.0, 20.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glTranslatef(0.0, 0.0, -5.0);
}
void spinDisplay(void)
{
    spin = spin + 1.0;
    if (spin > 360.0)
	{
		spin = spin - 360.0;
	}
    glutPostRedisplay();
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize (500, 500); 
    glutInitWindowPosition (100, 100);
    glutCreateWindow (argv[0]);
    init ();
    glutDisplayFunc(display); 
    glutReshapeFunc(reshape);
    glutIdleFunc(spinDisplay);
    glutMainLoop();
    return 0;
}

运行结果如下:

http://blog.csdn.net/ryfdizuo/article/details/3968697

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net

标签:贴图,1.0,OpenGL,float,vertex,texcoord,factor,GL,绘制
来源: https://www.cnblogs.com/sownchz/p/10501103.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有