background image

 Strona główna

 Kursy

 Artykuły

 Forum

 Pliki

 Promuj Nas!

 

[Kurs OpenGL, C++] VI. Elementarne obiekty geometryczne

http://kursy.ddt.pl/?LessonId=198

1 z 7

2010-04-30 14:23

background image

Powrót

Historia odwiedzonych stron

Poprzednia lekcja

Kurs OpenGL, C++

Następna lekcja

Autor: Janusz Ganczarski

http://januszg.hg.pl/opengl/

VI. Elementarne obiekty geometryczne

Biblioteka   OpenGL  oferuje   kilka   podstawowych  prymitywów  graficznych,  które   słuza   do   modelowania

dowolnych  obiektów.   Projektanci  biblioteki  celowo  nie   umiescili  w  niej  bardziej  skomplikowanych  obiektów
(wybrane   powierzchnie   3D   zawiera   biblioteka   GLU).   Decyzja   o   stopniu   złozonosci   stosowanych   obiektów
została pozostawiona uzytkownikom i mozliwosciom konkretnych implementacji OpenGL.

6.1. Wybór rodzaju prymitywu

Definiowanie współrzednych wierzchołków figur podstawowych musi zawierac sie pomiedzy wywołaniami

funkcji:

void

 glBegin (GLenum mode)

void

 glEnd (

void

)

Parametr mode okresla rodzaj prymitywu, którego wierzchołki beda definiowane. Parametr przyjmuje jedna

z ponizszych wartosci:

GL_POINTS - punkty: {p1}, {p2}, {p3}, {p4}, ...,
GL_LINES - odcinki: {p1, p2}, {p3, p4}, {p5, p6}, ...,
GL_LINE_STRIP - łamana: {p1, p2}, {p2, p3}, {p3, p4}, ...,
GL_LINE_LOOP - łamana zamknieta: {p1, p2}, {p2, p3}, {p3, p4}, ... {pn,p1},
GL_TRIANGLES - trójkaty: {p1, p2, p3}, {p4, p5, p6}, ...,
GL_TRIANGLE_STRIP - wstega trójkatów: {p1, p2, p3}, {p3, p2, p4}, {p3, p4, p5}, {p5, p4, p6}, ...,
GL_TRIANGLE_FAN - wachlarz trójkatów: {p1, p2, p3}, {p1, p3, p4}, {p1, p4, p5}, ...,
GL_QUADS - czworokaty,
GL_QUAD_STRIP - wstega czworokatów,
GL_POLYGON - wielokat.

Szczególne   znaczenie   w  grafice   3D   ma   trójkat.   Zasadnicza   zaleta   trójkąta   jest   jego   ...   płaskosc,   co   w

geometrycznym  ujeciu   oznacza,   ze   trzy   niewspółliniowe   punkty   wyznaczaja   dokładnie   jedna   płaszczyzne   w
przestrzeni trójwymiarowej.

Przy  budowie   skomplikowanych  obiektów  3D  składajacych  sie   z  trójkątów  proporcjonalnie   rosnie  ilosc

wierzchołków,   czyli   ilosc   danych   przetwarzanych   przez   procesor   komputera   i   karty   graficznej.   Stad   duze
znaczenie ma mozliwosc definiowania wsteg (patrz rysunek 1) i wachlarzy trójkatów (rysunek 2). Prymitywy te
bowiem umozliwiaja definiowanie kolejnych trójkątów tylko przy pomocy jednego wierzchołka. Oczywiscie nie
w  każdym  przypadku   bedzie   mozliwe   wykorzystanie   wstegi   lub   wachlarza   trójkatów,   ale   wykorzystywac   te
prymitywy zawsze, gdy jest to mozliwe.

Rysunek 1.  P rogram  P rymitywy  graficzne  -  wstega  trójkatów

Rysunek 2.  P rogram  P rymitywy  graficzne  -  wachlarz  trójkatów

Nieco bardziej skomplikowana grupa prymitywów graficznych obsługiwanych przez biblioteke OpenGL sa

