background image

 Strona główna

 Kursy

 Artykuły

 Forum

 Pliki

 Promuj Nas!

 

[Kurs OpenGL, C++] VIII. Kolory i cieniowanie

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

1 z 4

2010-04-30 14:24

background image

Powrót

Historia odwiedzonych stron

Poprzednia lekcja

Kurs OpenGL, C++

 

Autor: Janusz Ganczarski

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

VIII. Kolory i cieniowanie

Standardowo   biblioteka   OpenGL   korzysta   z   modelu   barw   RGB,   który   wykorzystuje   trzy   barwy

podstawowe: czerwoną (R), zieloną (G) i niebieską (B). Jak wspomnieliśmy na początku kursu barwa może być
określona bezpośrednio poprzez wartości składowych bądź w trybie indeksowym z użyciem mapy (tablicy) barw.
Tryb indeksowy zostanie opisany, ale przykładowe programy nie będą go stosowały. Przedtem jednak poznamy
budowę bufora koloru - najważniejszego elementu bufora ramki obrazu.

8.1. Bufor koloru

Bufor koloru służy do przechowywania obrazu renderowanej sceny 3D.
Jest on podzielony na kilka buforów. Typowo OpenGL stosuje dwa bufory koloru: przedni i tylny. Bieżąca

scena znajduje się w przednim buforze i jest wyświetlana na ekranie monitora, a jednocześnie w tylnym buforze
rysowana jest kolejna ramka sceny. Po zakończeniu rysowania, bufory są zamieniane i cały proces zaczyna się
od   początku.   Podwójne   buforowanie   eliminuje   migotanie   obrazu   występujące   przy   stosowaniu   pojedynczego
bufora koloru.

Niektóre  implementacje  biblioteki  OpenGL  udostępniają  stereoskopowy  tryb  działania   bufora  koloru,  tj.

generowanie dwóch niezależnych obrazów dla  prawego i lewego oka. Oba kanały stereoskopowe mają własne
niezależne   bufory   przednie   i  tylne.   Ponadto  implementacja  OpenGL  może  posiadać   dodatkowe  (pomocnicze)
bufory koloru.

Wybór  trybu   działania   bufora  kolorów  dokonywany  jest  na  początku   działania   programu.   W  przypadku

biblioteki GLUT realizuje to opisywana już funkcja glutInitDisplayMode, której parametrem jest maska bitowa.

Stała GLUT_SINGLE wybiera domyślny w bibliotece GLUT tryb pojedynczego bufora koloru. Podwójne

buforowanie wymaga stałej GLUT_DOUBLE. Z kolei tryb stereoskopowy uruchamia stała GLUT_STEREO.

Inna   grupa   stałych  odpowiada,  za   wybór  sposobu   zapisu   kolorów  w  buforach  koloru:   GLUT_RGB  lub

GLUT_RGBA - bezpośredni tryb RGB wyświetlania kolorów (bez kanału alfa), GLUT_INDEX - tryb indeksowy
z mapą kolorów, GLUT_ALPHA - obsługa kanału alfa, GLUT_LUMINANCE - alternatywny tryb wyświetlania
obrazu  w  odcieniach  szarości,  w  którym  składowe  R  pikseli  stanowią  indeksy  do  mapy  kolorów  początkowo
zawierającej liniowo uporządkowane odcienie szarości.

8.2. Kolor - tryb bezpośredni

W trybie bezpośrednim kolor ustalany jest przy użyciu funkcji z grupy glColor. Funkcje te można podzielić

na  trzy  grupy.  Pierwsza  to funkcje  trójargumentowe,  przyjmujące  składowe  RGB  w  różnych  formatach;  druga
grupa to funkcje czteroargumentowe umożliwiające określenie także wartości składowej alfa (RGBA); trzecia to
funkcje przyjmujące wskaźnik na tablicę ze składowymi RGB lub RGBA. W przypadku, gdy kolor określają trzy
składowe wartość składowej alfa wynosi 1.0. Początkową wartość bieżącego koloru określają składowe RGBA:
(1, 1, 1, 1).

Funkcje   przyjmujące   argumenty   zmiennoprzecinkowe   wymagają   wartości   z   przedziału   [0,   1],   gdzie   0

określa minimalną wartość składowej koloru, a 1 maksymalną wartość składowej. Wartości przekraczające ten
przedział   są   odpowiednio   przycinane.   Funkcje   przyjmujące   argumenty   całkowitoliczbowe   przekształcają   te
wartości do liczb zmiennoprzecinkowych z przedziału [0, 1] wg schematu przedstawionego w tabeli 1, gdzie c
oznacza składową koloru.

typ  OpenGL

konwersja

GLubyte

c/(2

8

-1)

GLbyte

(2*c+1)/(2

8

-1)

GLushort

