2013-03-14 21 views
0

的窗口周圍拖動圖形是目前的代碼,我的問題在於拖動窗口周圍的圖形?我似乎無法做到這一點?任何提示給我的人?我想要的是,當你點擊並按住鼠標左鍵時,你應該可以在窗口周圍拖動圖形?如何在OpenGL/C++

#include <GL/glut.h> 
#include <stdlib.h> 
#include <math.h> 
#if !defined(GLUT_WHEEL_UP) 
# define GLUT_WHEEL_UP 

# define GLUT_WHEEL_DOWN 4 
#endif 


/* Set initial size of the display window. */ 
GLsizei winWidth = 600, winHeight = 600; 

/* Set size of world-coordinate clipping window. */ 
GLfloat xwcMin = -50.0, xwcMax = 50.0; 
GLfloat ywcMin = -50.0, ywcMax = 50.0; 
bool leftButton; 
int downX, downY; 

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

void init (void) {  
    /* Set color of display window to white. */ 
    glClearColor (1.0, 1.0, 1.0, 0.0); 
} 

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

/* Compute binomial coefficients C for given value of n. */ 
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 t, 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 blend control points. */ 
    for (k = 0; k < nCtrlPts; k++) { 
     bezBlendFcn = C [k] * pow (t, k) * pow (1 - t, 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 t; 
    GLint *C; 

    /* Allocate space for binomial coefficients */ 
    C = new GLint [nCtrlPts]; 

    binomialCoeffs (nCtrlPts - 1, C); 
    for (int i = 0; i <= nBezCurvePts; i++) { 
     t = GLfloat (i)/GLfloat (nBezCurvePts); 
     computeBezPt (t, &bezCurvePt, nCtrlPts, ctrlPts, C); 
     plotPoint (bezCurvePt); 
    } 
    delete [ ] C; 
} 

void displayFcn (void) { 
    glClear (GL_COLOR_BUFFER_BIT); // Clear display window. 

    /* Set example number of control points and number of 
    * curve positions to be plotted along the Bezier curve. 
    */ GLint nCtrlPts = 4, nBezCurvePts = 1000; 

    wcPt3D ctrlPts [4] = { {-40.0, -40.0, 0.0}, {-10.0, 200.0, 0.0}, 
          {10.0, -200.0, 0.0}, {40.0, 40.0, 0.0} }; 

    glPointSize (4); 
    glColor3f (1.0, 0.0, 0.0);  // Set point color to red. 

    bezier (ctrlPts, nCtrlPts, nBezCurvePts); 
    glutSwapBuffers(); 
} 

void winReshapeFcn (GLint newWidth, GLint newHeight) { 
    /* Maintain an aspect ratio of 1.0. */ 
    glViewport (0, 0, xwcMin, ywcMin); 

    glMatrixMode (GL_PROJECTION); 
    glLoadIdentity (); 

    gluOrtho2D (xwcMin, xwcMax, ywcMin, ywcMax); 

    glutPostRedisplay(); 
} 

void MouseCallback(int button, int state, int x, int y) { 
    downX = x; 
    downY = y; 
    leftButton = ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN)); 
    glutPostRedisplay(); 
} 

void MotionCallback(int x, int y) { 
    if (leftButton){ 
     downX=downX+x; 
     downY=downY+y; 
     gluOrtho2D (xwcMin, xwcMax, ywcMin, ywcMax); 
    } 

    downX = x; 
    downY = y; 
    glutPostRedisplay(); 
} 
/* 
    void MouseCallback(int button, int state, int x, int y) { 
     if (button == GLUT_WHEEL_UP && glutGetModifiers()==GLUT_ACTIVE_CTRL) { 
     }else if (button == GLUT_WHEEL_DOWN) 
      glutPostRedisplay(); 
     } 
*/ 

int main (int argc, char** argv) { 
    glutInit (&argc, argv); 
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); 
    glutInitWindowPosition (50, 50); 
    glutInitWindowSize (winWidth, winHeight); 
    glutCreateWindow ("Bezier Curve"); 

    init (); 
    glutDisplayFunc (displayFcn); 
    glutReshapeFunc (winReshapeFcn); 
    glutMouseFunc(MouseCallback); 
    glutMotionFunc(MotionCallback); 
    glutMainLoop (); 
} 
+0

當您單擊並拖動,會發生什麼?在MotionCallback中調用gluOrtho2D之前,您可能需要'glLoadIdentity',因爲gluOrtho2D會乘以當前選定的矩陣。 – 2013-03-14 17:31:58

+1

@JacobParker:從技術上講,你不應該在輸入事件處理程序中做任何OpenGL調用。設置一些用於參數化繪圖過程的變量。 – datenwolf 2013-03-14 17:58:50

回答

0

試試這個:

