2D grafikus rendszerek (BSc)

Download Report

Transcript 2D grafikus rendszerek (BSc)

2D grafikus rendszerek
Szirmay-Kalos László
2D grafikus editor:
GUI, use-case, dinamikus modell
L
LD
L
L
MouseLDown
MouseLDown
...
MouseLDown
MouseRDown
R
első pont
második
n.
utolsó
LU
MouseLDown
MouseMove
MouseLUp
pick?
mozgat
letesz
Funkcionális modell
Bemeneti csővezeték
Eszközképtér
TV-1
TM-1
Képtérvilág
Világlokális mod.
kamera
Virtuális világ
Eszköz koord.
(xe, ye)
Kurzor
(xp, yp)
Kép
frissités
vektorizáció
rasztertár
Pixel
műveletek
Raszterizáció
Vágás
Kimeneti csővezeték
Világképtér
TV
Modellezési
transzf.
TM
Osztálydiagram
Point
x,y
tároló
Object
transform
AddPrimitive()
GetPrimitive()
Scene
actobject
tároló
InputPipe()
Pick()
Render()
tároló
Primitive
color
AddPoint()
Vectorize()
RenderPrimitive
Transform()
Clip()
Draw()
Controller +
View
Window
state
MouseLD()
MouseLU()
MouseMov()
PutPixel()
Camera
Op.rendszer
window
függő
viewport
ClipWindow()
ViewTransform()
Curve
Polygon
r(t)
Vectorize()
Vectorize()
RPolyline RPolygon
Clip()
Clip()
Bezier
B-Spline
Draw()
Draw()
r(t)
r(t)
Polyline
Vectorize()
Transform
float m[3][3]
RPoints
Clip()
Draw()
Rect
x,y,w,h
Color
float R, G, B
Kimeneti csővezeték: Render
Scene :: Render ( ) {
Transform Tv = camera.ViewTransform( );
for each object obj {
// prioritás
Transform Tm = obj -> Transform( );
Transform Tc = Tm * Tv;
for each primitive p of object obj { // prioritás
RenderPrimitive * rp = p -> Vectorize( );
rp -> Transform( Tc );
if ( rp -> Clip( camera.ClipWindow ) ) rp -> Draw( );
}
}
}
Ablak-nézet transzformáció
class Camera {
h
Rect Viewport, Window;
(x, y)
w
Transform ViewTransform( ) {
vw/ww
Transform t =
0
0
0
vh/wh
0
vx-wxvw/ww vy-wyvh/wh 1
return t;
}
Rect ClipWindow( ) { return Viewport; }
};
Vektorizáció
class Curve : Primitive {
virtual Point r( float t ) = 0;
RenderPrimitive Vectorize( ) {
RPolyLine * polyline = new RPolyLine();
for(int i = 0; i <= NVECTOR; i++) {
float t = (float)i / NVECTOR;
t1= 0, t2 , ... , tn =1
polyline -> AddPoint( r( t ) );
}
r(ti)
return polyline;
}
};
Bezier görbe: r(t)
n i
class Bezier : Curve {
n-i
B
(t)
=
t
(1-t)
i
i
Point r( float t ) {
Point rr(0, 0);
int n = npoints – 1;
for(int i = 0; i < npoints; i++) {
float Bi = 1;
for(int j = 1; j <= i; j++) Bi *= (float)(n-j+1)/j;
Bi *= pow(t, i) * pow(1-t, n-i);
rr += points[i] * Bi;
}
return rr;
}
r(t) = S Bi(t) ri
};
()
class RenderPrimitive {
Point *
points;
Color
color;
void Transform( Transform T ) {
for each point i do points[i].Transform( T );
}
virtual Bool Clip( Rect cliprect ) = 0;
virtual void Draw( ) = 0;
};
RenderPrimitive
class RPolyLine : public RenderPrimitive {
Bool Clip( Rect cliprect ) { Cohen-Sutherland vágás }
void Draw( ) { Szakaszrajzoló algoritmus: PutPixel(X, Y, color) }
};
class RPolygon : public RenderPrimitive {
Bool Clip( Rect cliprect ) { Sutherland-Hodgeman vágás }
void Draw( ) { Területkitöltő algoritmus: PutPixel(X, Y, color) }
};
Bemeneti csővezeték: pontok
beépítése a virtuális világba
Scene :: InputPipeline( int X, int Y ) {
if ( !actobject ) actobject = AddObject( );
Transform Tm = actobject -> Transform( );
Transform Tv = camera.ViewTransform( );
Transform Tci = (Tm * Tv).Invert( );
Point p = Point(X, Y).Transform( Tci );
actobject -> GetPrimitive( ) -> AddPoint(p);
}
Window :: MouseLD( int X, int Y ) {
... ha az állapot szerint a pontot be kell építeni
scene.InputPipeline( X, Y );
scene.Render(); // visszacsatolás
}
Primitív (objektum) kiválasztása
Scene :: Pick( int X, int Y ) {
Rect pickw( X-5, Y-5, X+5, Y+5 );
fordown each object obj { // vissza prioritás
Transform Tm = obj -> Transform( );
Transform Tv = camera.ViewTransform( );
Transform Tc = Tm * Tv;
fordown each primitive p of object obj {
RenderPrimitive * rp = p -> Vectorize( );
rp -> Transform( Tc );
if ( rp -> Clip( pickw ) ) { actobj = obj; return; }
}
}
}
Window :: MouseLD( X, Y ) {
... ha az állapot szerint kiválasztás:
}
scene.Pick( X, Y );
Operációs rendszer illesztés
MouseLD()
MouseLU()
MouseMov()
Alkalmazás
GLUT
Operációs
és ablakozó
rendszer
(Windows)
transzform
vágás raszterizáció
Rasztertár
PutPixel()
OpenGL
alkalmazás
main
DisplayFunc
GLUT/OpenGL
Ablak létrehozás
callback regisztráció
GLUT
KeyboadFunc
SpecialFunc
Operációs
és ablakozó
rendszer
(Windows)
callback-ek
ReshapeFunc
MouseFunc
MotionFunc
OpenGL
grafikus
hardver
IdleFunc
kimeneti csővezeték
Rasztertár
OpenGL szintaxis
gl könyvtár része
glVertex3dv( … )
Paraméterszám
2 - (x, y)
3 - (x, y, z),
(R, G, B)
4 - (x, y, z, h)
(R, G, B, A)
Adattípus
b - byte
ub - unsigned byte
s - short
i - int
f - float
d - double
Vektor vagy skalár
v - vektor
- skalár
Ablakozó – OpenGL – alkalmazás
elhelyezkedése
applikáció
GLUT
glX, wgl
glu
X v. MS-Win
gl
hw
Ablak-kezelés
widgetek
Ablakozógl híd
Window
menedzsment
Utility-k,
tesszellátorok
OpenGL transzformációk
(2D-s utánérzés)
Normalizált
képernyő
x
y Modelview
z=0
mátrix
h=1
TM
Projection
mátrix
TV
Homogén
osztás
Viewport
transzf.
raszterizáció
vágás
1,1
-1,-1
képernyő
OpenGL mátrix

OpenGL specifikáció:
 x '  T0 T4 T8
 y '  T T T
5
9
  1
 z '  T2 T6 T10
  
h'  T3 T7 T11

T12   x 
T13   y 
 
T14   z 
  
T15  h 
Mi:
x'
y ' z ' h'  x
y
 T0
T
z h   4
 T8

T12
T1
T2
T5
T9
T6
T10
T13 T14
T3 
T7 

T11 

T15 
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h> // download!!!
main( int argc, char *argv[] ) {
glutInitWindowSize(200, 200);
glutInitWindowPosition(100, 100);
glutInit(&argc, argv);
glutInitDisplayMode( GLUT_RGB );
glutCreateWindow("Sample Window");
// callback függvények
glutKeyboardFunc( Keyboard );
glutDisplayFunc( ReDraw );
// transzformáció
glViewport(0, 0, 200, 200);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity( );
glMatrixMode(GL_PROJECTION);
glLoadIdentity( );
gluOrtho2D(0., 100., 0., 100.);
// fő hurok
glutMainLoop();
}
OpenGL/
(100,100)
GLUT
200
inicializálás
200
(100,100)
ablak
(0,0)
Eseménykezelés és rajzolás
void ReDraw( ) {
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
}
void Keyboard(unsigned char key,
int x, int y) {
if (key == ‘d’) {
(0,0)
glColor3d( 0.0, 1.0, 0.0 );
glBegin(GL_TRIANGLES);
glVertex2d(10.0, 10.0);
glVertex2d(20.0, 100.0);
glVertex2d(90.0, 30.0);
glEnd( );
glFlush( );
}
}
Ablak újrarajzoláskor elveszik!
ablak
(100,100)
(200,200)
A háromszög
void ReDraw( ) {
újrarajzoláskor
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
megmarad
if ( haromszog ) {
bool haromszog = false;
glColor3d( 0.0, 1.0, 0.0 );
glBegin(GL_TRIANGLES);
glVertex2d(10.0, 10.0);
glVertex2d(20.0, 100.0);
glVertex2d(90.0, 30.0);
glEnd( );
}
glFlush( );
}
void Keyboard(unsigned char key, int x, int y) {
if (key == 'd') {
haromszog = true;
ReDraw( );
}
}
Nem rajzol
void ReDraw( ) {
glClearColor(0, 0, 0, 0);
feleslegesen
glClear(GL_COLOR_BUFFER_BIT);
if ( haromszog ) {
sokszor
glColor3d( 0.0, 1.0, 0.0 );
bool haromszog = false;
glBegin(GL_TRIANGLES);
glVertex2d(10.0, 10.0);
glVertex2d(20.0, 100.0);
glVertex2d(90.0, 30.0);
glEnd( );
}
glFlush( );
}
void Keyboard(unsigned char key, int x, int y) {
if (key == 'd') {
haromszog = true;
glutPostRedisplay();
}
}
2D grafikus editor GLUT/OpenGL-lel
main
DisplayFunc
GLUT
Redraw
MouseFunc
MouseDown
MouseMove
Operációs
és ablakozó
rendszer
MotionFunc
OpenGL
transzform
vágás
raszterizáció
Raszter
műveletek
Rasztertár
RGB
Osztálydiagram
Scene
actobject
Object
transform
AddPrimitive()
GetPrimitive()
Primitive
color
AddPoint()
Draw()
Point
x,y
Polyline
Draw()
Curve
r(t)
Draw()
Bezier
r(t)
InputPipe()
Pick()
Render()
RenderPrimitive
Transform()
Camera
Clip()
ClipWindow()
Draw()
ViewTransform()
window
viewport
Polygon
Draw()
B-Spline
r(t)
RPolyLine RPolygon RPointList
Clip()
Clip()
Clip()
Draw()
Draw()
Draw()
Window
state
MouseLD()
MouseLU()
MouseMov()
PutPixel()
GLUT: inicializálás
main(argc, argv) {
glutInitWindowSize(200, 200);
glutInitWindowPosition(100, 100);
glutInit(&argc, argv);
glutInitDisplayMode( GLUT_RGB );
glutCreateWindow("2D graphics editor");
glutMouseFunc(MouseDown); // callback
glutMotionFunc(MouseMove);
glutDisplayFunc(ReDraw);
glutMainLoop();
}
// fő hurok
GLUT: eseménykezelés
void ReDraw( ) {
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
window.scene.Render( );
}
void MouseDown( int button, int state, int x, int y ) {
if (button == GLUT_LEFT && state == GLUT_DOWN)
window.MouseLD(x, y);
…
}
void MouseMove( int x, int y ) {
window.MouseMov(x, y);
}
OpenGL Render
Scene :: Render ( ) {
glViewport(camera.viewport.Left(), camera.viewport.Bottom(),
camera.viewport.Width(), camera.viewport.Height());
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluOrtho2D(camera.window.Left(), camera.window.Right(),
camera.window.Bottom(), camera.window.Top());
glMatrixMode( GL_MODELVIEW );
for each object obj {
glLoadIdentity(); // 4x4 matrix
glMultMatrixf(obj->Transform());
for each primitive p of object obj
p -> Draw( ); // OpenGL-nek
}
}
ux uy
vx vy
[x, y, 1] ox oy
{
ux uy 0
vx vy 0
0
}
[x, y, 0, 1]
0
ox oy
0
0
1
0
1
0
0
0
1
Curve rajzolás
class Curve : Primitive {
void Draw( ) {
glColor3d( color.R, color.G, color.B );
glBegin( GL_LINE_STRIP );
for(int i = 0; i <= NVECTOR; i++) {
float t = (float)i / NVECTOR;
Point p = r( t );
glVertex2d(p.x, p.y);
}
glEnd( );
}
};
OpenGL: primitívek
GL_LINES
GL_POINTS
GL_LINE_STRIP
GL_LINE_LOOP
GL_TRIANGLES
GL_TRIANGLE_STRIP
GL_POLYGON
GL_QUADS
GL_TRIANGLE_FAN
GL_QUAD_STRIP
Házi
//================================================================================
// Szamitogepes grafika hazi feladat keret. Ervenyes 2010-tol.
// A //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// sorokon beluli reszben celszeru garazdalkodni, mert a tobbit ugyis toroljuk.
// A Hazi feladat csak ebben a fajlban lehet.
// Tilos:
// - mast "beincludolni", illetve mas konyvtarat hasznalni
// - faljmuveleteket vegezni (printf is fajlmuvelet!)
// --------------------------------------------------------// Csak az órán elhangzott gl/glu/glut fuggvenyek hasznalhatok:
// glBegin, glVertex[2|3]f, glColor3f, glNormal3f, glTexCoord2f, glEnd, glDrawPixels
// glViewport, glMatrixMode, glLoadIdentity, glMultMatrixf, gluOrtho2D,
// glTranslatef, glRotatef, glScalef, gluLookAt, gluPerspective,
// glPushMatrix,glPopMatrix,
// glMaterialfv, glMaterialfv, glMaterialf, glLightfv
// glGenTextures, glBindTexture, glTexParameteri, glTexImage2D, glTexEnvi,
// glShadeModel,
// glEnable/Disable a kovetkezokre: GL_LIGHT[0..7],
// GL_LIGHTING, GL_NORMALIZE, GL_DEPTH_TEST, GL_CULL_FACE, GL_TEXTURE_2D, GL_BLEND,
//
// A házi feladat felesleges programsorokat NEM tartalmazhat!
//================================================================================
#include <math.h>
#include <stdlib.h>
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h> // A GLUT-ot le kell tolteni
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Innentol modosithatod...
// Nev
: <VEZETEKNEV(EK)> <KERESZTNEV(EK)>, Neptun : <NEPTUN KOD>
//-------------------------------------------------------void onInitialization( ) { } // Inicializacio,
void onDisplay( ) {// Rajzolas
glClearColor(0.1f, 0.2f, 0.3f, 1.0f);
// torlesi szin beallitasa
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // kepernyo torles
// ...
glutSwapBuffers();
// Buffercsere: rajzolas vege
}
void onKeyboard(unsigned char key, int x, int y) { // Billentyuzet esemeny
if (key == 'd') glutPostRedisplay( );
// d beture rajzold ujra a kepet
}
void onMouse(int button, int state, int x, int y) {// Eger esemeny
if (button == GLUT_LEFT && state == GLUT_DOWN);
}
Házi
void onIdle( ) {// `Idle' esemenykezelo, jelzi, hogy az ido telik
long time = glutGet(GLUT_ELAPSED_TIME); // program inditasa ota eltelt ido
}
// ...Idaig modosithatod
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Még mindig házi
// A C++ program belepesi pontja, nem bántani!
int main(int argc, char **argv) {
glutInit(&argc, argv);
// GLUT inicializalasa
glutInitWindowSize(600, 600);
glutInitWindowPosition(100, 100);
// 8 bites R,G,B,A + dupla buffer + melyseg buffer
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("Grafika hazi feladat");
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// A MODELVIEW egysegmatrix
onInitialization();
// Az altalad irt inicializalas
glutDisplayFunc(onDisplay);
glutMouseFunc(onMouse);
glutIdleFunc(onIdle);
glutKeyboardFunc(onKeyboard);
glutMainLoop();
return 0;
// Esemenykezelok regisztralasa
// A PROJECTION egysegmatrix
// Esemenykezelo hurok