Задание полигональных моделей объектов Трехмерная визуализация с использование OPEN Gl

Страницы работы

8 страниц (Word-файл)

Фрагмент текста работы

Министерство образования Российской Федерации

НОВОСИБИРСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ

Лабораторная работа №2

по  курсу «Компьютерная графика »

 «Задание полигональных моделей объектов Трехмерная визуализация с использование OPEN GL».

Факультет:       ПМИ

Группа:               ПМ-11

Студенты:            Голубева М.

Николаева А.

Вариант:              5

Преподаватель: 

Новосибирск

 2004

Цель работы: ознакомиться с основным способом задания полигональных моделей – методом тиражирования сечений; ознакомиться со средствами трехмерной визуализации в OpenGL (источники света, свойства материалов, текстуры).

Задания.

Путь

Сечение

Способ тиражирования сечения

5

прямой

выпуклый многоугольник

с масштабированием

Входные данные задаются с помощью текстового файла с имение param.txt, в котором содержится данные о сечении ( т.е количество точек в сечении, координаты этих точек, количество сечений в изображаемой фигуре, положение сечения вдоль пути, которое задается длиной пути от начальной вершины в процентах).

Все данные вводятся с учетом следующих направление осей координат:                                                   

                                                     y

z

 


x

Чтобы  изменение размера фигуры было нагляднее в программе предусмотрен ее поворот для каждой из осей.

Нормали в вершинах объекта задаются двумя способами.

В первом случае, узлы одной плоскости имеют разное направление нормалей. Направление в этом случае совпадает с вектором, выходящем из центра плоскости  и проходящем через соответствующую вершину плоскости.

Во втором, нормаль имеет одинаковое направление во всех узлах одной плоскости и направлена, перпендикулярна этой плоскости.  Нахождение это направление в программе реализовано с помощью процедуры ортогонализации Грамма-Шмидта.  За начальную систему  выбирается система из трех векторов: два из них принадлежат плоскости, к которой ищется перпендикуляр, а в качестве третьего вектора принимается единичный вектор из плоскости xy.

Также, используется наложение текстуры. Размер изображенной фигуры  увеличивается после нажатия стрелки вверх и уменьшается при нажатии стрелки вниз. 

Текст программы:

/*лаба №2_1 (прямой,выпуклый прямоугольник, с масштабированием)

нормаль задается в каждой точке*/

#include <windows.h>

#include <GL/gl.h>

#include <GL/glu.h>

#include <GL/glaux.h>

#include <math.h>

#include<stdio.h>

#include<conio.h>

# include<math.h>

#define max_t 10  //максимальное количество узлов в сечении

#define max_s 100   //максимальное кол-во сечений

#define len_x     4   //длина пути по х

#define len_y     4   //длина пути по у

#define len_z     8   //длина пути по z

float razm=1;           //маштабирование

float delta=3;    //величина увеличения поворота по осям

float f=0,g=0,p=0;  //переменные для поворота по осям

float p1=0;             //переменные для масштабирования

int XY[max_t][2];   //массив хранения координат точек сечения

int z[max_s],mashy[max_s],mashx[max_s];

float xprev[max_t],yprev[max_t],zprev[max_t];//предыдущее сечение

float xtek[max_t],ytek[max_t],ztek[max_t];//текущее сечение

int n;//количество узлов в вершине

int k;//  количество сечений

GLuint TexId;//

//уменьшение размера фигуры

void CALLBACK OnKeyDown()

{razm = razm-0.1;

}

//увеличение размера фигуры

void CALLBACK OnKeyUp()

{razm = razm +0.1;

}

//поворот по z

void CALLBACK OnKey9()

{f = f + delta;

}

void CALLBACK OnKey0()

{f = f - delta;

}

//поворот по y

void CALLBACK OnKeyLeft()

{g = g + delta;

}

void CALLBACK OnKeyRight()

{g = g - delta;

}

//поворот по x

void CALLBACK OnKey8()

{p = p-delta;

}

void CALLBACK OnKey7()

{p= p +delta;

}

