#include "Kwadryka.h" unsigned int Kwadryka::TwórzTablicęWerteksówŚciętegoStożka(CWerteks*& tablicaWerteksów, float promieńDolny, float promieńGórny, float położeniePodstawy, float wysokość, int liczbaSekcji) { const int liczbaWerteksów = 2 * (liczbaSekcji + 1); const double przyrostKąta = 2 * M_PI / liczbaSekcji; const float r = 1, g = 1, b = 1, a = 1; tablicaWerteksów = new CWerteks[liczbaWerteksów]; for (int i = 0; i <= liczbaSekcji; i++) //ilość par musi być większa o 1 niż ilość sekcji, przy pełnym obrocie pierwsza i ostatnia są takie same { double kąt = i * przyrostKąta; tablicaWerteksów[2 * i].x = promieńGórny*(float)cos(kąt); tablicaWerteksów[2 * i].y = promieńGórny*(float)sin(kąt); tablicaWerteksów[2 * i].z = położeniePodstawy + wysokość; tablicaWerteksów[2 * i].r = r; tablicaWerteksów[2 * i].g = g; tablicaWerteksów[2 * i].b = b; tablicaWerteksów[2 * i].a = a; tablicaWerteksów[2 * i + 1].x = promieńDolny*(float)cos(kąt); tablicaWerteksów[2 * i + 1].y = promieńDolny*(float)sin(kąt); tablicaWerteksów[2 * i + 1].z = położeniePodstawy; tablicaWerteksów[2 * i + 1].r = r; tablicaWerteksów[2 * i + 1].g = g; tablicaWerteksów[2 * i + 1].b = b; tablicaWerteksów[2 * i + 1].a = a; //obliczanie normalnej float a = promieńDolny - promieńGórny; float c = sqrt(a * a + wysokość * wysokość); float sinTheta = a / c; float cosTheta = wysokość / c; tablicaWerteksów[2 * i].nx = (float)(cos(kąt)*cosTheta); tablicaWerteksów[2 * i].ny = (float)(sin(kąt)*cosTheta); tablicaWerteksów[2 * i].nz = sinTheta; tablicaWerteksów[2 * i + 1].nx = tablicaWerteksów[2 * i].nx; tablicaWerteksów[2 * i + 1].ny = tablicaWerteksów[2 * i].ny; tablicaWerteksów[2 * i + 1].nz = tablicaWerteksów[2 * i].nz; //współrzędne teksturowania tablicaWerteksów[2 * i].s = (float)(1 - kąt / 2 / M_PI); tablicaWerteksów[2 * i].t = 0; tablicaWerteksów[2 * i + 1].s = (float)(1 - kąt / 2 / M_PI); tablicaWerteksów[2 * i + 1].t = 1; } return liczbaWerteksów; } unsigned int Kwadryka::TwórzTablicęWerteksów(CWerteks*& werteksy) { if (liczbaPasm == 1) { return TwórzTablicęWerteksówŚciętegoStożka(werteksy, promieńDolny, promieńGórny, położeniePodstawy, wysokość, liczbaSekcji); } else //tylko sfera ma więcej niż jedno pasmo; tu lepiej byłoby użyć bufora indeksów { unsigned int całkowitaLiczbaWerteksów = liczbaWerteksówWPaśmie * liczbaPasm; const float promień = promieńDolny; werteksy = new CWerteks[całkowitaLiczbaWerteksów]; double przyrostKątaTheta = M_PI / liczbaPasm; for (int i = 0; i < liczbaPasm; i++) { double kątThetaGórny = i * przyrostKątaTheta; double kątThetaDolny = (i + 1) * przyrostKątaTheta; float wysokośćGórna = (float)(promień * cos(kątThetaGórny)); float wysokośćDolna = (float)(promień * cos(kątThetaDolny)); float _promieńGórny = (float)(promień * sin(kątThetaGórny)); float _promieńDolny = (float)(promień * sin(kątThetaDolny)); CWerteks* tablicaWerteksówPasma; unsigned int liczbaWerteksówWPaśmie = TwórzTablicęWerteksówŚciętegoStożka( tablicaWerteksówPasma, _promieńDolny, _promieńGórny, wysokośćDolna, wysokośćGórna - wysokośćDolna, liczbaSekcji); CWerteks* początekWerteksówPasma = werteksy + liczbaWerteksówWPaśmie * i; std::copy(tablicaWerteksówPasma, tablicaWerteksówPasma + liczbaWerteksówWPaśmie, początekWerteksówPasma); delete[] tablicaWerteksówPasma; } return całkowitaLiczbaWerteksów; } } void Kwadryka::Rysuj() { glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vbo); for (int i = 0; i < liczbaPasm; ++i) { glDrawArrays(GL_TRIANGLE_STRIP, i*liczbaWerteksówWPaśmie, liczbaWerteksówWPaśmie); } //glBindBuffer(GL_ARRAY_BUFFER, NULL); //glBindVertexArray(NULL); } //------------------------------------------------------------------- unsigned int SferaZBuforemIndeksów::TwórzTablicęWerteksów(CWerteks*& werteksy) { const unsigned int całkowitaLiczbaWerteksów = (liczbaSekcjiNaRównoleżnikach + 1) * (liczbaSekcjiNaPołudnikach + 1); werteksy = new CWerteks[całkowitaLiczbaWerteksów]; const double przyrostKątaTheta = M_PI / liczbaSekcjiNaPołudnikach; const double przyrostKątaPhi = 2 * M_PI / liczbaSekcjiNaRównoleżnikach; const float r = 1, g = 1, b = 1, a = 1; for (unsigned int i = 0; i <= liczbaSekcjiNaPołudnikach; i++) { double kątTheta = i * przyrostKątaTheta; float _wysokość = (float)(promień * cos(kątTheta)); float _promień = (float)(promień * sin(kątTheta)); for (unsigned int j = 0; j <= liczbaSekcjiNaRównoleżnikach; j++) { double kątPhi = j*przyrostKątaPhi; int indeks = j + i*(liczbaSekcjiNaRównoleżnikach + 1); werteksy[indeks].x = _promień*(float)cos(kątPhi); werteksy[indeks].y = _promień*(float)sin(kątPhi); werteksy[indeks].z = _wysokość; werteksy[indeks].r = r; werteksy[indeks].g = g; werteksy[indeks].b = b; werteksy[indeks].a = 1; if (i != 0 && i != liczbaSekcjiNaPołudnikach) { werteksy[indeks].nx = werteksy[indeks].x / _promień; werteksy[indeks].ny = werteksy[indeks].y / _promień; werteksy[indeks].nz = werteksy[indeks].z / _promień; } else { werteksy[indeks].nx = 0; werteksy[indeks].ny = 0; werteksy[indeks].nz = werteksy[indeks].z / fabs(werteksy[indeks].z); } werteksy[indeks].s = (float)(1 - kątPhi / 2 / M_PI); werteksy[indeks].t = (float)(kątTheta / M_PI); } } return całkowitaLiczbaWerteksów; } unsigned int SferaZBuforemIndeksów::TwórzTablicęIndeksów(GLuint*& indeksy) { const unsigned int liczbaIndeksówWPaśmie = 2 * (liczbaSekcjiNaRównoleżnikach + 1); const unsigned int całkowitaLiczbaIndeksów = liczbaIndeksówWPaśmie * liczbaSekcjiNaPołudnikach; indeksy = new GLuint[całkowitaLiczbaIndeksów]; for (unsigned int i = 0; i < całkowitaLiczbaIndeksów / 2; i++) { indeksy[2 * i] = i; indeksy[2 * i + 1] = indeksy[2 * i] + (liczbaSekcjiNaRównoleżnikach + 1); } return całkowitaLiczbaIndeksów; }