電腦圖形學第三章—使用者介面與互動式技術使用者介面設計

來源:互聯網
上載者:User

 第三章  使用者介面與互動式技術使用者介面設計

3.1 使用者介面設計
一個好的圖形使用者介面應具備以下特點:
易於被使用者理解並接受;
易於操作、使用;
高效率、可靠性和實用性。

 

一致性原則:
一致性原則是指在設計系統的各個環節時,應遵從統一和簡單的規則,保證不出現例外和特殊的情況,無論資訊顯示還是命令輸入都應如此。
按使用者認為最正常、最合乎邏輯的方式去做,這比保持單純的一致性更重要。

 

減少記憶量:
使用者介面的操作應該組織得容易理解和記憶。
重要的原則是喚醒使用者的識別而不是記憶。

 

邏輯輸入裝置——拾取裝置
拾取裝置:拾取裝置用於選擇情境中即將進行變換、編輯和處理的部分。

 

3.2略
3.3 互動式繪圖技術

基本互動繪圖技術:
回顯  約束  網格  引力域  橡皮筋技術  草擬技術  拖動  旋轉  形變 

三維互動技術:
三維圖形資料的輸入
三維定位
三維定向

3.4 OpenGL實現橡皮筋技術
橡皮筋技術的實現方法:
利用顏色的異或操作,對原有圖形並不是擦除,而是再繪製一條同樣的直線段並與原圖形進行異或操作,此時原圖形會從螢幕上消失;
利用雙緩衝技術,繪製圖形時分別繪製到兩個緩衝,交替顯示。

滑鼠實現
滑鼠響應函數
     glutMouseFunc
滑鼠移動相應函數
     glutMotionFunc
     glutPassiveMotionFunc

鍵盤實現
鍵盤相應函數
    glutKeyboardFunc

 

3.5 OpenGL實現拾取操作
設定拾取緩衝區
        void glSelectBuffer(GLsizei n, GLunint *buff);
進入選擇模式
        GLint glRenderMode(GLenum mode);

名字堆棧操作
初始化名字堆棧(glInitNames)
將一個名字壓入堆棧(glPushName)
替換名字堆棧的棧頂元素(glLoadName)
將棧頂元素彈出(glPopName)

設定合適的變換過程
        gluPickMatrix(xPick, yPick, widthPick, heightPick, *vp);
為每個圖元分配名字並繪製
切換回渲染模式
分析選擇緩衝區中的資料

 

3.6 OpenGL中的菜單功能
菜單註冊函數
        glutCreateMenu(ProcessMenu);
在菜單中加入功能表項目
         void glutAddMenuEntry(char *name, GLint value);
將菜單與某個滑鼠按鍵關聯
         void glutAttachMenu(button);

 

#include <gl/glut.h>

int iPointNum = 0;                     //已確定點的數目
int x1=0,x2=0,y1=0,y2=0;               //確定的點座標
int winWidth = 400, winHeight = 300;     //視窗的寬度和高度

void Initial(void)
{
 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);        
}

void ChangeSize(int w, int h)
{
 winWidth = w; winHeight = h;
 glViewport(0, 0, w, h);                 //指定視窗顯示地區
 glMatrixMode(GL_PROJECTION);      //設定投影參數
 glLoadIdentity();
 gluOrtho2D(0.0,winWidth,0.0,winHeight);
}

void Display(void)
{
 glClear(GL_COLOR_BUFFER_BIT);
 glColor3f(1.0f, 0.0f, 0.0f);
 if(iPointNum >= 1) {
  glBegin(GL_LINES);              //繪製直線段
   glVertex2i(x1,y1);
   glVertex2i(x2,y2);
  glEnd();
 }
 glutSwapBuffers();                    //交換緩衝區
}

void MousePlot(GLint button, GLint action, GLint xMouse, GLint yMouse)
{
 if(button == GLUT_LEFT_BUTTON && action == GLUT_DOWN) {
  if(iPointNum == 0 || iPointNum == 2){
   iPointNum = 1;
   x1 = xMouse;  y1 = winHeight - yMouse;
  }
  else {
   iPointNum = 2;
   x2 = xMouse;  y2 = winHeight - yMouse;
   glutPostRedisplay();                  //指定視窗重新繪製
  }
 }
 if(button == GLUT_RIGHT_BUTTON && action == GLUT_DOWN){
  iPointNum = 0;
  glutPostRedisplay();
 }
}

void PassiveMouseMove (GLint xMouse, GLint yMouse)
{
 if(iPointNum == 1) {
  x2 = xMouse;
  y2 = winHeight - yMouse; 
  glutPostRedisplay();
 } 
}

int main(int argc, char* argv[])
{
 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);   //使用雙緩衝及RGB模型
 glutInitWindowSize(400,300);
 glutInitWindowPosition(100,100);
 glutCreateWindow("橡皮筋技術");
 glutDisplayFunc(Display);
 glutReshapeFunc(ChangeSize);                //指定視窗在整形回呼函數
 glutMouseFunc(MousePlot);                  //指定滑鼠響應函數
 glutPassiveMotionFunc(PassiveMouseMove);    //指定滑鼠移動響應函數
 Initial();                                   
 glutMainLoop();                              
 return 0;
}

 

#include <gl/glut.h>

int iPointNum = 0;                     //已確定點的數目
int x1=0,x2=0,y1=0,y2=0;               //確定的點座標
int winWidth = 400, winHeight = 300;     //視窗的寬度和高度

void Initial(void)
{
 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);        
}

void ChangeSize(int w, int h)
{
 winWidth = w; winHeight = h;
 glViewport(0, 0, w, h);                 //指定視窗顯示地區
 glMatrixMode(GL_PROJECTION);      //設定投影參數
 glLoadIdentity();
 gluOrtho2D(0.0,winWidth,0.0,winHeight);
}