czworokaty i wstegi czworokatów (patrz rysunki 3 i 4). Zastosowanie tych prymitywów moze byc wygodne w
wielu sytuacjach, ale trzeba liczyc sie z nastepujacymi ograniczeniami:

wierzchołki czworokata musza znajdowac sie w jednej płaszczyznie,

P anel  Logowania

dast19

Administracja

Twój profil

Wyloguj

Uż yt kowników

Obecnie aktywnych:

14

Zalogowanych:

2

Zarejestrowanych:

3855

Ostatnie 24h:

646

Non-cookie 24h:

2051

Wszystkich:

178944

O c z e kuj ąc e  t e mat y

Lista jest pusta.

Pokaż wszystkie (0)

Os tatnia  Aktualizacja

2010-04-29 22:01:07

(wczoraj)

O st atnio akt ywni

dast19

1 min

Piotr Szawdyński

5 min

Iname

 

(√ιק)

17 min

szywro5

29 min

Saiph

34 min

markon

57 min

imandre

75 min

WunM

93 min

kuba1817

2 godz

killersft

2 godz

fish13

2 godz

kizia

2 godz

Kurs programowania 699zł

50%teoria 50%praktyki - 120
godzin nauka w
centrum,male grupy 5-10 os

www.gowork.pl

Romulus drewno do
ogrodu

Kompleksowe wyposażenie
ogrodów, placów zabaw,
działek, parków.

www.romulus.waw.pl

[Kurs OpenGL, C++] VI. Elementarne obiekty geometryczne

http://kursy.ddt.pl/?LessonId=198

2 z 7

2010-04-30 14:23

background image

rysowanie czworokata zawierajacego samoprzeciecie krawedzi (czwarty czworokat na rysunku 3) moze
byc nieprawidłowe w niektórych sytuacjach.

Ponadto nalezy dodac, ze wiele implementacji biblioteki OpenGL w procesie przetwarzania wierzchołków

dzieli czworokaty na trójkaty, co takze może powodowac nieoczekiwane efekty.

Rysunek 3.  P rogram  P rymitywy  graficzne  – czworokąty

Rysunek 4.  P rogram  P rymitywy  graficzne  -  wstega  czworokątów

Ostatnim  prymitywem  graficznym  jest   wielokat.   Wielokaty   podlegaja   takim  samym  ograniczeniom  jak

czworokaty. Ich wierzchołki musza znajdowac sie w jednej płaszczyznie, a krawedzie nie powinny sie przecinac.
Podobnie jak w przypadku czworokatów, wiele implementacji OpenGL dzieli wielokaty

na trójkaty, co moze byc zródłem niepozadanych efektów. Specyfikacja wskazuje ograniczona grupe funkcji

biblioteki OpenGL, które moga byc wywoływane pomiedzy glBegin a glEnd. Naleza do nich następujące funkcje
(lub   grupy   funkcji):   glVertex,   glColor,   glSecondaryColor,   glIndex,   glNormal,   glTexCoord,   glMultiTexCoord,
glVertexAttrib,   glFogCoord,   glArrayElement,   glEvalCoord,   glEvalPoint,   glMaterial,   glEdgeFlag,   glCallList   i
glCallLists.   Wywołanie   funkcji   spoza   powyższej   grupy   spowoduje   zgłoszenie   błedu.   Nie   ma   natomiast
ograniczen co do wywoływania funkcji pochodzacych z innych bibliotek wykorzystywanych w programie.

6.2. Definiowanie współrzędnych wierzchołków figur

Współrzedne  wierzchołków  figur  podstawowych  standardowo  definiuje  sie   przy  pomocy  funkcji  z  grupy

glVertex. Co do zasady wierzchołki prymitywów graficznych opisywane sa w bibliotece OpenGL przy pomocy
czterech   współrzednych:   (x,   y,   z,w).   Poniewaz   nie   we   wszystkich   przypadkach   konieczne   jest   stosowanie
wszystkich współrzednych, OpenGL zawiera funkcje definiujace tylko trzy pierwsze współrzedne (wtedy wartosc
współrzędnej   w  wynosi   domyslnie   1)   oraz  funkcje   definiujace   dwie   pierwsze   współrzędne   (wtedy   wartosc
współrzednej z wynosi domyslnie 0, a wartosc współrzędnej w wynosi 1).