//величина масштабирования

void CALLBACK OnKey6()

{     p1 = p1-0.2;

}

void CALLBACK OnKey5()

{     p1= p1 +0.2;

}

//чтение исходных данных

void readdata(void)

{     int i;

FILE* param=fopen("param.txt","r");

fscanf(param,"%d ",&n);

for(i=0; i<n; i++)

{           fscanf(param,"%d %d",&XY[i][0],&XY[i][1]);

}

fscanf(param,"%d ",&k);

for(i=0; i<k; i++)

{           fscanf(param,"%d %d %d",&z[i],&mashx[i],&mashy[i]);

}

fclose(param);   

}

//подпрограмма работы с текстурой

void TextureInit(void)

{

char strFile[]="texture11.bmp";

AUX_RGBImageRec *pImage;

glPixelStorei(GL_UNPACK_ALIGNMENT,1);

glGenTextures(1,&TexId);             

pImage = auxDIBImageLoad(strFile);   

glBindTexture(GL_TEXTURE_2D, TexId); 

gluBuild2DMipmaps(GL_TEXTURE_2D,3,pImage->sizeX,

pImage->sizeY,GL_RGB,GL_UNSIGNED_BYTE,

pImage->data);

);

}

//подпрограмм рисования фигуры

void drawer(void)

{     float delta_z; //длина по z

float xn,yn,zn;

int i,j;

//изображение самого левого сечения фигуры    

glColor3d(0.8,0.8,0.8);

glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

glBegin(GL_POLYGON);

for (j=0; j<n; j++)

{     xprev[j] = 0.01*mashx[0]*razm*XY[j][0];

yprev[j] = 0.01*mashy[0]*razm*XY[j][1];

zprev[j] = (len_z/100.)*razm*z[0];

glVertex3d(xprev[j],yprev[j],zprev[j]);

}

glEnd();

//всех остальных       

for (i=1;i<k; i++)     

{     delta_z=(len_z/100.)*z[i];

//координаты точек нового сечения             

xtek[0] = 0.01*mashx[i]*razm*XY[0][0];

ytek[0] = 0.01*mashy[i]*razm*XY[0][1];

ztek[0] = delta_z*razm;

xn = xprev[0];//запоминаем первую точку предыдущего сечения

yn = yprev[0];

zn = zprev[0];

/*glColor3d устанавливает текущий цвет, которым будут рисоваться фигуры*/                              glColor3d(1,1,1);

/*функция glPolygonMode. Она устанавливает опции для отрисовки многоугольника.

Первый параметр может принимать значения - GL_FRONT, GL_BACK и GL_FRONT_AND_BACK.

Первый параметр указывает: к лицевой, тыльной или же к обеим сторонам применяется опция, заданная вторым параметром.

Второй параметр указывает, как будет рисоваться многоугольник.

Он принимает значения:GL_FILL(рисуем заполненный многоугольник). */

glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

glBegin(GL_QUADS);

/*Четырехугольники рисуются вызовом функции glBegin с параметром GL_QUADS .

: каждые четыре вершины определяют свой четырехугольник.  */

for (j=0; j<n-1; j++)

{    

//закрашиваем верхнюю,переднюю и нижнию поверхность фигуры      

glNormal3d(xtek[j],ytek[j],0);

glTexCoord2d(1,1);

glVertex3d(xtek[j],ytek[j],ztek[j]);

glNormal3d(xprev[j],yprev[j],0);

glTexCoord2d(1,0);

glVertex3d(xprev[j],yprev[j],zprev[j]);

glNormal3d(xprev[j+1],yprev[j+1],0);

glTexCoord2d(0,0);                            

glVertex3d(xprev[j+1],yprev[j+1],zprev[j+1]);

xprev[j] = xtek[j];

yprev[j] = ytek[j];

zprev[j] = ztek[j];

xtek[j+1] = 0.01*mashx[i]*razm*XY[j+1][0];

ytek[j+1] = 0.01*mashy[i]*razm*XY[j+1][1];

ztek[j+1] = delta_z*razm;

glNormal3d(xtek[j+1],ytek[j+1],0);

glTexCoord2d(0,1);

glVertex3d(xtek[j+1],ytek[j+1],ztek[j+1]);                                   }

//дальная сторона

glNormal3d(xtek[j],ytek[j],0);

glTexCoord2d(1,1);

glVertex3d(xtek[j],ytek[j],ztek[j]);

glNormal3d(xprev[j],yprev[j],0);

glTexCoord2d(1,0);

glVertex3d(xprev[j],yprev[j],zprev[j]);

glNormal3d(xn,yn,0);

glTexCoord2d(0,0);

glVertex3d(xn,yn,zn);

glNormal3d(xprev[0],yprev[0],0);

glTexCoord2d(0,1);                            

glVertex3d(xprev[0],yprev[0],zprev[0]);

xprev[j] = xtek[j];

yprev[j] = ytek[j];

zprev[j] = ztek[j];

glEnd();

}

//самого правого сечения     

glColor3d(0.8,0.8,0.8);

glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

glBegin(GL_POLYGON);

for (j=0; j<n; j++)

{     glVertex3d(xprev[j],yprev[j],zprev[j]);

}

glEnd();

}