c/(2

16

-1)

GLshort

(2*c+1)/(2

16

-1)

GLuint

c/(2

32

-1)

GLint

(2*c+1)/(2

32

-1)

Tabela 1:  K onwers ja  składowych  koloru  w OpenGL

8.2.1. Funkcje z grupy glColor3

void

 glColor3b (GLbyte red, GLbyte green, GLbyte blue)

void

 glColor3d (GLdouble red, GLdouble green, GLdouble blue)

void

 glColor3f (GLfloat red, GLfloat green, GLfloat blue)

void

 glColor3i (GLint red, GLint green, GLint blue)

void

 glColor3s (GLshort red, GLshort green, GLshort blue)

void

 glColor3ub (GLubyte red, GLubyte green, GLubyte blue)

void

 glColor3ui (GLuint red, GLuint green, GLuint blue)

void

 glColor3us (GLushort red, GLushort green, GLushort blue)

void

 glColor3bv(

const

 GLbyte *v)

void

 glColor3dv(

const

 GLdouble *v)

void

 glColor3fv(

const

 GLfloat *v)

void

 glColor3iv(

const

 GLint *v)

void

 glColor3sv(

const

 GLshort *v)

void

 glColor3ubv(

const

 GLubyte *v)

void

 glColor3uiv(

const

 GLuint *v)

P anel  Logowania

dast19

Administracja

Twój profil

Wyloguj

Uż yt kowników

Obecnie aktywnych:

13

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

0 min

Piotr Szawdyński

6 min

Iname

 

(√ιק)

19 min

szywro5

31 min

Saiph

35 min

markon

59 min

imandre

76 min

WunM

95 min

kuba1817

2 godz

killersft

2 godz

fish13

2 godz

kizia

2 godz

Take Your Time

We take care of your IT
functions: Software
Development, Outsourcing

www.impaqgroup.com

Kurs programowania w
C++

Wygodna Metoda nauczania.
Poznaj Tajniki języka C++

www.SzkolaLinuxa.pl

[Kurs OpenGL, C++] VIII. Kolory i cieniowanie

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

2 z 4

2010-04-30 14:24

background image

void

 glColor3usv(

const

 GLushort *v)

8.2.2. Funkcje z grupy glColor4

void

 glColor4b (GLbyte red, GLbyte green, GLbyte blue,

GLbyte alpha)

void

 glColor4d (GLdouble red, GLdouble green, GLdouble blue, GLdouble

alpha)

void

 glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)

void

 glColor4i (GLint red, GLint green, GLint blue, GLint alpha)

void

 glColor4s (GLshort red, GLshort green, GLshort blue, GLshort alpha)

void

 glColor4ub (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)

void

 glColor4ui (GLuint red, GLuint green, GLuint blue, GLuint alpha)

void

 glColor4us (GLushort red, GLushort green, GLushort blue, GLushort

alpha)

void

 glColor4bv(

const

 GLbyte *v)

void

 glColor4dv(

const

 GLdouble *v)

void

 glColor4fv(

const

 GLfloat *v)

void

 glColor4iv(

const

 GLint *v)

void

 glColor4sv(

const

 GLshort *v)

void

 glColor4ubv(

const

 GLubyte *v)

void

 glColor4uiv(

const

 GLuint *v)

void

 glColor4usv(

const

 GLushort *v)

8.3. Kolor - tryb indeksowy

W trybie indeksowym kolor określany jest pojedynczą liczbą - indeksem do mapy (tablicy) kolorów, która

zawiera informacje o składowych RGB.

Typowo   wielkość   mapy   kolorów  wynosi   od   256   (28)  do   4.096   (212).   Zarządzanie   mapą   kolorów  jest

uzależnione od konkretnego systemu okienkowego, w którym pracuje program. Biblioteka OpenGL nie posiada
żadnych mechanizmów pozwalających na zmianę zawartości mapy kolorów oraz zmiany jej rozmiarów.

Wybór indeksu bieżącego koloru realizują funkcje z grupy glIndex:

void

 glIndexd (GLdouble c)

void

 glIndexf (GLfloat c)

void

 glIndexi (GLint c)

void

 glIndexs (GLshort c)

void

 glIndexdv (

const

 GLdouble *c)

void

 glIndexfv (

const

 GLfloat *c)

void

 glIndexiv (

const

 GLint *c)

void

 glIndexsv (

const

 GLshort *c)

Początkowa wartość indeksu bieżącego koloru wynosi 1.
Czyszczenie bufora koloru w trybie indeksowym wykonuje funkcja:

void

 glClearIndex (GLfloat c)

gdzie parametr c określa indeks mapy kolorów. Domyślna wartość indeksu wynosi 0. Jest to odpowiednik

funkcji glClearColor działającej w trybie bezpośrednim.

8.4. Cieniowanie