Grupa glVertex obejmuje 24 funkcje, które mozna podzielic na 3 równoliczne podgrupy, kazda wymagajaca

innej ilosci współrzednych.  Parametrami funkcji z  kazdej  podgrup sa albo kolejne  współrzedne  wierzchołków,
albo wskazniki na tablice zawierajace te współrzedne. Jak zapewne Czytelnik zauwazył, wiekszosc prymitywów
wymaga   scisle   okreslonej   ilosci   wierzchołków.   OpenGL  w  trakcie   procesu   rysowania   prymitywu   pomija   te
ostatnie wierzchołki, których ilosc nie pozwala na zbudowanie prymitywu.

6.2.1. Funkcje z grupy glVertex2

void

 glVertex2d (GLdouble x, GLdouble y)

void

 glVertex2f (GLfloat x, GLfloat y)

void

 glVertex2i (GLint x, GLint y)

void

 glVertex2s (GLshort x, GLshort y)

void

 glVertex2dv (

const

 GLdouble *v)

void

 glVertex2fv (

const

 GLfloat *v)

void

 glVertex2iv (

const

 GLint *v)

void

 glVertex2sv (

const

 GLshort *v)

6.2.2. Funkcje z grupy glVertex3

void

 glVertex3d (GLdouble x, GLdouble y, GLdouble z)

void

 glVertex3f (GLfloat x, GLfloat y, GLfloat z)

void

 glVertex3i (GLint x, GLint y, GLint z)

void

 glVertex3s (GLshort x, GLshort y, GLshort z)

void

 glVertex3dv (

const

 GLdouble *v)

void

 glVertex3fv (

const

 GLfloat *v)

void

 glVertex3iv (

const

 GLint *v)

void

 glVertex3sv (

const

 GLshort *v)

6.2.3. Funkcje z grupy glVertex4

[Kurs OpenGL, C++] VI. Elementarne obiekty geometryczne

http://kursy.ddt.pl/?LessonId=198

3 z 7

2010-04-30 14:23

background image

void

 glVertex4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w)

void

 glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w)

void

 glVertex4i (GLint x, GLint y, GLint z, GLint w)

void

 glVertex4s (GLshort x, GLshort y, GLshort z, GLshort w)

void

 glVertex4dv (

const

 GLdouble *v)

void

 glVertex4fv (

const

 GLfloat *v)

void

 glVertex4iv (

const

 GLint *v)

void

 glVertex4sv (

const

 GLshort *v)

6.3. Prostokąty

Wspecjalny sposób potraktowano w bibliotece OpenGL prostokaty. Opracowana została bowiem oddzielna

grupa funkcji glRect rysujacych prostokąt na podstawie współrzednych dwóch wierzchołków: lewego górnego i
prawego dolnego. Prostokat rysowany jest na płaszczyznie o równaniu Z = 0, a jego boki sa równoległe do osi
układu   współrzednych.   Stanowi   to   duze   oczywiście   ograniczenie,   ale   umozliwia   jednoczesnie   opracowanie
szczególnie szybkiej implementacji rysowania prostokatów.

Podobnie jak funkcje z grupy glVertex, funkcje glRect dostepne sa w wersjach wymagajacych dwóch par

współrzednych wierzchołków oraz pobierających wskaznik na tablice ze współrzednymi wierzchołków:

void

 glRectd (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)

void

 glRectf (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)

void

 glRecti (GLint x1, GLint y1, GLint x2, GLint y2)

void

 glRects (GLshort x1, GLshort y1, GLshort x2, GLshort y2)

void

 glRectdv (

const

 GLdouble *v1, 

const

 GLdouble *v2)

void

 glRectfv (

const

 GLfloat *v1, 

const

 GLfloat *v2 )

void

 glRectiv (

const

 GLint *v1, 

const

 GLint *v2)

