简体   繁体   中英

How to combine gl_lines with bezier?

I am trying to combine bezier point with gl_lines to create a face. When i was trying the code it shows the output as shows below. I have tried two methods by placing the bezier code after the face polygon and before the face polygon. It gives two different answers. I am trying to draw the mouth line onto the face.

// COLORFACE.cpp : Defines the entry point for the console application.

#include "stdafx.h"
#include<windows.h>
#include<GL/glut.h> // GL means folder. glut.h is in folder GL.
#include<GL/gl.h> // used in system
#include<math.h>

//angle of rotation for the camera direction
//float angle = 0.0f;
//actual vector representing the camera's direction
//float lx=0.0f,ly=0.0,lz=-10.0f;
//XZ position of the camera
//float x=0.0f,y=1.0f, z=-10.0f;

        float angle = 0.0f;
        float lx=0.0f,ly=0.0,lz=1.0f;
        float x=0.0f,y=1.0f, z=5.0f;
        float deltaAngle = 0.0f;
        float deltaMove = 0;
        float deltaMoveLR = 0;
        float deltaZoom=0.0f;
        float shearx=0.0f;
        float sheary=0.0f;
        float scalex=0.0f;
        float scaley=0.0f;
      /*  float mmx =-80;
        float mmy =-40;
        float mmx1 =4;
        float mmy1 =3;*/

        float mmx =70;
        float mmy =100;
        float mmz = 1000;
        float mmx1 =4;
        float mmy1 =3;
        float mmz1 = 1;
        float upperlip=0.0f;
        float lowerlip=0.0f;
        float upperleftlip=0.0;
        float lowerleftlip=0.0f;
        float upperrightlip=0.0f;
        float lowerrightlip=0.0f;

        int w=640;
        int h=480;

 // Initial display-window size
        GLsizei winWidth =800, winHeight=4000;
        // Set coordinate limits for the clipping window
        GLfloat xwcMin = 10.0, xwcMax = 500.0;
        GLfloat ywcMin = 0.0, ywcMax = 500.0;
        GLfloat zwcMin = 0.0, zwcMax = 500.0;

        class wcPt3D
        {
        public:
        GLfloat x,y,z;
        };

void myInit(void)
{
glClearColor(1.0, 1.0, 1.0, 1.0); // set the background to white
//glColor3f(0.0, 0.0, 0.0); // set the drawing color to black
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,640.0,0.0,480.0);
// Set the correct perspective.
gluPerspective(0.0f, 0.0f, 0.0f, 0.0f);
}

  void plotPoint (wcPt3D bezCurvePt)
        {
        glBegin (GL_POINTS); // Plot control points
        glVertex2f(bezCurvePt.x, bezCurvePt.y);
        glEnd(); // Done drawing the GL_POINTS
        }

        void binomialCoeffs (GLint n, GLint *C)
        {
        GLint k,j;
        for (k=0; k<=n; k++) // Compute n!/(k!(n-k)!)
        {
        C[k] = 1;
        for (j=n; j>=k+1; j--)
        C[k] *= j;
        for (j=n-k; j>=2; j--)
        C[k] /= j;
        }
        }

        void computeBezPt (GLfloat u, wcPt3D * bezPt, GLint nCtrlPts, wcPt3D * ctrlPts, GLint*C)
        {
        GLint k, n=nCtrlPts -1;
        GLfloat bezBlendFcn;
        bezPt->x = bezPt->y = bezPt-> z = 0.0;
        // Compute blending functions and blen control points
        for (k=0; k<nCtrlPts; k++)
        {
        bezBlendFcn = C[k] *pow(u,k) * pow (1-u,n-k);
        bezPt->x +=ctrlPts[k].x * bezBlendFcn;
        bezPt->y +=ctrlPts[k].y * bezBlendFcn;
        bezPt->z +=ctrlPts[k].z * bezBlendFcn;
        }
        }

        void bezier(wcPt3D * ctrlPts,GLint nCtrlPts, GLint nBezCurvePts)
        {
        wcPt3D bezCurvePt;
        GLfloat u;
        GLint *C, k;
        // Allocate space for binomial coefficients
        C=new GLint [nCtrlPts];
        binomialCoeffs (nCtrlPts - 1,C);
        for (k=0; k<=nBezCurvePts; k++)
        {
        u=GLfloat (k) / GLfloat (nBezCurvePts);
        computeBezPt (u, &bezCurvePt, nCtrlPts, ctrlPts, C);
        plotPoint (bezCurvePt);
        }
        delete [] C;
        }

