Міністерство освіти і науки України
Національний університет «Львівська Політехніка»
Інститут комп’ютерних технологій автоматики та метрології
Кафедра БІТ
Звіт
до лабораторної роботи № 7
з дисципліни :
“ Програмування комп’ютерної графіки ”
Львів 2012
Мета: Дати уявлення про можливості накладення текстур на поверхні об'єктів засобами OPENGL.
КОРОТКІ ТЕОРЕТИЧНІ ДАНІ
Текстура – одновимірне, двомірне або тривимірне зображення, яке має безліч асоційованих з ним параметрів, що визначають яким чином проводитиметься накладення зображення на поверхню. Простіше кажучи, текстура – це зображення, що накладається на поверхню. З фізичної точки зору текстура - масив даних, наприклад колірних, світлових або колірних і альфа. Кожен елемент цього масиву називається текселем. Координати текстур – координати текселя, що призначається вершині.
Загальноприйняті імена для координат текстур – s, t, r, q.
Для використання текстур необхідно виконати наступну послідовність дій:*
1. Підготовка зображення для використання в текстурі
Завантаження зображення з файлу.
2. Створення текстури
Генерація унікального імені текстури*
Виконання операції первинного зв’язування*
Пов'язання зображення з текстурою*
Установка режимів фільтрації текстури
Установка параметрів взаємодії об'єкту, з текстурою, що накладається.
Установка режиму мозаїчного накладення текстури.
Автоматична генерація координат текстур, ефект віддзеркалення.
3. Використання текстури
Вибір текстури для використання (вторинне скріплення).
Узгодження геометричних і текстур координат
Створення ефекту віддзеркалення за допомогою текстур.
* - Зірочкою позначені обов'язкові пункти.
Підготовка зображення для використання в текстурі.
Перший етап виконується при ініціалізації OPENGL.
OPENGL має свій формат зберігання зображень. Підготовчий етап полягає в тому, що б перетворити зображення у формат OPENGL. У бібліотеці GLAUX є функція, яка прочитує зображення з DIB або BMP файлу і автоматично перетворює його до формату OPENGL.
AUX_RGBImageRec* auxDIBImageLoad(strFile);
Функція повертає покажчик на структуру типу AUX_RGBImageRec, яка зберігає саме зображення і його основні параметри – ширину і висоту.
struct AUX_RGBImageRec
{unsigned char *data; // зображення GLint sizeX; // ширина зображення GLint sizeY; // висота зображення};
Передаване значення – шлях до файлу із зображенням.
Приклад використання функції auxDIBImageLoad – завантаження зображення з файлу sky.bmp у об'єкт структури ImageSky.
AUX_RGBImageRec *ImageSky;ImageSky = auxDIBImageLoad(“sky.bmp”);
Хід роботи:
1. Підготуйте зображення до використання як текстура. Як зображення вибирається будь-яке зображення, що є на комп'ютері. За відсутності таких зображення створюється в графічному редакторові.
2. Створіть об'єкт текстури.
3. Набудуйте параметри об'єктів текстур, відповідно до варіанту.
Номер варіанту
Збільшуючий фільтр
Зменшуючий фільтр
Взаємодія з поверхнею
2
без згладжування
лінійна фільтрація
без змішування
4. Змалюєте об'єкт відповідно до варіанту
Номер варіанту
Вид об'єкту
2
5. Накладете текстури на створений геометричний об'єкт.
6. Реалізуйте зміну параметрів текстури при натисненні клавіш відповідно до варіанту.
Номер варіанту
Що вносяться зміна
2
Дозвіл файлового покриття текстурою. Зміни кількості повторення текстури. Обертання об'єкту навколо осі Z.
Текст програми:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Tao.OpenGl;
using Tao.FreeGlut;
using Tao.Platform.Windows;
using Tao.DevIl;
namespace lab77
{
public partial class Form1 : Form
{
private int rot = 0;
private bool textureIsLoad = false;
public string texture_name = "";
public int imageId = 0;
public uint mGlTextureObject = 0;
public Form1()
{
InitializeComponent();
AnT.InitializeContexts();
}
private void Form1_Load(object sender, EventArgs e)
{
Glut.glutInit();
Glut.glutInitDisplayMode(Glut.GLUT_RGB | Glut.GLUT_DOUBLE);
Il.ilInit();
Il.ilEnable(Il.IL_ORIGIN_SET);
Gl.glClearColor(255, 255, 255, 1);
Gl.glViewport(0, 0, AnT.Width, AnT.Height);
Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Glu.gluPerspective(30, AnT.Width / AnT.Height, 1, 100);
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
Gl.glEnable(Gl.GL_DEPTH_TEST);
Gl.glEnable(Gl.GL_LIGHTING);
Gl.glEnable(Gl.GL_LIGHT0);
RenderTimer.Start();
}
private void RenderTimer_Tick(object sender, EventArgs e)
{
Draw();
}
private void Draw()
{
if (textureIsLoad)
{
rot++;
if (rot > 360)
rot = 0;
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
Gl.glClearColor(255, 255, 255, 1);
Gl.glLoadIdentity();
Gl.glEnable(Gl.GL_TEXTURE_2D);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, mGlTextureObject);
Gl.glPushMatrix();
Gl.glTranslated(0, -1, -5);
Gl.glRotated(rot, 0, 1, 0);
Gl.glBegin(Gl.GL_QUADS);
Gl.glVertex3d(1, 1, 0);
Gl.glTexCoord2f(0, 0);
Gl.glVertex3d(1.5, 0, 0);
Gl.glTexCoord2f(1, 0);
Gl.glVertex3d(0.5, 0, 0);
Gl.glTexCoord2f(1, 1);
Gl.glVertex3d(0, 1, 0);
Gl.glTexCoord2f(0, 1);
Gl.glEnd();
Gl.glPopMatrix();
Gl.glDisable(Gl.GL_TEXTURE_2D);
AnT.Invalidate();
}
}
private void button1_Click(object sender, EventArgs e)
{
Il.ilGenImages(1, out imageId);
Il.ilBindImage(imageId);
string url = "1.png";
if (Il.ilLoadImage(url))
{
int width = Il.ilGetInteger(Il.IL_IMAGE_WIDTH);
int height = Il.ilGetInteger(Il.IL_IMAGE_HEIGHT);
int bitspp = Il.ilGetInteger(Il.IL_IMAGE_BITS_PER_PIXEL);
switch (bitspp)
{
case 24:
mGlTextureObject = MakeGlTexture(Gl.GL_RGB, Il.ilGetData(), width, height);
break;
case 32:
mGlTextureObject = MakeGlTexture(Gl.GL_RGBA, Il.ilGetData(), width, height);
break;
}
textureIsLoad = true;
Il.ilDeleteImages(1, ref imageId);
}
}
private static uint MakeGlTexture(int Format, IntPtr pixels, int w, int h)
{
uint texObject;
Gl.glGenTextures(1, out texObject);
Gl.glPixelStorei(Gl.GL_UNPACK_ALIGNMENT, 1);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, texObject);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_REPEAT);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_REPEAT);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);
Gl.glTexEnvf(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, Gl.GL_REPLACE);
switch (Format)
{
case Gl.GL_RGB:
Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGB, w, h, 0, Gl.GL_RGB, Gl.GL_UNSIGNED_BYTE, pixels);
break;
case Gl.GL_RGBA:
Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, w, h, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, pixels);
break;
}
return texObject;
}
}
}
Виконання програми:
Висновок: На даній лабораторній роботі я дав уявлення про можливості накладення текстур на поверхні об'єктів засобами OPENGL.