void CALLBACK resize(int width,int height)

{     glViewport(0,0,width,height);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(-7,7, -7,7, -7,7);

gluLookAt(3,0,0, 0,0,0, 0,1,0);

glMatrixMode(GL_MODELVIEW);

}

void CALLBACK display(void)

{     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glPushMatrix();                    // сохраняем текущие координаты

glRotated(f,0,0,1);                //поворот по оси z

glRotated(g,0,1,0);                //поворот по оси y

glRotated(p,1,0,0);                //поворот по оси x

glScaled(1 +p1,1+p1,1+p1);    //масштабирование

glTranslated(0,0,-4);         // сдвигаемся по оси z на -4

drawer();                          //изображение фигуры

glPopMatrix();                     // возвращаемся к старой системе координат

auxSwapBuffers();

}

void main()

{     GLfloat ch[] = {0.5,0.5,0.5,1};

//    GLfloat pos[] = {0,100,0,1};   

GLfloat fon[] = {0.2,0.2,0.2,1}; //цвет освещения

//    GLfloat ch[] = {0,100,0,1};

GLfloat pos[] = {100,10,10,1};   

readdata();                

auxInitPosition(0,0,600,600);

auxInitDisplayMode(AUX_RGB | AUX_DEPTH | AUX_DOUBLE);

auxInitWindow( "OpenGL Application Template" );

auxIdleFunc(display);

auxReshapeFunc(resize);

/*Режим сглаживания можно устанавливать вызовом функции

glEnable(GL_POINT_SMOOTH)

*/

glEnable(GL_DEPTH_TEST);   

glEnable(GL_TEXTURE_2D);   

glEnable(GL_COLOR_MATERIAL);

glEnable(GL_LIGHTING);      

glEnable(GL_LIGHT0);       

glLightModelfv(GL_LIGHT_MODEL_AMBIENT,fon);

glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,ch);      

glLightfv(GL_LIGHT0,GL_POSITION,pos);      

TextureInit();                    

auxKeyFunc(AUX_UP, OnKeyUp);

auxKeyFunc(AUX_DOWN, OnKeyDown);

auxKeyFunc(AUX_SPACE, OnKeySpace);

auxKeyFunc(AUX_LEFT, OnKeyLeft);

auxKeyFunc(AUX_RIGHT, OnKeyRight);

auxKeyFunc(AUX_9, OnKey9);

auxKeyFunc(AUX_0, OnKey0);

auxKeyFunc(AUX_7, OnKey7);

auxKeyFunc(AUX_8, OnKey8);

auxKeyFunc(AUX_5, OnKey5);

auxKeyFunc(AUX_6, OnKey6);

auxMainLoop(display);

}

/*лаба №2_2 (прямой,выпуклый прямоугольник, с масштабированием

Информация о работе