OpenGL 平面圆绘制与贴图

                两种画圆的方法,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 64GLubyte 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           

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

猜你喜欢

转载自blog.csdn.net/ytffhew/article/details/86580304