Cześć,
mam taki program który wyświetla trójkąt z teksturą. Trójkąt można obrócić za pomocą myszki. Jednak gdy na samym początku uruchomimy program, to trójkąt wygląda tak jak w załączniku. Dopiero po kliknięciu myszką i obracaniu go przyjmuje kształt trójkąta.. dlaczego tak jest?
/* System */
#include<windows.h>
#include<stdio.h>
#include<math.h>
/* Główna bibloteka OpenGL */
#include<GL/gl.h>
/* Biblioteka GLUT */
#include<GL/glut.h>
/* Deklaracje funkcji narzędziowych */
void MouseMotion(GLsizei x, GLsizei y);
void MouseFunc(int button, int state, int x, int y);
GLbyte *LoadTGAImage(const char *FileName, GLint *ImWidth, GLint *ImHeight, GLint *ImComponents, GLenum *ImFormat);
/* Funkcja do rysowania */
void DrawScene(void);
/* Prototyp fukcji rysujšcej osie ukłšdu */
void DrawSceneAxes(void);
/* Funkcja do inicjacji OpenGLa */
void InitOpenGL(void);
/* Funkcja wywoływana w momentach zmiany rozmiarów okna */
void ReshapeWindow(int width, int height);
/* Deklaracja globalnych zmiennych */
GLfloat theta = 0.0f;
GLfloat fi = 0.0f;
GLfloat r = 20.0f;
GLfloat zoom = 0.0f;
GLfloat rotx = 5.0f;
GLfloat roty = 5.0f;
GLfloat rotz = 5.0f;
GLint lbutton_status = 0;
GLint rbutton_status = 0;
GLfloat pixelsangle = 0.0;
GLint x_last_pos = 0;
GLint y_last_pos = 0;
GLint x_delta = 0;
GLint y_delta = 0;
// Pozycja obserwatora
GLfloat viewer_pos[] = { 0.0, 0.0, 20.0 };
/* Globalny identyfikator głównego okna programu */
int mainWindow;
/* Funkcja main */
int main(int argc, char **argv)
{
// Inicjujemy bibliotekę GLUT
glutInit(&argc, argv);
// Inicjujemy: format koloru, dwa bufoy ramki
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
// Ustawiamy poczštkowe wymiary okna
glutInitWindowSize(800, 600);
// Ustawiamy pozycję okna - lewy górny narożnik
glutInitWindowPosition(150,150);
// Tworzymy główne okno programu
mainWindow = glutCreateWindow("Lab4");
// Sprawdzamy powodzenie operacji
if(mainWindow == 0){
puts("Nie mozna stworzyc okna!!!\nWyjscie z programu.\n");
exit(-1);
}
// Czynimy aktywnym okno główne programu
glutSetWindow(mainWindow);
// Tutaj rejestrujemy funkcje narzędziowe - tzw. callbacks
glutDisplayFunc(DrawScene);
glutReshapeFunc(ReshapeWindow);
glutMouseFunc(MouseFunc);
glutMotionFunc(MouseMotion);
// Ustawienia poczštkowe
InitOpenGL();
// Włšczamy mechanizm usuwania niewidocznych powierzchni
glEnable(GL_DEPTH_TEST);
// Wej?cie do pętli programu
glutMainLoop();
return(0);
}
/* W tej funkcji okre?lamy to co ma byc narysowane na ekranie.
* Jest wywoływana zawsze wtedy, gdy trzeba przerysować ekran - bufor ramki.
*/
// Obsluga myszy
void MouseFunc(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
x_last_pos = x;
y_last_pos = y;
lbutton_status = 1;
}
else
{
lbutton_status = 0;
}
if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
{
y_last_pos = y;
rbutton_status = 1;
}
else
{
rbutton_status = 0;
}
}
void MouseMotion(GLsizei x, GLsizei y)
{
x_delta = x - x_last_pos;
y_delta = y - y_last_pos;
x_last_pos = x;
y_last_pos = y;
glutPostRedisplay();
}
void DrawScene(void)
{
// Czy?cimy okno aktualnym (domy?lnym) kolorem oraz resetujemy bufor głębi
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Resetujemy bieżšcš macierz
glLoadIdentity();
// Definiujemy położenie obserwatora
gluLookAt(rotx+zoom,roty,rotz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
// Rysujemy osie układu
DrawSceneAxes();
// Zamieniamy bufory ramki
glutSwapBuffers();
}
/* Ta funkcja jest wywoływana przez funkcję DrawScene.
* Jej zadaniem jest rysowanie konkretnych obiektów osi układu
* współrzędnych.
*/
void DrawSceneAxes(void)
{
// Definiujemy nowy typ jako tablicę 3-elementowš
typedef float pt3d[3];
// Poczštek i koniec osi X
pt3d x_beg = { -10.0f, 0.0f, 0.0f };
pt3d x_end = { 10.0f, 0.0f, 0.0f };
// Poczatek i koniec osi Y
pt3d y_beg = { 0.0f, -10.0f, 0.0f };
pt3d y_end = { 0.0f, 10.0f, 0.0f };
// Poczštek i koniec osi Z
pt3d z_beg = { 0.0f, 0.0f, -10.0f };
pt3d z_end = { 0.0f, 0.0f, 10.0f };
if (lbutton_status == 1)
{
theta += (y_delta*pixelsangle)*(0.01);
fi+= (x_delta*pixelsangle)*(0.01);
//Obroc
rotx = r*cos(theta)*cos(fi);
roty = r*sin(theta);
rotz = r*cos(theta)*sin(fi);
}
if (rbutton_status == 1)
{
zoom += y_delta*(0.01);
}
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_TRIANGLES);
glTexCoord2f(0.0f, 0.0f);
glVertex3f( -5.0f, -5.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f( 5.0f, -5.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f( 5.0f, 5.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glEnd();
// glutSolidTeapot(4.0);
// glEnd();
}
/* Ta funkcja służy do wstępnej konfiguracji OpenGLa.
* Zanim co? narysujemy musimy wywołać tę funkcję.
*/
void InitOpenGL(void)
{
GLint ImHeight, ImWidth, ImComponents;
GLenum ImFormat;
GLbyte *pBytes;
//Teksturowanie bÍdzie prowadzone tyko po jednej stronie úciany
glEnable(GL_CULL_FACE);
// glCullFace(GL_FRONT);
//Przeczytanie obrazu tekstury z pliku o nazwie tekstura.tga
pBytes = LoadTGAImage("tekstura.tga", &ImWidth, &ImHeight, &ImComponents, &ImFormat);
//Zdefiniowanie tekstury 2-D
glTexImage2D(GL_TEXTURE_2D, 0, ImComponents, ImWidth, ImHeight, 0, ImFormat, GL_UNSIGNED_BYTE, pBytes);
//Zwolnienie pamiÍci
free(pBytes);
//W??czenie mechanizmu teksturowania
glEnable(GL_TEXTURE_2D);
//Ustalenie trybu teksturowania
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
//Okreúlenie sposobu nak?adania tekstur
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Ustawiamy domy?lny, czarny kolor tła okna - bufor ramki malujemy na czarno
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GLfloat mat_ambient[] = {1.0, 1.0, 1.0, 1.0}; //wspolczynniki ka =[kar,kag,kab] dla swiatla otoczenia
GLfloat mat_diffuse[] = {1.0, 1.0, 1.0, 1.0}; //wspolczynniki kd =[kdr,kdg,kdb] swiatla rozproszonego
GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0}; // wspolczynniki ks =[ksr,ksg,ksb] dla úswiatla odbitego
GLfloat mat_shininess = {20.0}; // wspolczynnik n opisujący polysk powierzchni
// Definicja zrodla swiatla
GLfloat light_position[] = {0.0, 0.0, 10.0, 1.0}; //polozenie zrodla
//skladowe intensywnosci swiecenia zrodla swiatla otoczenia - Ia = [Iar,Iag,Iab]
GLfloat light_ambient[] = {0.1, 0.1, 0.1, 1.0};
//skladowe intensywnoúci swiecenia zrodla swiatla powodujacego odbicie dyfuzyjne Id = [Idr,Idg,Idb]
GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0};
//skladowe intensywnoúci swiecenia zrodla swiatla powodujacego odbicie kierunkowe Is = [Isr,Isg,Isb]
GLfloat light_specular[]= {1.0, 1.0, 1.0, 1.0};
//skladowa stala ds dla modelu zmian oswietlenia w funkcji odleglosci od zrodla
GLfloat att_constant = {1.0};
//skladowa liniowa dl dla modelu zmian oswietlenia w funkcji odlegosci od zrodla
GLfloat att_linear = {0.05};
//skladowa kwadratowa dq dla modelu zmian oswietlenia w funkcji odleglosc od zrodla
GLfloat att_quadratic = {0.001};
// Ustawienie patrametrUw materialu
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess);
// Ustawienie parametrow zrodla
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, att_constant);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, att_linear);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, att_quadratic);
// Ustawienie opcji systemu oswietlania sceny
glShadeModel(GL_SMOOTH);// wlaczenie lagodnego cieniowania
glEnable(GL_LIGHTING);//wlaczenie systemu oúwietlenia sceny
glEnable(GL_LIGHT0); // wlaczenie zrodla o numerze 0
glEnable(GL_DEPTH_TEST); //wlaczenie mechanizmu z-bufora
}
/*Ta funkcja ustawia perspektywę - jej odpowiednikiem w starszych implementacjach openGL jest gluPerspective
*/
void perspectiveGL( GLdouble fovY, GLdouble aspect, GLdouble zNear, GLdouble zFar )
{
const GLdouble pi = 3.1415926535897932384626433832795;
GLdouble fW, fH;
fH = tan( fovY / 360 * pi ) * zNear;
fW = fH * aspect;
glFrustum( -fW, fW, -fH, fH, zNear, zFar );
}
/* Tę funkcję wywołuje system w momencie gdy użytkownik zmieni myszš
* rozmiar głównego okna. jej zadaniem jest zachowanie proporcji wymiarów
* rysowanych obiektów niezależnie od wymiarów okna.
*/
void ReshapeWindow(int width, int height)
{
pixelsangle = 360.0f/(float)width;
// Ustawiamy układ współrzędnych obserwatora
glMatrixMode(GL_PROJECTION);
// Resetujemy macierz projkecji
glLoadIdentity();
// Ustawiamy perspektywę
perspectiveGL(80.0, 1.0, 1.0, 100.0);
// Korekta
if(width <= height)
glViewport(0, (height - width)/2, width, width);
else
glViewport((width - height)/2, 0, height, height);
// Ustawiamy macierz modelu
glMatrixMode(GL_MODELVIEW);
// Resetujemy macierz modelu
glLoadIdentity();
}
GLbyte *LoadTGAImage(const char *FileName, GLint *ImWidth, GLint *ImHeight, GLint *ImComponents, GLenum *ImFormat)
{
// Struktura dla nag?Uwka pliku TGA
#pragma pack(1)
typedef struct
{
GLbyte idlength;
GLbyte colormaptype;
GLbyte datatypecode;
unsigned short colormapstart;
unsigned short colormaplength;
unsigned char colormapdepth;
unsigned short x_orgin;
unsigned short y_orgin;
unsigned short width;
unsigned short height;
GLbyte bitsperpixel;
GLbyte descriptor;
}TGAHEADER;
#pragma pack(8)
FILE *pFile;
TGAHEADER tgaHeader;
unsigned long lImageSize;
short sDepth;
GLbyte *pbitsperpixel = NULL;
// Wartoúci domyúlne zwracane w przypadku b?Ídu
*ImWidth = 0;
*ImHeight = 0;
*ImFormat = GL_BGR_EXT;
*ImComponents = GL_RGB8;
pFile = fopen(FileName, "rb");
if (pFile == NULL)
return NULL;
// Przeczytanie nag?Uwka pliku
fread(&tgaHeader, sizeof(TGAHEADER), 1, pFile);
// Odczytanie szerokoúci, wysokoúci i g?Íbi obrazu
*ImWidth = tgaHeader.width;
*ImHeight = tgaHeader.height;
sDepth = tgaHeader.bitsperpixel / 8;
// Sprawdzenie, czy g?Íbia spe?nia za?ooone warunki (8, 24, lub 32 bity)
if (tgaHeader.bitsperpixel != 8 && tgaHeader.bitsperpixel != 24 && tgaHeader.bitsperpixel != 32)
return NULL;
// Obliczenie rozmiaru bufora w pamiÍci
lImageSize = tgaHeader.width * tgaHeader.height * sDepth;
// Alokacja pamiÍci dla danych obrazu
pbitsperpixel = (GLbyte*)malloc(lImageSize * sizeof(GLbyte));
if (pbitsperpixel == NULL)
return NULL;
if(fread(pbitsperpixel, lImageSize, 1, pFile) != 1)
{
free(pbitsperpixel);
return NULL;
}
// Ustawienie formatu OpenGL
switch (sDepth)
{
case 3:
*ImFormat = GL_BGR_EXT;
*ImComponents = GL_RGB8;
break;
case 4:
*ImFormat = GL_BGRA_EXT;
*ImComponents = GL_RGBA8;
break;
case 1:
*ImFormat = GL_LUMINANCE;
*ImComponents = GL_LUMINANCE8;
break;
};
fclose(pFile);
return pbitsperpixel;
}
- Przechwytywanie.JPG (28 KB) - ściągnięć: 157