Changes between Version 11 and Version 12 of opengl-intro


Ignore:
Timestamp:
Feb 14, 2009, 1:14:39 PM (12 years ago)
Author:
msitar
Comment:

Urejeno celotno besedilo, vključno s pripadajočimi programi

Legend:

Unmodified
Added
Removed
Modified
  • opengl-intro

    v11 v12  
    1212  brez bistvenih popravkov kode lahko pišemo tudi v jeziku C in C++.
    1313
     14[[BR]][[BR]]
    1415
    1516= Uvod =
     
    5152vmesnike.
    5253
     54[[BR]][[BR]]
    5355
    5456= Enostavni OpenGL program =
     
    5961GL ukazov, ki pa so splošno uporabni in so bili zato
    6062standardizirani.
     63
     64[[BR]]
    6165
    6266== Dogodki ==
     
    97101okenskemu sistemu, za katere dogodke bo skrbel in za te dogodke mu bo
    98102sistem tudi pošiljal sporočila.
     103
     104[[BR]]
    99105
    100106== GLUT ==
     
    161167  ''#include <GL/glut.h> ''
    162168
    163   {{{
    164   2. Dopovej Fortranu, da so imena, kot je npr. ''display'',
    165   podprogrami in ne spremenljivke. To se naredi z ukazom ''external''
    166   }}}
     169{{{
     170#!comment
     1712. Dopovej Fortranu, da so imena, kot je npr. ''display'',
     172podprogrami in ne spremenljivke. To se naredi z ukazom ''external''
     173}}}
    167174
    168175  '''2.''' Inicializiraj GLUT
     
    185192  '''7.''' Zadnji je klic ''glutMainLoop'', iz katerega se program
    186193  vrne, ko zapremo okno. Ob tem glavni program konča.
     194
     195[[BR]]
    187196
    188197== Izris v jeziku OpenGL ==
     
    221230Tipi argumentov (končnic) so naslednji:
    222231
    223 '''f''' V jeziku C float in real ali real*4 za Fortran
    224 
    225 '''d''' double za C in real*8 za Fortran
    226 
    227 '''i''' integer
    228 
    229 '''s''' short integer v C-ju ali integer*2 za F
     232  '''f''' V jeziku C float in real ali real*4 za Fortran
     233
     234  '''d''' double za C in real*8 za Fortran
     235
     236  '''i''' integer
     237
     238  '''s''' short integer v C-ju ali integer*2 za F
    230239
    231240Namesto fiksiranega števila argumentov obstajajo tudi funkcije, ki
     
    233242''v''. Nekaj primerov končnic:
    234243
    235 '''3f''' Sledijo trije argumenti realnih števil
    236 
    237 '''3i''' Sledijo trije argumenti celih števil
    238 
    239 '''3fv''' Sledi vektor treh realnih števil
     244  '''3f''' Sledijo trije argumenti realnih števil
     245
     246  '''3i''' Sledijo trije argumenti celih števil
     247
     248  '''3fv''' Sledi vektor treh realnih števil
    240249
    241250Ker je GL v osnovi 3D, pomeni, da so argumenti, če sta podani le dve
     
    304313animacijah.
    305314
     315[[BR]][[BR]]
     316
    306317= Geometrijski primitivi =
    307318
     
    381392}
    382393}}}
    383 
    384 
    385394
    386395Pred vsako točko je podana še trenutna barva. Izrisani
     
    412421Slika 2: Normala
    413422
     423[[BR]][[BR]]
    414424
    415425= Geometrijske transformacije =
     
    456466Da smo spravili naših 11 točk lomljenke v okvir -1, 1 je bilo
    457467potrebno premakniti koordinatni sistem osi ''x'' za 5, ga nato še
    458 skalirati tako, da smo iz območja [0,10] dobili območje [-3.14,
     468skalirati tako, da smo iz območja [ 0,10 ] dobili območje [-3.14,
    4594693.14]. čeprav smo za izračun koordinate y potrebovali na osi x
    460470območje [-3.14, 3.14] pa je potrebna os ''x'' za izris v območju
    461471[-1,1]. Zato pri izrisu podajamo os ''x'' tako, da ponovno
    462 poračunavamo območje [0,10] v območje [-1,1], tako da ''i''-ju
     472poračunavamo območje [ 0,10 ] v območje [-1,1], tako da ''i''-ju
    463473odštejemo 5 in delimo z 5. Lahko bi tudi delili s 5 in odšteli
    4644741. Nekoliko bi poenostavili stvari, če bi imeli vsaj en kordinatni
     
    541551tako, da se ta vmesna točka pomnoži še z 1/3.14.
    542552
     553[[BR]]
     554
    543555== Nadzor transformacijske matrike ==
    544556
     
    638650potem ponovno obnovi z ukazom ''Pop''.
    639651
     652[[BR]]
     653
    640654== Globinski pomilnik ==
    641655
     
    669683pomnilnika je potrebna tudi nastavitev projekcijske matrike, kot je to
    670684opisano v poglavju Transformacije pogleda.
     685
     686[[BR]]
    671687
    672688== Animacija ==
     
    768784novih položajev. Prostorski pomnilnik v tem primeru ni potreben,
    769785saj je zagotovljeno, da se izrisi prekrijejo v pravilnem vrstnem redu.
     786
     787[[BR]]
    770788
    771789== Transformacije pogleda ==
     
    880898paralelne projekcije ''glOrtho(l,r,b,,n,f)'':
    881899       
    882   ''PM = [2/(r-l), 0, 0, (r+l)/(l-r); 0, 2/(t-b), 0, (t+b)/(t-b); 0, 0, 2/(f-n), (f+n)/f-n); 0, 0, 0, 1]''
     900  ''PM = [ 2/(r-l), 0, 0, (r+l)/(l-r); 0, 2/(t-b), 0, (t+b)/(t-b); 0, 0, 2/(f-n), (f+n)/f-n); 0, 0, 0, 1 ]''
    883901
    884902Za primer normalizacijskega prostora v obsegu [-1,1] je tako matrika paralelne
    885903projekcije
    886904
    887    ''PM(-1, 1, -1, 1, -1, 1) = [1, 0, 0, 0; 0, 1, 0, 0; 0, 0, -1, 0; 0, 0, 0, 1]''
     905   ''PM(-1, 1, -1, 1, -1, 1) = [ 1, 0, 0, 0; 0, 1, 0, 0; 0, 0, -1, 0; 0, 0, 0, 1 ]''
    888906
    889907kar se razlikuje od enotske prav v koordinati ''z''. Če bi
     
    894912nelogično postavil v ospredje modro stranico in ne rdečo.
    895913
     914[[BR]][[BR]]
    896915
    897916= Osvetlitev =
     
    10101029rezultat upodabljanja z osvetlitvijo.
    10111030
     1031[[BR]][[BR]]
    10121032
    10131033= Tekst =
     
    11671187Slika 7: Osenčen model kocke z ''bitmap'' napisi
    11681188
     1189[[BR]][[BR]]
    11691190
    11701191= Uporabniški vmesnik =
     
    11731194dodatne funkcionalnost knjižnice GLUT za vnos dodatnih podatkov v
    11741195program. To je predvsem uporaba tipk in miške.
     1196
     1197[[BR]]
    11751198
    11761199== Rotacija s tipkami ==
     
    12271250}}}
    12281251
     1252[[BR]]
     1253
    12291254== Miška in inverzna projekcija ==
    12301255
     
    12331258ravnini (x,y) s tem, da je potrebno zaslonske koordinate pretvoriti
    12341259nazaj v modelne.
    1235 {\scriptsize\begin{verbatim}
    1236 subroutine redraw
    1237 implicit none
    1238 include 'GL/fgl.h'
    1239 common /vertices/ n, vertex(2, 100)
    1240 integer n, i
    1241 real vertex
    1242 call fglClear(GL_COLOR_BUFFER_BIT)
    1243 call fglbegin(GL_LINE_STRIP)
    1244 do i = 1,n
    1245         call fglVertex2f(vertex(1, i), vertex(2, i))
    1246 end do
    1247 call fglend
    1248 call fglFlush
    1249 end
    1250 
    1251 subroutine mouse (button, state, x, y)
    1252 implicit none
    1253 include 'GL/fglut.h'
    1254 include 'GL/fgl.h'
    1255 include 'GL/fglu.h'
    1256 common /vertices/ n, vertex(2, 100)
    1257 integer n, i
    1258 real vertex
    1259 integer button, state, x, y
    1260 integer viewport(4)
    1261 real*8 mvmatrix(16), projmatrix(16)
    1262 real*8 wx, wy, wz               ! returned world x, y, z coords
    1263 real*8 px, py, pz               ! picked window coortinates
    1264 integer status
    1265 
    1266 if (button .eq. GLUT_LEFT_BUTTON) then
    1267  if (state .eq. GLUT_DOWN) then
    1268         call fglGetIntegerv (GL_VIEWPORT, viewport)
    1269         call fglGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix)
    1270         call fglGetDoublev (GL_PROJECTION_MATRIX, projmatrix)
    1271         note viewport(4) is height of window in pixels
    1272         px = x
    1273         py = viewport(4) -  y - 1
    1274         pz = 0.0
    1275         print *, ' Coordinates at cursor are ', px, py
    1276         status = fgluUnProject (px, py, pz,  mvmatrix,
    1277                     projmatrix,  viewport, wx, wy, wz)
    1278         print *, 'World coords at z=0.0 are ', wx, wy, wz
    1279         n = n + 1
    1280         vertex(1, n) = wx
    1281         vertex(2, n) = wy
    1282         call fglutPostRedisplay
    1283  end if
    1284 end if
    1285 end
    1286 
    1287 
    1288 program main
    1289 external redraw
    1290 external mouse
    1291 include 'GL/fglut.h'
    1292 call fglutinit
    1293 call fglutinitdisplaymode(ior(GLUT_SINGLE,GLUT_RGB))
    1294 call fglutInitWindowSize (500, 500)
    1295 call fglutInitWindowPosition (100, 100)
    1296 window = fglutcreatewindow('Click in window')
    1297 call fglutdisplayfunc(redraw)
    1298 call fglutMouseFunc(mouse)
    1299 call fglutmainloop
    1300 end
    1301 \end{verbatim}
    1302 }
    1303 
    1304 
    1305 
    1306 \subsection{Kvaternionska rotacija}
     1260
     1261{{{
     1262#!c
     1263#include <stdio.h>
     1264#include <stdlib.h>
     1265#include <GL/glut.h>
     1266
     1267#define MAXN 100
     1268
     1269GLint n;
     1270GLfloat *vertex;
     1271
     1272void redraw()
     1273{
     1274  int i;
     1275  glClear(GL_COLOR_BUFFER_BIT);
     1276  glPushMatrix();
     1277  glColor3f(1,1,1);
     1278  glBegin(GL_LINE_STRIP);
     1279  for (i = 0; i < n; i++)
     1280  {
     1281    glVertex2fv(&vertex[i*2]);
     1282  }
     1283  glEnd();
     1284 
     1285  for (i = 0; i < n; i++) //Adding spheres on world coords
     1286  {
     1287  glColor3f(1,0,0);
     1288  glPushMatrix();
     1289  glTranslatef(vertex[i*2],vertex[i*2+1],0);
     1290  glutSolidSphere(0.01,8,8);
     1291  glPopMatrix();
     1292  }
     1293  glPopMatrix();
     1294  glutSwapBuffers();
     1295}
     1296
     1297void mouse(int button, int state, int x, int y)
     1298{
     1299  GLint viewport[4];
     1300  GLdouble mvmatrix[16], projmatrix[16];
     1301  GLdouble wx, wy, wz; //Returned world x, y, z coords
     1302  GLdouble px, py, pz; //Picked window coordinates
     1303  int status;
     1304  if (button == GLUT_LEFT_BUTTON )
     1305  {
     1306  if (state == GLUT_DOWN)
     1307    {
     1308      glGetIntegerv (GL_VIEWPORT, viewport);
     1309      glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix);
     1310      glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);
     1311      //Note viewport[4] is height in pixels
     1312      px = x;
     1313      py = viewport[3] - y - 1;
     1314      pz = 0.0;
     1315      fprintf (stderr, "Coordinates at cursor are %f, %f\n", px, py);
     1316      status = gluUnProject (px, py, pz, mvmatrix, projmatrix, viewport, &wx, &wy, &wz);
     1317      fprintf(stderr, "World coords at z=0.0 are %f, %f, %f\n", wx, wy, wz);
     1318      if (n < MAXN)
     1319      {
     1320        vertex[n*2] = wx;
     1321        vertex[n*2+1] = wy;
     1322        n=n+1;
     1323      }       
     1324      else
     1325      {
     1326        fprintf(stderr, "Maximum number of points was received!\n");
     1327      }
     1328      glutPostRedisplay();
     1329    }
     1330  }
     1331}
     1332
     1333
     1334int main(int argc, char *argv[])
     1335{
     1336  vertex = (GLfloat *) malloc(2 * MAXN * sizeof (GLfloat));
     1337  glutInit(&argc, argv);
     1338  glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
     1339  glutInitWindowSize (700, 700);
     1340  glutInitWindowPosition (0, 0);
     1341  glutCreateWindow("Click in window");
     1342  glutDisplayFunc(redraw);
     1343  glutMouseFunc(mouse);
     1344  glutMainLoop();
     1345  return 0;
     1346}
     1347}}}
     1348
     1349[[BR]]
     1350
     1351== Kvaternionska rotacija ==
     1352
    13071353Naslednji program prikazuje vrtenje osenčenega čajnika z
    13081354miško. V ta namem se uporabi že izdelam podprogram v jeziku C,
    1309 ki ga kličemo iz fortrana in nam omogoča kvaternionsko
     1355ki nam omogoča kvaternionsko
    13101356rotacijo. Za vrtenje enotske krogle je potrebno zaznati tako
    1311 začetni pritisk na gumb (podprogram \emph{mouse}) kot vse
    1312 naslednje pomike miške (podprogram \emph{motion}).
    1313 
    1314 
    1315 {\scriptsize\begin{verbatim}
    1316 subroutine display
    1317 implicit none
    1318 include 'GL/fgl.h'
    1319 common /quaternion/ last(4), cur(4)
    1320 real last, cur, m(4,4)
    1321 call build_rotmatrix(m, cur)
    1322 call fglLoadIdentity
    1323 call fglMultMatrixf(m)
    1324 call fglclear(GL_COLOR_BUFFER_BIT+GL_DEPTH_BUFFER_BIT)
    1325 call fglutSolidTeapot(dble(0.5))
    1326 call fglutSwapBuffers
    1327 end
    1328 
    1329 subroutine motion (x, y)
    1330 include 'GL/fglut.h'
    1331 include 'GL/fgl.h'
    1332 implicit none
    1333 integer x, y
    1334 common /quaternion/ last(4), cur(4)
    1335 common /mousestart/ beginx, beginy
    1336 common /viewport/ width, height
    1337 integer width, height
    1338 integer beginx, beginy
    1339 real last, cur
    1340 real p1x, p1y, p2x, p2y
    1341 p1x = (2.0*beginx - width)/width
    1342 p1y = (height - 2.0*beginy)/height
    1343 p2x = (2.0 * x - width) / width
    1344 p2y = (height - 2.0 * y) / height
    1345 call trackball(last,p1x, p1y, p2x, p2y)
    1346 call add_quats(last, cur, cur)
    1347 beginx = x
    1348 beginy = y
    1349 call fglutPostRedisplay
    1350 end
    1351 
    1352 subroutine mouse (button, state, x, y)
    1353 implicit none
    1354 integer button, state, x, y
    1355 include 'GL/fglut.h'
    1356 include 'GL/fgl.h'
    1357 include 'GL/fglu.h'
    1358 common /mousestart/ beginx, beginy
    1359 integer beginx, beginy
    1360 beginx = x
    1361 beginy = y     
    1362 end
    1363 
    1364 subroutine reshape(w, h)
    1365 include 'GL/fgl.h'
    1366 integer w, h
    1367 real*8 l
    1368 common /viewport/ width, height
    1369 integer width, height
    1370 width=w
    1371 height=h
    1372 l = 1
    1373 call fglViewPort(0, 0, w, h)
    1374 call fglMatrixMode(GL_PROJECTION)
    1375 call fglLoadIdentity
    1376 call fglOrtho(-l,l,-l,l,-l,l)
    1377 call fglMatrixMode(GL_MODELVIEW)
    1378 call fglLoadIdentity
    1379 end
    1380 
    1381 program trackballdemo
    1382 implicit none
    1383 include 'GL/fglut.h'
    1384 include 'GL/fgl.h'
    1385 include 'GL/fglu.h'
    1386 external display
    1387 external motion
    1388 external mouse
    1389 external reshape
    1390 integer window
    1391 common /quaternion/ last(4), cur(4)
    1392 real last, cur
    1393 call trackball(cur, 0.0, 0.0, 0.0, 0.0)
    1394 call fglutinit
    1395 call fglutinitdisplaymode(GLUT_DOUBLE+GLUT_RGB+GLUT_DEPTH)
    1396 window = fglutcreatewindow('Use mouse to rotate')
    1397 call fglutdisplayfunc(display)
    1398 call fglutmousefunc(mouse)
    1399 call fglutmotionfunc(motion)
    1400 call fglutreshapefunc(reshape)
    1401 call fglEnable(GL_LIGHTING)
    1402 call fglEnable(GL_LIGHT0)
    1403 call fglEnable(GL_DEPTH_TEST)
    1404 call fglutmainloop
    1405 end
    1406 \end{verbatim}
    1407 }
     1357začetni pritisk na gumb (podprogram ''mouse'') kot vse
     1358naslednje pomike miške (podprogram ''motion'').
     1359
     1360{{{
     1361#!c
     1362#include <GL/glut.h>
     1363#include "trackball.h"
     1364#include "trackball.c"
     1365
     1366GLfloat m[4][4];               
     1367float last[4];
     1368float cur[4];
     1369int width;
     1370int height;
     1371int beginx;
     1372int beginy;
     1373float p1x;
     1374float p1y;
     1375float p2x;
     1376float p2y;
     1377
     1378void display()
     1379{
     1380  glPushMatrix();
     1381  build_rotmatrix(m, cur); 
     1382  glLoadIdentity();
     1383  glMultMatrixf(*m);
     1384  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
     1385  glutSolidTeapot(0.5);
     1386  glPopMatrix();
     1387  glutSwapBuffers();
     1388}
     1389
     1390void mouse(int button,int state, int x, int y)   
     1391{
     1392  beginx = x;
     1393  beginy = y;
     1394}
     1395
     1396void motion(int x,int y)   
     1397{
     1398  p1x = (2.0*beginx - width)/width;
     1399  p1y = (height - 2.0*beginy)/height;
     1400  p2x = (2.0 * x - width) / width;
     1401  p2y = (height - 2.0 * y) / height;
     1402  trackball(last,p1x, p1y, p2x, p2y);   
     1403  add_quats(last, cur, cur);   
     1404  beginx = x;
     1405  beginy = y;
     1406  glutPostRedisplay();   
     1407}
     1408
     1409void reshape (int w, int h)
     1410{
     1411  width=w;
     1412  height=h;
     1413  double l;
     1414  l = 1;
     1415  glViewport (0, 0, w, h);
     1416  glMatrixMode (GL_PROJECTION);
     1417  glLoadIdentity();
     1418  glOrtho(-l, l, -l, l, -l, l);
     1419  glMatrixMode(GL_MODELVIEW);
     1420  glLoadIdentity();
     1421}
     1422
     1423
     1424int main(int argc, char *argv[])
     1425{
     1426  glutInit(&argc, argv);
     1427  trackball(cur, 0.0, 0.0, 0.0, 0.0);
     1428  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
     1429  glutCreateWindow("Rotacija z misko");
     1430  glutDisplayFunc(display);
     1431  glutMouseFunc(mouse);
     1432  glutMotionFunc(motion);
     1433  glutReshapeFunc(reshape);
     1434  glEnable(GL_LIGHTING);
     1435  glEnable(GL_LIGHT0);
     1436  glEnable(GL_DEPTH_TEST);
     1437  glutMainLoop();
     1438  return 0;
     1439}}}
     1440
    14081441Predstavljeni program je sestavljen iz dveh delov. Kodo za rotacijo v
    1409 jeziku C \texttt{trackball.c} uporabimo kod zunanje podprograme.
     1442jeziku C ''trackball.c'' uporabimo kot zunanje podprograme.
    14101443Rezultat osenčenega model, ki je bil obrnjen z miško, prikazuje
    1411 slika \ref{fig:teapot}.
    1412 \begin{figure}[htbp]
    1413   \centering
    1414   \includegraphics[width=2.1in]{teapot}
    1415   \caption{Osenčen model čajnika}
    1416 \label{fig:teapot}
    1417 \end{figure}
    1418 
    1419 
     1444slika 8.
     1445
     1446[[Image(teapot.png)]]
     1447
     1448Slika 8: Osenčen model čajnika
    14201449
    14211450