#include <GL/glut.h> 
#include <cmath> 

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

struct wcPt3D 
{ 
    GLfloat x, y, z; 
}; 

void computeBezPt 
    (
    GLfloat t, 
    wcPt3D* bezPt, 
    GLint nCtrlPts, 
    wcPt3D* ctrlPts, 
    GLint* C 
    ) 
{ 
    GLint n = nCtrlPts - 1; 
    GLfloat bezBlendFcn; 

    bezPt->x = bezPt->y = bezPt->z = 0.0; 

    // Compute blending functions and blend control points. 
    for (GLint k = 0; k < nCtrlPts; k++) 
    { 
     bezBlendFcn = C [k] * pow (t, k) * pow (1 - t, 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 
    ) 
{ 
    // Allocate space for binomial coefficients 
    GLint* C = new GLint [nCtrlPts]; 

    binomialCoeffs (nCtrlPts - 1, C); 
    glBegin (GL_POINTS); 
    for (int i = 0; i <= nBezCurvePts; i++) 
    { 
     GLfloat t = GLfloat (i)/GLfloat (nBezCurvePts); 
     wcPt3D bezCurvePt; 
     computeBezPt (t, &bezCurvePt, nCtrlPts, ctrlPts, C); 
     glVertex2f (bezCurvePt.x, bezCurvePt.y); 
    } 
    glEnd(); 
    delete [ ] C; 
} 

int btn; 
int startMouseX = 0; 
int startMouseY = 0; 
int startTransX = 0; 
int startTransY = 0; 
int curTransX = 0; 
int curTransY = 0; 
void MouseCallback(int button, int state, int x, int y) 
{ 
    btn = button; 
    if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) 
    { 
     startMouseX = x; 
     startMouseY = glutGet(GLUT_WINDOW_HEIGHT) - y; 
     startTransX = curTransX; 
     startTransY = curTransY; 
    } 
    glutPostRedisplay(); 
} 

void MotionCallback(int x, int y) 
{ 
    int curMouseX = x; 
    int curMouseY = glutGet(GLUT_WINDOW_HEIGHT) - y; 
    if (btn == GLUT_LEFT_BUTTON) 
    { 
     curTransX = startTransX + (curMouseX - startMouseX); 
     curTransY = startTransY + (curMouseY - startMouseY); 
    } 

    glutPostRedisplay(); 
} 

// Set size of world-coordinate clipping window. 
GLfloat xwcMin = -50.0, xwcMax = 50.0; 
GLfloat ywcMin = -50.0, ywcMax = 50.0; 
void displayFcn() 
{ 
    // Clear display window. 
    glClearColor (1.0, 1.0, 1.0, 0.0); 
    glClear (GL_COLOR_BUFFER_BIT); 

    glMatrixMode (GL_PROJECTION); 
    glLoadIdentity (); 
    double w = glutGet(GLUT_WINDOW_WIDTH); 
    double h = glutGet(GLUT_WINDOW_HEIGHT); 
    glTranslatef(curTransX/w * 2, curTransY/h * 2, 0); 
    gluOrtho2D (xwcMin, xwcMax, ywcMin, ywcMax); 

    glMatrixMode (GL_MODELVIEW); 
    glLoadIdentity(); 

    // Set example number of control points and number of 
    // curve positions to be plotted along the Bezier curve. 
    GLint nCtrlPts = 4, nBezCurvePts = 1000; 
    wcPt3D ctrlPts [4] = 
    { 
     {-40.0, -40.0, 0.0}, 
     {-10.0, 200.0, 0.0}, 
     {10.0, -200.0, 0.0}, 
     {40.0, 40.0, 0.0} 
    }; 

    // Set point color to red. 
    glPointSize (4); 
    glColor3f (1.0, 0.0, 0.0);  

    bezier (ctrlPts, nCtrlPts, nBezCurvePts); 
    glutSwapBuffers(); 
} 

int main (int argc, char** argv) 
{ 
    glutInit (&argc, argv); 
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); 
    glutInitWindowPosition (50, 50); 
    glutInitWindowSize (600, 600); 
    glutCreateWindow ("Bezier Curve"); 

    glutDisplayFunc (displayFcn); 
    glutMouseFunc(MouseCallback); 
    glutMotionFunc(MotionCallback); 
    glutMainLoop (); 
} 

從我的回答here改編。

編輯:最小(-ish)差異版本:

#include <GL/glut.h> 
#include <stdlib.h> 
#include <math.h> 
#if !defined(GLUT_WHEEL_UP) 
# define GLUT_WHEEL_UP 

# define GLUT_WHEEL_DOWN 4 
#endif 


/* Set initial size of the display window. */ 
GLsizei winWidth = 600, winHeight = 600; 