void

 glRectsv (

const

 GLshort *v1, 

const

 GLshort *v2)

6.4. Punkty

Punkt w bibliotece OpenGL nie podlega efektom perspektywy i ma standardowo kształt kwadratu (piksela

lub jego wielokrotnosci). Wielkosc rysowanych punktów okresla funkcja:

void

 glPointSize (GLfloat size)

Parametr size okresla srednice punktu i jego wartosc musi byc wieksza od 0. Domyslnie wielkosc punktów

wynosi   1   i   jest   to   jedyna   wielkosc,   której   obsługe   wymaga   specyfikacja   OpenGL.   Dopuszczalny   zakres
wielkosci punktu oraz krok z jakim wielkosc ta moze byc zmieniana zalezy od implementacji biblioteki OpenGL.
Punkty o róznych rozmiarach przedstawia rysunek 5.

Rysunek 5.  P rogram  P unkty  - punkty o  róznych  rozmiarach

6.5. Linie

Podobnie   jak   w   przypadku   punktów   biblioteka   OpenGL   umozliwia   zmiane   grubosci   (szerokosci)

rysowanych linii. Słuzy do tego funkcja:

void

 glLineWidth (GLfloat width)

Parametr okresla grubosc linii i musi byc wiekszy od 0. Domyslnie grubosc linii wynosi 1. Dopuszczalny

zakres   grubosci  linii   oraz  krok   z  jakim  wielkość   ta   moze   byc   zmieniana   zalezy   od   implementacji   biblioteki
OpenGL.

[Kurs OpenGL, C++] VI. Elementarne obiekty geometryczne

http://kursy.ddt.pl/?LessonId=198

4 z 7

2010-04-30 14:23

background image

Rysunek 6.  P rogram  Linie  -  linie  o  róznych grubos ciach  i wzorach

Poza gruboscia biblioteka OpenGL pozwala na okreslenie wzoru jakim bedzie rysowana linia (patrz rysunek

6). Umozliwia to funkcja:

void

 glLineStipple (GLint factor, GLushort pattern)

której  parametr  pattern  to  16-bitowa  liczba  całkowita  zawierajaca  wzór  rysowanej  linii,  a  factor  okresla

zwielokrotnienie   bitów   wzoru.   Wartosc   parametru   factor   jest   ograniczona   i   w  razie   potrzeby   obcinana   do
przedziału [1, 256], a wartosc poczatkowa wynosi 1. Poczatkowy wzór linii okresla stała FFFFh, która oznacza
linie   ciagła.   Standardowo   rysowanie   linii   ze   wzorami   jest   wyłaczone.   Właczenie   tego   mechanizmu   wymaga
wywołania funkcji glEnable z parametrem GL LINE - STIPPLE.

6.6. Programy przykładowe

Pierwszy   przykładowy   program   (plik   prymitywy   graficzne.cpp)   pozwala   na   przetestowanie   wszystkich

prymitywów  graficznych  dostępnych  w  bibliotece   OpenGL.   Szczególnie   wazna   jest  mozliwosc   bezposredniej
oceny   sposobu   konstruowania   takich  prymitywów  jak   wstegi   trójkatów  i   czworokatów.   Program  umozliwia
zmiane  rodzaju  prymitywu  bez  usuwania  współrzędnych  wierzchołków  poprzedniego  prymitywu.   Moze  dac  to
czasami bardzo zaskakujace efekty. Do przechowywania współrzednych wierzchołków prymitywów zastosowano
klase vector z biblioteki standardowej C++.

Nowym   elementem   biblioteki   GLUT,   który   pojawił   sie   w   pierwszym   przykładowym   programie   jest

wyswietlanie ciagów znaków w postaci numerów wierzchołków prymitywów. Realizuje to funkcja:

void

 glutBitmapCharacter (

void

 *font, 

int

 character)

której   parametr  font   okresla   rodzaj  wyswietlanej  czcionki  bitmapowej,  a   character  znak   jaki   ma   zostac

