sources:
cgairbrush.cpp (5.4k)
cgairbrush.h (1.3k)
cgapplication.cpp (2.9k)
cgapplication.h (3.5k)


binaries:
Release/airbrush.exe (64.0k)


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     {
 79         // setze Pinsel auf Bildinhalt an der aktuellen Position
 80         glReadPixels(x-m_brushPatternSize/2, y-m_brushPatternSize/2,
 81                      m_brushPatternSize, m_brushPatternSize,
 82                      GL_RGBA, GL_FLOAT, m_brushPattern)
;
 83     }
 84 }
 85
 86 void CGAirbrush::onMove(int x, int y)
 87 {       
 88     // lege obere linke Ecke fest,
 89     // sodass Mauscursor der Mittelpunkt der gezeichneten Fläche ist
 90     glRasterPos2i(x-m_brushPatternSize/2, y-m_brushPatternSize/2);
 91     // zeichne Pinsel
 92     glDrawPixels(m_brushPatternSize, m_brushPatternSize,
 93                  GL_RGBA, GL_FLOAT, m_brushPattern)
;
 94
 95     // Pipeline abarbeiten
 96     glFlush();
 97 }
 98
 99 void CGAirbrush::onKey(unsigned char key) {
100     // Keys
101     switch(key) {
102         // beenden
103     case 'q' : exit(0); break;
104        
105         // Farbe setzen
106     case '0' : setColor(1.0, 0.0, 0.0); break;
107     case '1' : setColor(0.0, 1.0, 0.0); break;
108     case '2' : setColor(0.0, 0.0, 1.0); break;
109     case '3' : setColor(1.0, 1.0, 0.0); break;
110     case '4' : setColor(1.0, 0.0, 1.0); break;
111     case '5' : setColor(0.0, 1.0, 1.0); break;
112     case '6' : setColor(1.0, 1.0, 1.0); break;
113     case '7' : setColor(0.0, 0.0, 0.0); break;
114
115         // Buffer löschen (weiss)
116     case 'c' : glClear(GL_COLOR_BUFFER_BIT); glFlush(); break;
117
118         // verschiedene Pinsel setzen
119     case 'r' : setRadialPattern(); break;
120     case 'k' : setConstantPattern(0.5); break;
121     case 'e' : setArbitraryPattern(); break;
122
123     default:
124         cerr << "No action defined for key: " << key << endl;
125     }
126 }
127
128 void CGAirbrush::setRadialPattern()
129 {
130     // Mitte des Pinsels bestimmen
131     float nCenterX = m_brushPatternSize/2;
132     float nCenterY = m_brushPatternSize/2;
133
134     // Durchmesser des runden Pinsels
135     float fMaxDistance = m_brushPatternSize/2;
136    
137     for (unsigned int nX = 0; nX < m_brushPatternSize; nX++)
138         for (unsigned int nY = 0; nY < m_brushPatternSize; nY++)
139         {
140             // Abstand zur Pinselmitte
141             float fDistance = sqrt((nCenterX-nX) * (nCenterX-nX) +
142                                    (nCenterY-nY) * (nCenterY-nY))
;
143
144             // 100% opak in der Pinselmitte, 0% am Rand
145             float fOpacity = 1 - fDistance/fMaxDistance;
146
147             // verhindere Underflow
148             if (fOpacity < 0)
149                 fOpacity = 0;
150             fOpacity *= 0.5;
151
152             // setze Opazität
153             m_brushPattern[nX*m_brushPatternSize+nY].alpha = fOpacity;
154         }
155 }
156
157 void CGAirbrush::setConstantPattern(float fOpacity)
158 {
159     // kompletter Pinsel mit einer Opazität
160     for (unsigned int nX = 0; nX < m_brushPatternSize; nX++)
161         for (unsigned int nY = 0; nY < m_brushPatternSize; nY++)
162             m_brushPattern[nX*m_brushPatternSize+nY].alpha = fOpacity;
163 }
164
165 void CGAirbrush::setArbitraryPattern()
166 {
167     // öffne Datei
168     ifstream hPattern("32x32.pat");
169
170     // lies Pinsel ein
171     for (unsigned int nX = 0; nX < m_brushPatternSize; nX++)
172         for (unsigned int nY = 0; nY < m_brushPatternSize; nY++)
173             hPattern >> m_brushPattern[nX*m_brushPatternSize+nY].alpha;
174 }
175
176 void CGAirbrush::setColor(GLfloat red, GLfloat green, GLfloat blue)
177 {
178     // ändere alle Farbwerte im Pinsel
179     for (unsigned int nX = 0; nX < m_brushPatternSize; nX++)
180         for (unsigned int nY = 0; nY < m_brushPatternSize; nY++)
181         {
182             m_brushPattern[nX*m_brushPatternSize+nY].r = red;
183             m_brushPattern[nX*m_brushPatternSize+nY].g = green;
184             m_brushPattern[nX*m_brushPatternSize+nY].b = blue;
185         }
186 }
187
188 int main(int argc, char* argv[]) {
189     CGAirbrush airbrush(32);
190     airbrush.start("CGAirbrush, Stephan Brumme, 702544", false);
191     return(0);
192 }
193
194