/* Set size of world-coordinate clipping window. */ 
GLfloat xwcMin = -50.0, xwcMax = 50.0; 
GLfloat ywcMin = -50.0, ywcMax = 50.0; 

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

void init (void) {  
    /* Set color of display window to white. */ 
    glClearColor (1.0, 1.0, 1.0, 0.0); 
} 

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

/* Compute binomial coefficients C for given value of n. */ 
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 t, 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 blend control points. */ 
    for (k = 0; k < nCtrlPts; k++) { 
     bezBlendFcn = C [k] * pow (t, k) * pow (1 - t, 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 t; 
    GLint *C; 

    /* Allocate space for binomial coefficients */ 
    C = new GLint [nCtrlPts]; 

    binomialCoeffs (nCtrlPts - 1, C); 
    for (int i = 0; i <= nBezCurvePts; i++) { 
     t = GLfloat (i)/GLfloat (nBezCurvePts); 
     computeBezPt (t, &bezCurvePt, nCtrlPts, ctrlPts, C); 
     plotPoint (bezCurvePt); 
    } 
    delete [ ] C; 
} 

int curTransX = 0; 
int curTransY = 0; 
void displayFcn (void) { 
    glClear (GL_COLOR_BUFFER_BIT); // Clear display window. 

    glMatrixMode (GL_PROJECTION); 
    glLoadIdentity (); 
    double w = glutGet(GLUT_WINDOW_WIDTH); 
    double h = glutGet(GLUT_WINDOW_HEIGHT); 
    glTranslatef(curTransX/w * 2, curTransY/h * 2, 0); 
    gluOrtho2D (xwcMin, xwcMax, ywcMin, ywcMax); 

    glMatrixMode (GL_MODELVIEW); 
    glLoadIdentity(); 

    /* Set example number of control points and number of 
    * curve positions to be plotted along the Bezier curve. 
    */ GLint nCtrlPts = 4, nBezCurvePts = 1000; 

    wcPt3D ctrlPts [4] = { {-40.0, -40.0, 0.0}, {-10.0, 200.0, 0.0}, 
          {10.0, -200.0, 0.0}, {40.0, 40.0, 0.0} }; 

    glPointSize (4); 
    glColor3f (1.0, 0.0, 0.0);  // Set point color to red. 

    bezier (ctrlPts, nCtrlPts, nBezCurvePts); 
    glutSwapBuffers(); 
} 

int btn; 
int startMouseX = 0; 
int startMouseY = 0; 
int startTransX = 0; 
int startTransY = 0; 
void MouseCallback(int button, int state, int x, int y) { 
    btn = button; 
    if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) 
    { 
     startMouseX = x; 
     startMouseY = glutGet(GLUT_WINDOW_HEIGHT) - y; 
     startTransX = curTransX; 
     startTransY = curTransY; 
    } 
    glutPostRedisplay(); 
} 

void MotionCallback(int x, int y) { 
    int curMouseX = x; 
    int curMouseY = glutGet(GLUT_WINDOW_HEIGHT) - y; 
    if (btn == GLUT_LEFT_BUTTON) 
    { 
     curTransX = startTransX + (curMouseX - startMouseX); 
     curTransY = startTransY + (curMouseY - startMouseY); 
    } 
    glutPostRedisplay(); 
} 
/* 
    void MouseCallback(int button, int state, int x, int y) { 
     if (button == GLUT_WHEEL_UP && glutGetModifiers()==GLUT_ACTIVE_CTRL) { 
     }else if (button == GLUT_WHEEL_DOWN) 
      glutPostRedisplay(); 
     } 
*/ 

int main (int argc, char** argv) { 
    glutInit (&argc, argv); 
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); 
    glutInitWindowPosition (50, 50); 
    glutInitWindowSize (winWidth, winHeight); 
    glutCreateWindow ("Bezier Curve"); 

    init (); 
    glutDisplayFunc (displayFcn); 
    glutMouseFunc(MouseCallback); 
    glutMotionFunc(MotionCallback); 
    glutMainLoop (); 
} 
+0

當我點擊並拖動圖形最小化到一個小小的正方形,我不能讓它恢復正常。我無法從原始代碼中過多地更改代碼,因爲這是實驗室練習,拖動代碼是最後一部分,我無法完成它:/ – sparky971 2013-03-15 20:06:52

+0

因此,您在* exact *程序中獲得了這種收縮行爲我已經發布?你寫評論的方式似乎意味着你可能已經修改了它。 – genpfault 2013-03-15 21:05:07

+0

哦,不,我不能使用你的代碼,因爲它從最初的程序變得太多了,教授希望我們使用我已經發布的代碼,並從那得到拖動工作,但不管我以什麼方式嘗試我無法看起來讓它做除收縮以外的任何事情? – sparky971 2013-03-15 22:32:48