sources:


website:
more info here


screenshot:
studies/grafik/Computergrafik-Code2/Aufgabe5/cgairbrush.cpp
download file

  1 // Computergrafik I
  2 // Prof. Dr. Juergen Doellner
  3 // Sommersemester 2001
  4 //
  5 // Programmrahmen fuer Aufgabe 5
  6
  7 // Stephan Brumme, 702544
  8 // last changes: May 01, 2001
  9
 10 #include "cgairbrush.h"
 11 #include <fstream.h>
 12
 13
 14 CGAirbrush::CGAirbrush(unsigned int brushPatternSize)
 15     : m_brushPatternSize(brushPatternSize) {
 16     assert(brushPatternSize >= 10); // sollte groesser/gleich 10x10 sein!
 17
 18     // erzeuge brush pattern dynamisch
 19     m_brushPattern = new Color[brushPatternSize*brushPatternSize];
 20
 21     // Initialisiere die RGB- und Alpha-Werte der Schablone
 22     // kreisförmiger Pinsel
 23     setRadialPattern();
 24     // rot
 25     setColor(1.0, 0.0, 0.0);
 26 }
 27
 28 CGAirbrush::~CGAirbrush() {
 29     // Nicht vergessen: Freigabe des dynamisch erzeugten Objekte
 30     delete [] m_brushPattern;
 31 }
 32
 33 void CGAirbrush::onInit() {
 34     // Setze die Hintergrundfarbe auf weiss
 35     glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
 36     glClear(GL_COLOR_BUFFER_BIT);
 37
 38     // Die Schablonen-Reihen sind dicht gepackt
 39     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 40
 41     // Schalte das Blending ein:
 42     glEnable(GL_BLEND);
 43     // mische Farbwerte
 44     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 45
 46     glFlush();
 47 }
 48
 49 void CGAirbrush::onDraw() {
 50     // Loesche den Farb-Buffer
 51     glClear(GL_COLOR_BUFFER_BIT);
 52     glFlush();
 53
 54     // Wir verwenden Single-Buffering und koennen
 55     // die bisher gezeichneten Figuren nicht mehr
 56     // restaurieren.
 57 }
 58
 59 void CGAirbrush::onSize(unsigned int newWidth, unsigned int newHeight) {
 60     // Nach jeder Groessenaenderung des OpenGL-Fensters
 61     // MUSS der Viewport entsprechend angepasst werden:
 62     glViewport(0, 0, newWidth - 1, newHeight - 1);
 63
 64     // Lege das zu verwendende Koordinatensystem fest:
 65     // die linke untere Fensterecke hat die Koordinaten (0, 0)
 66     // und die rechte obere die Koord. (newWidth, newHeight)
 67     glMatrixMode(GL_PROJECTION);
 68     glLoadIdentity();
 69     gluOrtho2D(0.0, newWidth, 0.0, newHeight);
 70 }
 71
 72 void CGAirbrush::onButton(MouseButton button, int x, int y) {
 73
 74     if (button == LeftMouseButton)
 75         // Mache das selbe wie bei einer Mausbewegung:
 76         onMove(x, y);
 77     else     {
 78         // setze Pinsel auf Bildinhalt an der aktuellen Position
 79         glReadPixels(x-m_brushPatternSize/2, y-m_brushPatternSize/2,
 80                      m_brushPatternSize, m_brushPatternSize,
 81                      GL_RGBA, GL_FLOAT, m_brushPattern)
;
 82     }
 83 }
 84
 85 void CGAirbrush::onMove(int x, int y)
 86 {       
 87     // lege obere linke Ecke fest,
 88     // sodass Mauscursor der Mittelpunkt der gezeichneten Fläche ist
 89     glRasterPos2i(x-m_brushPatternSize/2, y-m_brushPatternSize/2);
 90     // zeichne Pinsel
 91     glDrawPixels(m_brushPatternSize, m_brushPatternSize,
 92                  GL_RGBA, GL_FLOAT, m_brushPattern)
;
 93
 94     // Pipeline abarbeiten
 95     glFlush();
 96 }
 97
 98 void CGAirbrush::onKey(unsigned char key) {
 99     // Keys
100     switch(key) {
101         // beenden
102     case 'q' : exit(0); break;
103        
104         // Farbe setzen
105     case '0' : setColor(1.0, 0.0, 0.0); break;
106     case '1' : setColor(0.0, 1.0, 0.0); break;
107     case '2' : setColor(0.0, 0.0, 1.0); break;
108     case '3' : setColor(1.0, 1.0, 0.0); break;
109     case '4' : setColor(1.0, 0.0, 1.0); break;
110     case '5' : setColor(0.0, 1.0, 1.0); break;
111     case '6' : setColor(1.0, 1.0, 1.0); break;
112     case '7' : setColor(0.0, 0.0, 0.0); break;
113
114         // Buffer löschen (weiss)
115     case 'c' : glClear(GL_COLOR_BUFFER_BIT); glFlush(); break;
116
117         // verschiedene Pinsel setzen
118     case 'r' : setRadialPattern(); break;
119     case 'k' : setConstantPattern(0.5); break;
120     case 'e' : setArbitraryPattern(); break;
121
122     default:
123         cerr << "No action defined for key: " << key << endl;
124     }
125 }
126
127 void CGAirbrush::setRadialPattern()
128 {
129     // Mitte des Pinsels bestimmen
130     float nCenterX = m_brushPatternSize/2;
131     float nCenterY = m_brushPatternSize/2;
132
133     // Durchmesser des runden Pinsels
134     float fMaxDistance = m_brushPatternSize/2;
135    
136     for (unsigned int nX = 0; nX < m_brushPatternSize; nX++)
137         for (unsigned int nY = 0; nY < m_brushPatternSize; nY++)
138         {
139             // Abstand zur Pinselmitte
140             float fDistance = sqrt((nCenterX-nX) * (nCenterX-nX) +
141                                    (nCenterY-nY) * (nCenterY-nY))
;
142
143             // 100% opak in der Pinselmitte, 0% am Rand
144             float fOpacity = 1 - fDistance/fMaxDistance;
145
146             // verhindere Underflow
147             if (fOpacity < 0)
148                 fOpacity = 0;
149             fOpacity *= 0.5;
150
151             // setze Opazität
152             m_brushPattern[nX*m_brushPatternSize+nY].alpha = fOpacity;
153         }
154 }
155
156 void CGAirbrush::setConstantPattern(float fOpacity)
157 {
158     // kompletter Pinsel mit einer Opazität
159     for (unsigned int nX = 0; nX < m_brushPatternSize; nX++)
160         for (unsigned int nY = 0; nY < m_brushPatternSize; nY++)
161             m_brushPattern[nX*m_brushPatternSize+nY].alpha = fOpacity;
162 }
163
164 void CGAirbrush::setArbitraryPattern()
165 {
166     // öffne Datei
167     ifstream hPattern("32x32.pat");
168
169     // lies Pinsel ein
170     for (unsigned int nX = 0; nX < m_brushPatternSize; nX++)
171         for (unsigned int nY = 0; nY < m_brushPatternSize; nY++)
172             hPattern >> m_brushPattern[nX*m_brushPatternSize+nY].alpha;
173 }
174
175 void CGAirbrush::setColor(GLfloat red, GLfloat green, GLfloat blue)
176 {
177     // ändere alle Farbwerte im Pinsel
178     for (unsigned int nX = 0; nX < m_brushPatternSize; nX++)
179         for (unsigned int nY = 0; nY < m_brushPatternSize; nY++)
180         {
181             m_brushPattern[nX*m_brushPatternSize+nY].r = red;
182             m_brushPattern[nX*m_brushPatternSize+nY].g = green;
183             m_brushPattern[nX*m_brushPatternSize+nY].b = blue;
184         }
185 }
186
187 int main(int argc, char* argv[]) {
188     CGAirbrush airbrush(32);
189     airbrush.start("CGAirbrush, Stephan Brumme, 702544", false);
190     return(0);
191 }
192
193
194