void Display(void)
{
 glClear(GL_COLOR_BUFFER_BIT);
 glColor3f(1.0f, 0.0f, 0.0f);
 if(iPointNum >= 1) {
  glBegin(GL_LINES);              //繪製直線段
   glVertex2i(x1,y1);
   glVertex2i(x2,y2);
  glEnd();
 }
 glutSwapBuffers();                    //交換緩衝區
}

void PassiveMouseMove (GLint xMouse, GLint yMouse)
{
 if(iPointNum == 1) {
  x2 = xMouse;
  y2 = winHeight - yMouse; 
  glutPostRedisplay();
 } 
}

void Key(unsigned char key, int x, int y)
{
 switch(key){
  case 'p':
   if(iPointNum == 0 || iPointNum == 2) {
    iPointNum = 1;
    x1 = x; y1 = winHeight - y;
   }
   else {
    iPointNum = 2;
    x2 = x; y2 = winHeight - y;
    glutPostRedisplay();
   }
   break;
  default: break;
 } 
}

int main(int argc, char* argv[])
{
 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);   //使用雙緩衝及RGB模型
 glutInitWindowSize(400,300);
 glutInitWindowPosition(100,100);
 glutCreateWindow("橡皮筋技術");
 glutDisplayFunc(Display);
 glutReshapeFunc(ChangeSize);                //指定視窗在整形回呼函數
 glutKeyboardFunc(Key);        //指定鍵盤響應函數
 glutPassiveMotionFunc(PassiveMouseMove);    //指定滑鼠移動響應函數
 Initial();                                   
 glutMainLoop();                              
 return 0;
}

 

 

#include <gl/glut.h>
#include "stdio.h"

const GLint pickSize = 32;
int winWidth = 400, winHeight = 300;

void Initial(void)
{
 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);        
}

void DrawRect(GLenum mode)
{
 if(mode == GL_SELECT) glPushName(1); //壓入堆棧
 glColor3f(1.0f,0.0f,0.0f);
 glRectf(60.0f,50.0f,150.0f,150.0f);
 
if(mode == GL_SELECT) glPushName(2); //壓入堆棧
glColor3f(0.0f,1.0f,0.0f);
glRectf(230.0f,50.0f,330.0f,150.0f);

if(mode == GL_SELECT) glPushName(3); //壓入堆棧
glColor3f(0.0f,0.0f,1.0f);
glRectf(140.0f,140.0f,240.0f,240.0f);
}

void ProcessPicks(GLint nPicks, GLuint pickBuffer[])
{
 GLint i;
 GLuint name, *ptr;
printf("選中的數目為%d個/n",nPicks);
ptr=pickBuffer;
for(i=0;i<nPicks; i++){
 name=*ptr;    //選中圖元在堆棧中的位置
 ptr+=3;       //跳過名字和深度資訊
 ptr+=name-1;  //根據位置資訊獲得選中的圖元名字
 if(*ptr==1) printf("你選擇了紅色圖元/n");
 if(*ptr==2) printf("你選擇了綠色圖元/n");
 if(*ptr==3) printf("你選擇了藍色圖元/n");
 ptr++;
}
 printf("/n/n");
}

void ChangeSize(int w, int h)
{
winWidth = w;
winHeight = h;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,winWidth,0.0,winHeight);
}

void Display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
DrawRect(GL_RENDER);
glFlush();
}

void MousePlot(GLint button, GLint action, GLint xMouse, GLint yMouse)
{
GLuint pickBuffer[pickSize];
GLint nPicks, vp[4];

if(button == GLUT_LEFT_BUTTON && action == GLUT_DOWN){
 glSelectBuffer(pickSize,pickBuffer); //設定選擇緩衝區
glRenderMode(GL_SELECT); //啟用選擇模式
glInitNames();   //初始化名字堆棧
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glGetIntegerv(GL_VIEWPORT, vp);
//定義一個10×10的選擇地區
gluPickMatrix(GLdouble(xMouse), GLdouble(vp[3]-yMouse),10.0,10.0,vp);
gluOrtho2D(0.0,winWidth,0.0,winHeight);
DrawRect(GL_SELECT);
//恢複投影變換
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glFlush();

//獲得選擇集並輸出
nPicks = glRenderMode(GL_RENDER);
ProcessPicks(nPicks, pickBuffer);
glutPostRedisplay();
}
}

int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); 
glutInitWindowSize(400,300);                 
glutInitWindowPosition(100,100);             
glutCreateWindow("拾取操作");                  
glutDisplayFunc(Display);
glutReshapeFunc(ChangeSize);
glutMouseFunc(MousePlot);
Initial();                                   
glutMainLoop();                              
return 0;
}

 

最後的程式在vs2005種編譯出錯:

錯誤 1 error C2057: expected constant expression e:/vc/opengl1/opengl1/opengl.c 65
錯誤 2 error C2466: cannot allocate an array of constant size 0 e:/vc/opengl1/opengl1/opengl.c 65
錯誤 3 error C2133: 'pickBuffer' : unknown size e:/vc/opengl1/opengl1/opengl.c 65
錯誤 4 error C2143: syntax error : missing ')' before 'type' e:/vc/opengl1/opengl1/opengl.c 78
錯誤 5 error C2198: 'gluPickMatrix' : too few arguments for call e:/vc/opengl1/opengl1/opengl.c 78

 

修改兩處:

1、GLuint pickBuffer[32];//[pickSize];

2、gluPickMatrix((GLdouble)xMouse, (GLdouble)(vp[3]-yMouse),10.0,10.0,vp);

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.