void hardwiredHouse()
{
GLint nCtrlPts27 = 3, nBezCurvePts = 10000;         //draw mouth line
        wcPt3D ctrlPts27 [3] =
        {
        {(-50+mmx)*mmx1+upperleftlip,(-75+mmy)*mmy1,10000},
        {(0+mmx)*mmx1,(-75+mmy)*mmy1+upperlip,10000},        
        {(50+mmx)*mmx1+upperrightlip,(-75+mmy)*mmy1,10000},
        };

        GLint nCtrlPts28 = 3;       //draw lower lip 
        wcPt3D ctrlPts28 [3] =
        {
        {(-50+mmx)*mmx1+lowerleftlip,(-75+mmy)*mmy1,10000},
        {(0+mmx)*mmx1,(-110+mmy)*mmy1+lowerlip,10000},        
        {(50+mmx)*mmx1+lowerrightlip,(-75+mmy)*mmy1,10000}
        };      

        glClear (GL_COLOR_BUFFER_BIT); // Clear display window.
        glPointSize (4);
        glColor3f (0.0, 0.0, 0.0); // Set fill color = BLACK
        glRotatef(angle,0.0,0.0,1.0); // Create Rotation
        if(mmx1>0 && mmy1>0){ // Limit Shear or Scale
        bezier (ctrlPts27, nCtrlPts27, nBezCurvePts);
        bezier (ctrlPts28, nCtrlPts28, nBezCurvePts);

//hair falling
glColor3ub(0,0,0);
glBegin(GL_POLYGON);
glVertex2i(300,131);
glVertex2i(321,113);
glVertex2i(352,108);
glVertex2i(380,108);
glVertex2i(412,118);
glVertex2i(441,142);
glVertex2i(458,180);
glVertex2i(458,215);
glVertex2i(457,243);
glVertex2i(449,284);
glVertex2i(447,306);
glVertex2i(443,334);
glVertex2i(441,388);
glVertex2i(422,422);
glVertex2i(392,449);
glVertex2i(352,463);
glVertex2i(320,472);
glVertex2i(268,483);
glVertex2i(250,484);
glVertex2i(224,484);
glVertex2i(155,474);
glVertex2i(112,454);
glVertex2i(77,417);
glVertex2i(73,404);
glVertex2i(66,362);
glVertex2i(45,299);
glVertex2i(35,266);
glVertex2i(32,231);
glVertex2i(27,198);
glVertex2i(35,164);
glVertex2i(57,132);
glVertex2i(81,115);
glVertex2i(101,106);
glVertex2i(126,103);
glVertex2i(148,107);
glVertex2i(169,113);
glVertex2i(186,126);
glVertex2i(189,132);
glEnd();

//face cutting
glColor3ub(210,137,0);
glBegin(GL_POLYGON);
glVertex2i(85,295);
glVertex2i(86,278);
glVertex2i(88,261);
glVertex2i(91,243);
glVertex2i(94,226);
glVertex2i(99,196);
glVertex2i(104,163);
glVertex2i(110,140);
glVertex2i(116,123);
glVertex2i(123,107);
glVertex2i(131,92);
glVertex2i(140,80);
glVertex2i(149,73);
glVertex2i(154,69);
glVertex2i(161,65);
glVertex2i(170,60);
glVertex2i(181,54);
glVertex2i(196,50);
glVertex2i(209,45);
glVertex2i(220,44);
glVertex2i(231,41);
glVertex2i(241,39);
glVertex2i(251,39);
glVertex2i(264,41);
glVertex2i(275,43);
glVertex2i(287,50);
glVertex2i(301,53);
glVertex2i(316,59);
glVertex2i(329,66);
glVertex2i(340,73);
glVertex2i(352,82);
glVertex2i(358,95);
glVertex2i(365,106);
glVertex2i(371,119);
glVertex2i(379,146);
glVertex2i(384,167);
glVertex2i(389,192);
glVertex2i(392,208);
glVertex2i(394,225);
glVertex2i(398,248);
glVertex2i(402,268);
glVertex2i(405,284);
glVertex2i(405,293);
glVertex2i(407,309);
glVertex2i(392,315);
glVertex2i(374,321);
glVertex2i(353,325);
glVertex2i(337,329);
glVertex2i(317,332);
glVertex2i(302,336);
glVertex2i(283,337);
glVertex2i(266,338);
glVertex2i(245,340);
glVertex2i(233,340);
glVertex2i(208,336);
glVertex2i(186,338);
glVertex2i(159,334);
glVertex2i(146,330);
glVertex2i(123,327);
glVertex2i(107,321);
glVertex2i(90,315);
glVertex2i(84,310);
glEnd();

//hair on face
glColor3ub(0,0,0);
glBegin(GL_POLYGON);
glVertex2i(90,342);
glVertex2i(87,336);
glVertex2i(84,323);
glVertex2i(83,305);
glVertex2i(83,276);
glVertex2i(107,270);
glVertex2i(108,250);
glVertex2i(133,251);
glVertex2i(137,273);
glVertex2i(161,273);
glVertex2i(163,251);
glVertex2i(183,255);
glVertex2i(199,261);
glVertex2i(212,272);
glVertex2i(226,278);
glVertex2i(236,287);
glVertex2i(242,293);
glVertex2i(263,278);
glVertex2i(275,270);
glVertex2i(295,262);
glVertex2i(315,254);
glVertex2i(322,251);
glVertex2i(323,271);
glVertex2i(351,269);
glVertex2i(351,249);
glVertex2i(376,249);
glVertex2i(378,270);
glVertex2i(411,268);
glVertex2i(413,286);
glVertex2i(415,304);
glVertex2i(413,321);
glVertex2i(398,336);
glVertex2i(355,348);
glVertex2i(305,366);
glVertex2i(266,370);
glVertex2i(234,373);
glVertex2i(193,375);
glVertex2i(154,369);
glVertex2i(117,354);
glVertex2i(94,338);
glVertex2i(90,334);
glEnd();

//hair
glColor3ub(0,0,0);
glBegin(GL_POLYGON);
glVertex2i(87,352);
glVertex2i(109,350);
glVertex2i(110,332);
glVertex2i(134,331);
glVertex2i(135,352);
glVertex2i(161,350);
glVertex2i(163,329);
glVertex2i(183,335);
glVertex2i(207,347);
glVertex2i(222,358);
glVertex2i(242,373);
glVertex2i(265,356);
glVertex2i(285,346);
glVertex2i(308,335);
glVertex2i(323,331);
glVertex2i(323,347);
glVertex2i(350,349);
glVertex2i(351,328);
glVertex2i(376,330);
glVertex2i(378,352);
glVertex2i(402,354);
glVertex2i(404,375);
glVertex2i(406,390);
glVertex2i(319,417);
glVertex2i(236,421);
glVertex2i(165,413);
glVertex2i(117,405);
glVertex2i(82,390);
glVertex2i(86,354);
glEnd();

//left eyebrow
glColor3ub(0,0,0);
glBegin(GL_LINE_STRIP);
glVertex2i(271,202);
glVertex2i(284,212);
glVertex2i(307,219);
glVertex2i(322,219);
glVertex2i(339,218);
glVertex2i(356,214);
glVertex2i(368,208);
glVertex2i(379,204);
glEnd();

//right eyebrow
glColor3ub(0,0,0);
glBegin(GL_LINE_STRIP);
glVertex2i(109,202);
glVertex2i(117,208);
glVertex2i(128,214);
glVertex2i(143,217);
glVertex2i(160,220);
glVertex2i(174,220);
glVertex2i(190,217);
glVertex2i(204,212);
glVertex2i(219,203);
glEnd();

//left eye
glColor3ub(255,255,255);
glBegin(GL_QUAD_STRIP);
glVertex2i(133,186);
glVertex2i(141,174);
glVertex2i(168,198);
glVertex2i(215,178);
glEnd();

//left eye lining
glColor3ub(0,0,0);
glBegin(GL_LINE_LOOP);
glVertex2i(133,186);
glVertex2i(141,174);
glVertex2i(215,178);
glVertex2i(168,198);
glEnd();

//right eye
glColor3ub(255,255,255);
glBegin(GL_QUAD_STRIP);
glVertex2i(360,186);
glVertex2i(352,174);
glVertex2i(325,198);
glVertex2i(278,178);
glEnd();

//right eye lining
glColor3ub(0,0,0);
glBegin(GL_LINE_LOOP);
glVertex2i(360,186);
glVertex2i(352,174);
glVertex2i(278,178);
glVertex2i(325,198);
glEnd();

    // right eye lens
    double radius=9.9; 
        glBegin(GL_POLYGON);
        glColor3f(0.0, 0.0, 0.0);
        for(float t=0; t<360; t++) {
        glVertex2f(325 + sin (t)*radius, (h-w/12.6*6+radius) + cos(t)*radius); //---500- x axis, 90 - y-axis
        }
        glEnd();


    //left eye lens 

    double radius1=9.9; 
        glBegin(GL_POLYGON);
        glColor3f(0.0, 0.0, 0.0);
        for(float t=0; t<360; t++) {
        glVertex2f(168 + sin (t)*radius, (h-w/12.6*6+radius) + cos(t)*radius); //---500- x axis, 90 - y-axis
        }
        glEnd();

//nose
glColor3ub(0,0,0);
glBegin(GL_LINE_STRIP);
glVertex2i(220,140);
glVertex2i(230,130);
glVertex2i(245,125);
glVertex2i(260,130);
glVertex2i(270,140);
glEnd();

////mouth
//glColor3ub(255,0,0);
//glBegin(GL_LINE_LOOP);
//glVertex2i(191,169);
//glVertex2i(292,169);
//glVertex2i(276,160);
//glVertex2i(245,153);
//glVertex2i(210,159);
//glVertex2i(189,170);
//glEnd();
}
}
  void winReshapeFcn (GLint newWidth, GLint newHeight)
        {
        glViewport (0, 0, newHeight, newHeight); // Maintain an aspect ratio of 1.0
        glMatrixMode (GL_PROJECTION);
        glLoadIdentity ();
        gluOrtho2D (xwcMin, xwcMax, ywcMin, ywcMax);
        glClear (GL_COLOR_BUFFER_BIT); // Clear display window
        }