wyswietlony. Czcionki bitmapowe sa na stałe zapisane w bibliotece GLUT jako mapy bitowe. GLUT nie zawiera
funkcji umozliwiajacych skorzystanie z czcionek bitmapowych zawartych w zewnetrznych plikach.

Biblioteka GLUT w wersji 3.x zawiera nastepujace czcionki bitmapowe:

GLUT   BITMAP   8   BY   13   -   typowa   czcionka   o   wymiarach  znaków  8   ×   13   pikseli;  znaki   ASCII  z
przedziału   [0,  255];  odpowiednik   standardowej   czcionki   X  Window  o   nazwie:  

-misc-fixed-medium-

r-normal–13-120-75-75-C-80-iso8859-1

,

GLUT   BITMAP   9   BY   15   -   typowa   czcionka   o   wymiarach  znaków  9   ×   15   pikseli;  znaki   ASCII  z
przedziału   [0,  255];  odpowiednik   standardowej   czcionki   X  Window  o   nazwie:  

-misc-fixed-medium-

r-normal–15-140-75-75-C-90-iso8859-1

GLUT   BITMAP   TIMES   ROMAN   10   -   10-punktowa   czcionka   proporcjonalna   Times   Roman;  znaki
ASCII z przedziałów: [32, 126] i [160, 255]; odpowiednik czcionki X Window o nazwie: 

-adobe-times-

medium-r-normal–10-100-75-75-p-54-iso8859-1

,

GLUT   BITMAP   TIMES   ROMAN   24   -   24-punktowa   czcionka   proporcjonalna   Times   Roman;  znaki
ASCII z przedziałów: [32, 126] i [160, 255]; odpowiednik czcionki X Window o nazwie: 

-adobe-times-

medium-r-normal–24-240-75-75-p-124-iso8859-1

,

GLUT   BITMAP   HELVETICA   10   -   10-punktowa   czcionka   proporcjonalna   Helvetica;  znaki   ASCII  z
przedziałów:   [32,   126]   i   [160,   255];  odpowiednik   czcionki   X  Window  o   nazwie:  

-adobe-helvetica-

medium-r-normal–10-100-75-75-p-56-iso8859-1

,

GLUT   BITMAP   HELVETICA   12   -   12-punktowa   czcionka   proporcjonalna   Helvetica;  znaki   ASCII  z
przedziałów:   [32,   126]   i   [160,   255];  odpowiednik   czcionki   X  Window  o   nazwie:  

-adobe-helvetica-

medium-r-normal–12-120-75-75-p-67-iso8859-1

,

GLUT   BITMAP   HELVETICA   18   -   18-punktowa   czcionka   proporcjonalna   Helvetica;  znaki   ASCII  z
przedziałów:   [32,   126]   i   [160,   255];  odpowiednik   czcionki   X  Window  o   nazwie:  

-adobe-helvetica-

medium-r-normal–18-180-75-75-p-98-iso8859-1

.

Jak  Czytelnik  juz zapewne  zauwazył  wszystkie  czcionki  zawieraja  znaki  ASCII kodowane  w standardzie

ISO 8859-1, czyli bez  polskich liter. Niestety nie istnieje prosta metoda wyswietlenia czcionek  zawierajacych
polskie litery. W tym miejscu jedynie sygnalizujemy uzycie w programie nowej funkcji:

void

 glRasterPos2i (GLint x, GLint y)

Funkcja ta, nalezaca do licznej grupy funkcji glRasterPos, okresla położenie wyswietlanej grafiki rastrowej -

w tym przypadku liczby określającej numer wierzchołka prymitywu. Dokładny opis operacji na rastrach znajdzie

[Kurs OpenGL, C++] VI. Elementarne obiekty geometryczne

http://kursy.ddt.pl/?LessonId=198

5 z 7

2010-04-30 14:23

background image

sie w jednym z nastepnych odcinków kursu.

Drugi  przykładowy  program  (plik  punkty.cpp)  prezentuje  podstawowe  mozliwosci  rysowania  punktów  w

bibliotece   OpenGL.   Rozmiar   punktów   reguluja   przyciski   „+”   (zwiekszenie)   i   „-”   (zmniejszenie).   Rozmiar
punktów oraz ich współrzedne przechowywane sa w obiektach klasy vector z biblioteki standardowej C++.

Trzeci   przykładowy   program   (plik   linie.cpp)   prezentuje   podstawowe   mozliwosci   rysowania   linii   w

bibliotece OpenGL. Szerokosc rysowanej linii reguluja przyciski „+” (zwiekszenie) i „-” (zmniejszenie). Menu
podręczne   udostepnia   kilka   wzorów   linii.   Szerokosc   i   wzór   linii   oraz   współrzedne   ich   poczatku   i   konca
przechowywane sa w obiektach klasy vector z biblioteki standardowej C++.

6.6.1. Plik prymitywy graficzne.cpp

/*
(c) Janusz Ganczarski
http://www.januszg.hg.pl
JanuszG(małpeczka)enter.net.pl
*/

#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
#include <vector>

// stałe do obsługi menu podręcznego

enum

{
  RECTANGLES = GL_POLYGON + 100,  

// prostokąty

  CLEAR_VERTEX,                   

// usuwanie wierzchołków

  EXIT                            

// wyjście

};

// rodzaj rysowanego prymitywu graficznego

int

 primitive = GL_POINTS;

// współrzędne wierzchołków prymitywu

6.6.2. Plik punkty.cpp

/*
(c) Janusz Ganczarski
http://www.januszg.hg.pl
JanuszG(małpeczka)enter.net.pl
*/

#include <GL/glut.h>
#include <stdlib.h>
#include <vector>

// stałe do obsługi menu podręcznego

enum

{
  CLEAR_POINTS,  

// usuwanie punktów

  EXIT           

// wyjście

};

// współrzędne punktów

std::vector <GLint> vertex_x;
std::vector <GLint> vertex_y;

// rozmiary punktów

6.6.3. Plik linie.cpp

[Kurs OpenGL, C++] VI. Elementarne obiekty geometryczne

http://kursy.ddt.pl/?LessonId=198

6 z 7

2010-04-30 14:23

background image

/*
(c) Janusz Ganczarski
http://www.januszg.hg.pl
JanuszG(małpeczka)enter.net.pl
*/

#include <GL/glut.h>
#include <stdlib.h>
#include <vector>

// stałe do obsługi menu podręcznego

enum

{
  STIPPLE_1111111111111111,  

// wzór linii 1111111111111111

  STIPPLE_0000000011111111,  

// wzór linii 0000000011111111

  STIPPLE_1111111100000000,  

// wzór linii 1111111100000000

  STIPPLE_0000111100001111,  

// wzór linii 0000111100001111

  STIPPLE_1111000011110000,  

// wzór linii 1111000011110000

  STIPPLE_0011001100110011,  

// wzór linii 0011001100110011

  STIPPLE_1100110011001100,  

// wzór linii 1100110011001100

  CLEAR_LINES,               

// usuwanie linii

  EXIT                       

// wyjście

};

6.7. Źródło materiału

Materiał został pobrany ze strony 

http://januszg.hg.pl/opengl/

, za uprzednim otrzymaniem zgody od jego

autora. Podziekowania dla 

Janusza Ganczarskiego

 za udostępnienie materiałów 

Poprzednia lekcja

Kurs OpenGL, C++

Następna lekcja

Wsz e lkie  prawa z ast rz e ż one . Aut or:  ź ródło z e wnę t rz ne

Wszystkie   teksty   są   chronione   prawami   autorskimi.   Kopiowanie   lub
rozpowszechnianie treści bez wyraźnej zgody jego autora jest zabronione.

Powrót

Historia odwiedzonych stron

O portalu

Archiwum

Historia

Indeks

Regulamin

Wyszukiwarka

Linki

© Wszelkie prawa zastrzeżone   2005-2010

Czas wygenerowania strony: 0.069s

Autor: Piotr Szawdyński

[Kurs OpenGL, C++] VI. Elementarne obiekty geometryczne

http://kursy.ddt.pl/?LessonId=198

7 z 7

2010-04-30 14:23