Cieniowaniem  nazywamy  metodę  ustalania  koloru  poszczególnych pikseli  wielokąta.  Biblioteka  OpenGL

udostępnia standardowo dwa modele cieniowania: cieniowanie płaskie oraz cieniowanie gładkie. W cieniowaniu
płaskim  wielokąt   otrzymuje   jeden  kolor   -   określony   dla   ostatniego   wierzchołka   (wyjątek   stanowi   prymityw
GL_POLYGON, o kolorze którego decyduje kolor określony dla pierwszego wierzchołka). Cieniowanie gładkie
wykorzystuje  algorytm  Gourauda,  który   w  uproszczeniu   polega   na   liniowej  interpolacji  wartości   składowych
koloru określonych dla każdego wierzchołka wielokąta.

Cieniowane gładkie daje zadowalające efekty przy stosunkowo niewielkich wymaganiach obliczeniowych.
Wybór rodzaju cieniowania umożliwia funkcja:

void

 glShadeModel (GLenum mode)

której parametr mode przyjmuje jedną z wartości:

GL_FLAT - cieniowanie płaskie,
GL_SMOOTH - cieniowanie gładkie.

Domyślnie stosowane jest cieniowanie gładkie.

8.5. Dithering

Wewnętrznie   biblioteka   OpenGL   opisuje   kolory   za   pomocą   liczb   zmiennoprzecinkowych.   Natomiast

końcowy efekt widoczny na ekranie monitora zależy od możliwości systemu okienkowego oraz karty gra?cznej.
W sytuacji, gdy w systemie dostępna jest niewielka ilość barw (np. 256), biblioteka OpenGL może symulować
kolory   metodą   ditheringu.   W  uproszczeniu   algorytm  ten  umieszcza   w  pobliżu   siebie   różnokolorowe   plamki
(piksele) tak aby sprawiały wrażenie jednolitej barwy. Technika ta bywa określana także mianem rozpraszania,
rozsiewania lub roztrząsania.

Włączenie i wyłączenie ditheringu wymaga odpowiedniego użycia funkcji glEnable/glDisable z parametrem

GL_DITHER. Domyślnie dithering jest wyłączony.

8.6. Program przykładowy

[Kurs OpenGL, C++] VIII. Kolory i cieniowanie

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

3 z 4

2010-04-30 14:24

background image

Przykładowy   program   (plik   trojkat.cpp)   to   nieco   uproszczona   wersja   klasycznego   programu

wykorzystującego   bibliotekę   OpenGL.   Początkowo   barwa   każdego   z  wierzchołków  odpowiada   maksymalnej
wartości każdej z trzech składowych modelu RGB (patrz rysunek 1).

brak opisu

Rysunek 1. Program Trójkąt - widok początkowy

Program  umożliwia  zmianę  kolorów  wierzchołków trójkąta.   Służą  do  tego  przyciski  r,  g,  b  (zmniejszanie

wartości  składowych  RGB) oraz  R,  G,  B (zwiększanie wartości  składowych  RGB).   Ponadto  z  poziomu  menu
podręcznego   użytkownik   może   wybrać   rodzaj   cieniowania   oraz  włączyć   i   wyłączyć   dithering.   Na   dole   okna
program wyświetla m.in.  ilość  bitów  przypadającą  na  każdą składową  RGBA.  Wykorzystano do  tego funkcję
glGetIntegerv   z  pierwszym  parametrem  o   wartości:   GL_RED_BITS,   GL_GREEN_BITS,   GL_BLUE   -BITS   i
GL_ALPHA_BITS.

Po uruchomieniu programu w trybie 256 kolorowym Czytelnik ma możliwość sprawdzenia zarówno efektów

działania algorytmu ditheringu (rysunek 2) jak też i działania cieniowania gładkiego przy ograniczonej ilości barw
(rysunek 3). Oba rysunki powstały w systemie Windows XP w trybie zgodności 256 kolorów. Ocenę jakości tak
generowanej gra?ki pozostawiamy Czytelnikowi.

brak opisu

Rysunek 2. Program Trójkąt w trybie 256 kolorowym z ditheringiem

brak opisu

Rysunek 3. Program Trójkąt w trybie 256 kolorowym bez ditheringu koniec

8.6.1. Plik trojkat.cpp

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

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

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

enum

{
  FLAT_SHADING,   

// cieniowanie płaskie

  SMOOTH_SHADING, 

// cieniowanie gładkie (Gourauda)

  DITHERING,      

// dithering

  EXIT            

// wyjście

};

// model cieniowania

GLenum shading_model = GL_SMOOTH;

8.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++

 

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.058s

Autor: Piotr Szawdyński

[Kurs OpenGL, C++] VIII. Kolory i cieniowanie

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

4 z 4

2010-04-30 14:24