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
#include
#include
#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