花了我一段时间,但我能够成功实现菱形平方算法来绘制使用OpenGL的等离子体分形。它是通过使用每次生成场景时使用的递归函数来做到的(我猜)。接下来我要做的是添加一些额外的功能,让观看者在生成的分形上移动。但是,问题是我不能使它工作...所以这里是我的问题:飞越等离子体分形 - 菱形平方算法
它能够让算法呈现一次吗? (我没有使用任何数组来保存生成的点和颜色的记录)是否只是修改renderscene来做到这一点?
我怎样才能摆脱正方形之间的灰色空间?
如果没有其他的方式来做这件事,除了保留值的记录(即在一个数组),你可以给我一个建议,因为我迷失在设置数组的索引。 ..
下面的代码(注释是抛光不过,还有一些变量):
#include <Windows.h>
#include <gl\GL.h>
#include <glut.h>
#include <iostream>
#include <time.h>
#include <math.h>
#include <random>
using namespace std;
typedef float point3[3];
GLfloat ile;
bool kolor = 0;
bool gauss = 0;
int model = 0; // 0- siatka, 1 - trójkąty, 2-próba
static const double pi = 3.1415927;
static GLfloat theta[] = { 0.0, 0.0, 0.0 }; //trzy kąty obroty wokół osi x, y, z
void RenderScene(void);
void sr_boku(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h, GLfloat c1, GLfloat c2, GLfloat c3, GLfloat c4);
//Rozkład Gaussa
double normal(double mean, double std)
{
default_random_engine generator;
normal_distribution<double> distribution(mean, std);
return distribution(generator);
//std*sqrt(-2 * log(rand() + 1)/(RAND_MAX + 1))*sin(2 * pi * rand()/(RAND_MAX + 1)) + mean;
}
class Kolor
{
public:
GLfloat r;
GLfloat g;
GLfloat b;
};
//Funkcja reagująca na naciskane klawisze
void czytajKlawisz(unsigned char key, int x, int y)
{
switch (key)
{
case '=':
case '+':
{
ile = ile * 2;
break;
}
case '-':
{
ile = ile/2;
break;
}
case 'k':
{
if (kolor == 0)
kolor = 1;
else
kolor = 0;
break;
}
case 'g':
{
if (gauss == 0)
gauss = 1;
else
gauss = 0;
}
case '1':
case 's':
{
model = 0;
break;
}
case '2':
case 't':
{
model = 1;
break;
}
case '3':
case 'p':
{
model = 2;
break;
}
case 27:
break;
}
glutPostRedisplay();
}
void koloruj(GLfloat c, Kolor &kolor)
{
if (c < 0.5)
kolor.r = c * 2;
else
kolor.r = (1.0 - c) * 2;
if (c >= 0.3 && c < 0.8)
kolor.g = (c - 0.3) * 2;
else if (c < 0.3)
kolor.g = (0.3 - c) * 2;
else
kolor.r = (1.3 - c) * 2;
if (c >= 0.5)
kolor.b = (c - 0.5) * 2;
else
kolor.b = (0.5 - c) * 2;
}
GLfloat displace(GLfloat num, int max, int ziarno)
{
GLfloat m = num/(float)(max)* ziarno;
return ((GLfloat)(rand() % 101)*0.01f - 0.5f) * m;
}
//Wyrysowanie osi układu współrzędnych
void Axes(void)
{
point3 xmin = { -5.0f, 0.0f, 0.0f };
point3 xmax = { 5.0f, 0.0f, 0.0f };
point3 ymin = { 0.0f, -5.0f, 0.0f };
point3 ymax = { 0.0f, 5.0f, 0.0f };
point3 zmin = { 0.0f, 0.0f, -5.0f };
point3 zmax = { 0.0f, 0.0f, 5.0f };
glRotated(45.0, 1.0, -0.1, 0.1);
glColor3f(10.0f, 0.0f, 0.0f); //Ustawienie koloru rysowania na czerwony -oś X
glBegin(GL_LINES);
glVertex3fv(xmin);
glVertex3fv(xmax);
glEnd();
glColor3f(0.0f, 10.0f, 0.0f); //Ustawienie koloru rysowania na zielony -oś Y
glBegin(GL_LINES);
glVertex3fv(ymin);
glVertex3fv(ymax);
glEnd();
glColor3f(0.0f, 0.0f, 01.0f); //Ustawienie kolory rysowania na niebieski -oś Z
glBegin(GL_LINES);
glVertex3fv(zmin);
glVertex3fv(zmax);
glEnd();
}
//Funkcja zwrotną odpowiedzialna za obrót modelu wokół osi
void spin()
{
theta[0] -= 0.000005;
if (theta[0] > 360.0)
theta[0] -= 360.0;
theta[1] -= 0.000005;
if (theta[1] > 360)
theta[1] -= 360.0;
theta[2] -= 0.00005;
if (theta[2] > 360.0)
theta[2] -= 360.0;
glutPostRedisplay(); //odświeżenie zawartości aktualnego okna
}
//Fraktal
void fraktal(int w, int h)
{
float c1, c2, c3, c4;
int x, y;
x = w/2;
y = h/2;
GLfloat z = (GLfloat)(rand() % 101)/10.0f;
c1 = (GLfloat)(rand() % 101)/100.0f;
c2 = (GLfloat)(rand() % 101)/100.0f;
c3 = (GLfloat)(rand() % 101)/100.0f;
c4 = (GLfloat)(rand() % 101)/100.0f;
sr_boku(-x, -y, z, w, h, c1, c2, c3, c4);
}
//Główna funkcja rysująca
void sr_boku(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h, GLfloat c1, GLfloat c2, GLfloat c3, GLfloat c4)
{
GLfloat middle;
GLfloat w1, w2, w3, w4;
GLfloat new_w = w/2.0f;
GLfloat new_h = h/2.0f;
//inne podejście
if (model == 0) //siatka
{
if (h> ile || w > ile)
{
middle = (c1 + c2 + c3 + c4)*0.25 + displace(h + w, 30, 3);
w1 = (c1 + c2)/2.0f;
w2 = (c2 + c3)/2.0f;
w3 = (c3 + c4)/2.0f;
w4 = (c4 + c1)/2.0f;
if (middle > 1.0f)
middle = 1.0f;
if (middle < 0.0f)
middle = 0.5f;
sr_boku(x, y, z, new_w, new_h, w4, middle, w3, c4);// , n - 1);
sr_boku(x + new_w, y, z, new_w, new_h, middle, w2, c3, w3);// , n - 1);
sr_boku(x + new_w, y+new_h, z, new_w, new_h, w1, c2, w2, middle);// , n - 1);
sr_boku(x, y+new_h, z, new_w, new_h, c1, w1, middle, w4);// , n - 1);
}
else
{
GLfloat z1 = c1 * 5;
GLfloat z2 = c2 * 5;
GLfloat z3 = c3 * 5;
GLfloat z4 = c4 * 5;
Kolor kk;
glBegin(GL_QUADS);
koloruj(c1, kk);
glColor3f(kk.r, kk.g, kk.b);
glVertex3f(x, y + new_h, z1 - 2.5f);
koloruj(c2, kk);
glColor3f(kk.r, kk.g, kk.b);
glVertex3f(x + new_w, y + new_h, z2 - 2.5f);
koloruj(c3, kk);
glColor3f(kk.r, kk.g, kk.b);
glVertex3f(x + new_w, y, z3 - 2.5f);
koloruj(c4, kk);
glColor3f(kk.r, kk.g, kk.b);
glVertex3f(x, y, z4 - 2.5f);
glEnd();
}
}
if (model == 1) //trójkąty
{
if (h> ile || w > ile)
{
middle = (c1 + c2 + c3 + c4)*0.25 + displace(h + w, 60, 3);
w1 = (c1 + c2)/2.0f;
w2 = (c2 + c3)/2.0f;
w3 = (c3 + c4)/2.0f;
w4 = (c4 + c1)/2.0f;
if (middle > 1.0f)
middle = 1.0f;
if (middle < 0.0f)
middle = 0.0f;
sr_boku(x, y, z, new_w, new_h, w4, middle, w3, c4);// , n - 1);
sr_boku(x + new_w, y, z, new_w, new_h, middle, w2, c3, w3);// , n - 1);
sr_boku(x + new_w, y +new_h, z, new_w, new_h, w1, c2, w2, middle);// , n - 1);
sr_boku(x, y+new_h, z, new_w, new_h, c1, w1, middle, w4);// , n - 1);
}
else
{
GLfloat z1 = c1 * 5;
GLfloat z2 = c2 * 5;
GLfloat z3 = c3 * 5;
GLfloat z4 = c4 * 5;
Kolor kk;
glBegin(GL_TRIANGLE_FAN);
koloruj(c1, kk);
glColor3f(kk.r, kk.g, kk.b);
glVertex3f(x, y + new_h, z1 - 2.5f);
koloruj(c2, kk);
glColor3f(kk.r, kk.g, kk.b);
glVertex3f(x + new_w, y + new_h, z2 - 2.5f);
koloruj(c3, kk);
glColor3f(kk.r, kk.g, kk.b);
glVertex3f(x + new_w, y, z3 - 2.5f);
koloruj(c4, kk);
glColor3f(kk.r, kk.g, kk.b);
glVertex3f(x, y, z4 - 2.5f);
glEnd();
}
}
if (model == 2) //proby
{
if (h > ile || w > ile)
{
middle = (c1 + c2 + c3 + c4)*0.25 + displace(h + w, 60, 3);
w1 = (c1 + c2)/2.0f;
w2 = (c2 + c3)/2.0f;
w3 = (c3 + c4)/2.0f;
w4 = (c4 + c1)/2.0f;
if (middle > 1.0f)
middle = 1.0f;
if (middle < 0.0f)
middle = 0.0f;
sr_boku(x, y, z, new_w, new_h, w4, middle, w3, c4);// , n - 1);
sr_boku(x + new_w, y, z, new_w, new_h, middle, w2, c3, w3);// , n - 1);
sr_boku(x + new_w, y + new_h, z, new_w, new_h, w1, c2, w2, middle);// , n - 1);
sr_boku(x, y + new_h, z, new_w, new_h, c1, w1, middle, w4);// , n - 1);
}
else
{
GLfloat z1 = normal(5, 5);
GLfloat z2 = normal(5, 5);
GLfloat z3 = normal(5, 5);
GLfloat z4 = normal(5, 5);
Kolor kk;
glBegin(GL_TRIANGLES);
koloruj(c1, kk);
glColor3f(kk.r, kk.g, kk.b);
glVertex3f(x, y + new_h, z1 - 2.5f);
koloruj(c2, kk);
glColor3f(kk.r, kk.g, kk.b);
glVertex3f(x + new_w, y + new_h, z2 - 2.5f);
koloruj(c4, kk);
glColor3f(kk.r, kk.g, kk.b);
glVertex3f(x, y, z4 - 2.5f);
glEnd();
glBegin(GL_TRIANGLES);
koloruj(c2, kk);
glColor3f(kk.r, kk.g, kk.b);
glVertex3f(x + new_w, y + new_h, z2 - 2.5f);
koloruj(c3, kk);
glColor3f(kk.r, kk.g, kk.b);
glVertex3f(x, y, z4 - 2.5f);
glColor3f(kk.r, kk.g, kk.b);
glVertex3f(x + new_w, y, z3 - 2.5f);
koloruj(c4, kk);
glColor3f(kk.r, kk.g, kk.b);
glVertex3f(x, y, z4 - 2.5f);
glEnd();
}
}
}
// Funkcjs określająca co ma byc narysowane
void RenderScene(void)
{
// Czyszczenie okna aktualnym kolorem czyszczącym
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
srand(time(NULL));
//Obrócenie modelu wokół osi x, y, z
//glRotatef(theta[0], 0.01, 0.0, 0.0);
//glRotatef(theta[1], 0.0, 0.01, 0.0);
//glRotatef(theta[2], 0.0, 0.0, 0.01);
Axes();
fraktal(60, 60);
//fraktal(-90, 90, 180);
// Przekazanie poleceń rysujących do wykonania
glFlush();
glutSwapBuffers();
}
// Funkcja ustalająca stan renderowania
void MyInit(void)
{
// Kolor wnętrza okna - szary
glClearColor(0.5, 0.5f, 0.5f, 1.0f);
}
// Funkcja zachowująca proporcje rysowanych obiektów
void ChangeSize(GLsizei horizontal, GLsizei vertical)
{
GLfloat AspectRatio;
if (vertical == 0)
vertical = 1;
//Ustawienia wielkości okna urządzenia
glViewport(0, 0, horizontal, vertical);
// Określenie układu współrzędnych obserwatora
glMatrixMode(GL_PROJECTION);
// Określenie przestrzeni ograniczającej
glLoadIdentity();
// Współczynnik proporcji okna
AspectRatio = (GLfloat)horizontal/(GLfloat)vertical;
if (horizontal <= vertical)
glOrtho(-7.5, 7.5, -7.5/AspectRatio, 7.5/AspectRatio, 10.0, -10.0);
else
glOrtho(-7.5*AspectRatio, 7.5*AspectRatio, -7.5, 7.5, 10.0, -10.0);
// Określenie układu współrzędnych
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void main(void)
{
//wywołanie funkcji wypełniającej funkcje W(x) i Wc(x)
//funkcja_grey(250);
ile = 0.1;
// Ustawienia trybu wyświetlania (podwójny or rgb or głęboki)
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
// Utworzenie okna z nazwą na pasku stanu
glutCreateWindow("Fraktal Plazmowy w 3d v0.8");
//Funkcja reagująca na naciskane klawisze
glutKeyboardFunc(czytajKlawisz);
// Określenie funkcji RenderScene jako funkcji zwrotnej
glutDisplayFunc(RenderScene);
//Funkcja rejestrująca funkcje zwrotną
//glutIdleFunc(spin);
// Określenie funkcji zwrotnej odpowiedzialnej za rozmiar okna
glutReshapeFunc(ChangeSize);
// Wykonanie wszelki przygotowań przed rozpoczęciem renderowania
MyInit();
glEnable(GL_DEPTH_TEST);
// Uruchomienie szkieletu biblioteki GLUT
glutMainLoop();
}
下面是它的外观:
对于[so]问题,这是一大堆代码。如果可能的话(例如发布[SSCCE(短的,自包含的,正确的(可编译的),示例)]((在很多情况下,你仍然应该试着缩小问题的范围) http://sscce.org))。 – Dukeling
感谢您的建议,我会在未来尝试这样做。 – brian