void myDisplay(void) //for screen display
{
glClear( GL_COLOR_BUFFER_BIT );
hardwiredHouse();
glFlush();
}

void main( int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(640,480);
glutInitWindowPosition(100,100); // change posituon of window
glutCreateWindow("Chinese Girl");
glutDisplayFunc(myDisplay);
glutReshapeFunc (winReshapeFcn);
myInit();
glutMainLoop();
}

Your "two different output" images are missing, but presumably you inserted your bezier drawing code at the wrong point; either before the large planes for the face were drawn (so they get erased), or at a point where they get the wrong colors (the bezier routine in itself does not set a color so it uses what was set before).

You can put them anywhere after the //face cutting segment. Immediately before the line //hair on face works for me, although you need to insert an additional glColor3ub(0,0,0); before it to set the correct color.

中国姑娘,笑容很广


An improvement to your code would be this: instead of your own

void plotPoint (wcPt3D bezCurvePt)
{
    glBegin (GL_POINTS); // Plot control points
    glVertex2f(bezCurvePt.x, bezCurvePt.y);
    glEnd(); // Done drawing the GL_POINTS
}

consider

void plotPoint (wcPt3D bezCurvePt)
{
    glVertex2f(bezCurvePt.x, bezCurvePt.y);
}

and insert glBegin (GL_POINTS); and glEnd(); around the loop that draws the nBezCurvePts points. (Another optimization could be to use GL_LINE_LOOP or GL_LINE_LOOP , so you can calculate far less Bezier points.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM