2014-01-19 46 views
1

我正在使用OpenGl進行一個簡單的繪圖程序。其中一個要求是用戶能夠使用1-7鍵來改變線條的顏色,用「+」或「 - 」鍵以及其他一些情況來改變筆畫的大小。我已經實施了大部分,但這裏是我遇到麻煩的地方。每當我按任何鍵改變下一個筆劃時,它都會修改已經在屏幕上繪製的所有內容。所以如果我畫了一個白色的波形,然後想要改變下一行,我將按'1'鍵將其畫成紅色,這將改變我已經畫成紅色的白色波形。大小和/或刷子的形狀(三角形和線)也一樣。opengl繪製程序每次擊鍵都改變

我不期待一步一步的演練,但有關如何進行的一些建議。

這裏是我的參考代碼:

#include "stdafx.h" 
#include <vector> 
#include <gl/glut.h> 
#include <gl/gl.h> 


#define WINDOW_WIDTH 800 
#define WINDOW_HEIGHT 600 

std::vector<int>mouseX; 
std::vector<int>mouseY; 
int size=1; 
int num = 0; 
bool leftClick = false; 



void drawShape(int num) 
{ 
    if (num == 0) // quad brush 
    { 
     for (unsigned int x = 0; x < mouseX.size(); x++) 
     { 
      glBegin(GL_POLYGON); 
      glVertex2f(mouseX[x] - size, mouseY[x] - size); 
      glVertex2f(mouseX[x] + size, mouseY[x] - size); 
      glVertex2f(mouseX[x] + size, mouseY[x] + size); 
      glVertex2f(mouseX[x] - size, mouseY[x] + size); 
      glEnd(); 
     } 
    } 
    if (num == 1) //triangle brush 
    { 
     for (unsigned int x = 0; x < mouseX.size(); x++) 
     { 
      glBegin(GL_TRIANGLES); 
      glVertex2f(mouseX[x] - size, mouseY[x] - size); 
      glVertex2f(mouseX[x] + size, mouseY[x] - size); 
      glVertex2f(mouseX[x], mouseY[x] + size); 
      glEnd(); 
     } 
    } 
    if (num == 2) //line brush 
    { 
     for (unsigned int x = 0; x < mouseX.size(); x++) 
     { 
      glBegin(GL_LINES); 
      glVertex2f(mouseX[x], mouseY[x] - size); 
      glVertex2f(mouseX[x], mouseY[x] + size); 
      glEnd(); 
     } 
    } 
    if (num == 3) // circle brush 
    { 
     for (unsigned int x = 0; x < mouseX.size(); x++) 
     { 

     } 
    } 
    glFlush(); 
} 

void display(void) 
{ 
    glClearColor(0, 0, 0, 0); 
    glClear(GL_COLOR_BUFFER_BIT); 
    drawShape(num); 
    glFlush(); 
} 

void keyboard(unsigned char key, int x, int y) 
{ 
    switch (key) 
    { 
     case '1': //change the color to red 
      glClear(GL_COLOR_BUFFER_BIT); 
      glColor3f(1, 0, 0); 
      break; 
     case '2': //change the color to green 
      glColor3f(0, 1, 0); 
      break; 
     case '3': //change the color yellow 
      glColor3f(1, 1, 0); 
      break; 
     case '4': //change the color to blue 
      glColor3f(0, 0, 1); 
      break; 
     case '5': //change the color to magenta 
      glColor3f(1, 0, 1); 
      break; 
     case '6': //change the color to cyan 
      glColor3f(0, 1, 1); 
      break; 
     case '7': //change the color to white 
      glColor3f(1, 1, 1); 
      break; 
     case '=': //increase brush size by 2 
      if (size < 65) 
       size = size * 2; 
      break; 
     case '-': //decrease brush size by 2 
      if (size > 1) 
       size = size/2; 
      break; 
     case 'b': //cycle through brushes (0 - quad, 1 - triangle, 2 - line, 3 - circle) 
      num++; 
      if (num > 3) 
       num = 0; 
      break; 
     case 'c': //clear the screen back to black 
      glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
      break; 
     case 'r': //rotate the brush in 10 degree increments 

      break; 
     //EXTRA CREDIT ***case 'a':*** //a spray paint brush that has the edges blurred (transparent) 
    } 
    glutPostRedisplay(); 
} 

void init(void) 
{ 
    glClearColor(0.0, 0.0, 0.0, 0.0); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glOrtho(0.0, WINDOW_WIDTH - 1, WINDOW_HEIGHT - 1, 0, -1.0, 1.0); 
    glMatrixMode(GL_MODELVIEW); 
} 


void mouse(int button, int action, int x, int y) 
{ 
    if (button == GLUT_LEFT_BUTTON) 
    { 
     if (action == GLUT_DOWN) 
      leftClick = true; 
     else 
      leftClick = false; 
    } 
} 


void mouseMove(int x, int y) 
{ 
    if (leftClick) 
    { 
     mouseX.push_back(x); 
     mouseY.push_back(y); 
     glutPostRedisplay(); 
    } 
} 


int main(int argc, char *argv[]) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); 
    glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT); 
    glutInitWindowPosition(500, 300); 
    glutCreateWindow("Christopher Spear - Assignment 1"); 
    init(); 
    glutDisplayFunc(display); 
    glutMotionFunc(mouseMove); 
    glutMouseFunc(mouse); 
    glutKeyboardFunc(keyboard); 
    glutMainLoop(); 
    return 0; 
} 
+0

這是因爲你正在改變整個場景的顏色。您還應該存儲顏色,並在頂點之前使用'glColor3f(color [x],color [y],color [z]);'。 – Gasim

回答

2

由於OpenGL的工作作爲一個狀態機,它的命令一樣glColor直到再次改變會改變顏色。這就是爲什麼其他對象也會以選定顏色繪製的原因。您需要在內部保留當前顏色,在繪製線條時將其設置,然後在繪製下一個對象時將其重置。

例如:

float lineColor[3]; 
void keyboard(unsigned char key, int x, int y) 
{ 
    switch (key) 
    { 
    case '1': //change the color to red 
     lineColor[0] = 1.0f; 
     lineColor[1] = 0.0f; 
     lineColor[2] = 0.0f; 
     break; 
     ... and so on 
    } 
} 

void drawShape(int num) 
{ 
    if (num == 0) // quad brush 
    { 
     glColor3f(1.0f, 1.0f, 1.0f); 
     for (unsigned int x = 0; x < mouseX.size(); x++) 
     { 
      glBegin(GL_POLYGON); 
      glVertex2f(mouseX[x] - size, mouseY[x] - size); 
      glVertex2f(mouseX[x] + size, mouseY[x] - size); 
      glVertex2f(mouseX[x] + size, mouseY[x] + size); 
      glVertex2f(mouseX[x] - size, mouseY[x] + size); 
      glEnd(); 
     } 
    } 
    ... 
    if (num == 2) //line brush 
    { 
     glColor3fv(lineColor); 
     for (unsigned int x = 0; x < mouseX.size(); x++) 
     { 
      glBegin(GL_LINES); 
      glVertex2f(mouseX[x], mouseY[x] - size); 
      glVertex2f(mouseX[x], mouseY[x] + size); 
      glEnd(); 
     } 
    } 
    ... 
} 

所以你基本上將所有相關國家在繪製之前。或者,您可以在線之前設置顏色,然後直接將其重置,因此您無需在其他繪製調用中關心它。

+0

非常感謝您的回覆!我沒有時間完成所有事情,但我想至少感謝你的幫助 – spearman008

1

這更像是給你的家庭作業的提示。

創建一個類/結構頂點,它存儲所有的頂點信息,你可以很容易地將它們加在一起。

struct Vertex { 
    float x,y; 
    float r,g,b,a; 
}; 

,並創建一個列表std::vector<Vertex> vertices;,而不是對每個組件多個列表。它是一樣的東西,但它會更乾淨。然後你只需要使用

glVertex3f(vertices[i].x - size, vertices[i].y - size);