Я новичок в OpenGL и в качестве своего первого приложения я попытался сгенерировать фрактал, используя метод барицентрического деления треугольника. Не зная функций OpenGL для изменения перспективы, моя первая идея алгоритма масштабирования и изменения точки обзора заключалась в том, чтобы просто перерисовывать весь фрактал с различными координатами начальной точки и коэффициентом масштабирования при каждом нажатии клавиши (стрелки для перемещения камеры и + / — для увеличения).
Учитывая тот факт, что за 6 итераций барицентрического подразделения нарисовано около 56 000 треугольников (6 ^ 0 + 6 ^ 1 + 6 ^ 2 + 6 ^ 3 + 6 ^ 4 + 6 ^ 5 + 6 ^ 6 треугольников) этот алгоритм очень неэффективен. Поэтому я попытался использовать gluPerspective () для масштабирования, результатом был, к сожалению, черный экран, а не фрактал. У меня есть два основных вопроса:
Что я сделал не так в своем коде. Почему у меня черный экран?
#include <GL/glfw.h>
#include <iostream>
#include <math.h>
using namespace std;
struct punct{ GLdouble x, y;}; //"punct" means "point" in my native language
punct A, B, C;
int n=0, mode=1;
double l=1.6, ox=0, oy=0, scale=1;
punct mid (punct A, punct B);
void initiate ();
void line (punct A, punct B);
void triangle (punct A, punct B, punct C);
void divide (punct A, punct B, punct C,int i);
int main ()
{
int width, height;
bool running = true;
char input=NULL;
glfwInit();
if( !glfwOpenWindow( 800, 800, 0, 0, 0, 0, 0, 0, GLFW_FULLSCREEN ) )
{
glfwTerminate();
return 0;
}
glfwSetWindowTitle("Baricentric");
while(running)
{
glfwGetWindowSize( &width, &height );
height = height > 0 ? height : 1;
glViewport( 0, 0, width, height );
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glClear( GL_COLOR_BUFFER_BIT );
//This functions make my screen black
//glMatrixMode(GL_MODELVIEW);
//glLoadIdentity();
//gluPerspective (50*scale, width/height, 10.0, 100.0);
initiate ();
if(glfwGetKey(GLFW_KEY_KP_ADD) && glfwGetKey(GLFW_KEY_LCTRL)) input='+';
if(!glfwGetKey(GLFW_KEY_KP_ADD) && input=='+') {
if(n<7) n++;
input='\n';
}
if(glfwGetKey(GLFW_KEY_KP_SUBTRACT) && glfwGetKey(GLFW_KEY_LCTRL)) input='-';
if(!glfwGetKey(GLFW_KEY_KP_SUBTRACT) && input=='-') {
if(n>0)n--;
input='\n';
}
if(glfwGetKey(GLFW_KEY_KP_1)||glfwGetKey('1')) input='1';
if(!glfwGetKey(GLFW_KEY_KP_1) && input=='1') {
mode=1;
input='\n';
}
if(glfwGetKey(GLFW_KEY_KP_0)||glfwGetKey('0')) input='0';
if(!glfwGetKey(GLFW_KEY_KP_0) && input=='0') {
mode=0;
input='\n';
}
if(glfwGetKey(GLFW_KEY_KP_ADD) && !glfwGetKey(GLFW_KEY_LCTRL)) l+=0.002*(n+0.5); //'l' is replaced with 'scale' when using gluPerspective()
if(glfwGetKey(GLFW_KEY_KP_SUBTRACT) && !glfwGetKey(GLFW_KEY_LCTRL)) l-=0.002*(n+0.5); //'l' is replaced with 'scale' when using gluPerspective()
if(glfwGetKey(GLFW_KEY_UP)) oy-=0.002*(n+0.5);
if(glfwGetKey(GLFW_KEY_DOWN)) oy+=0.002*(n+0.5);
if(glfwGetKey(GLFW_KEY_RIGHT)) ox+=0.002*(n+0.5);
if(glfwGetKey(GLFW_KEY_LEFT)) ox-=0.002*(n+0.5);if (n) divide (A,B,C,1);glfwSwapBuffers();
running = !glfwGetKey(GLFW_KEY_ESC) && glfwGetWindowParam( GLFW_OPENED);
}
glfwTerminate();
return 0;
}
punct mid (punct A, punct B) {
punct C;
C.x=(A.x+B.x)/2;
C.y=(A.y+B.y)/2;
return C;
}
void initiate () {
A.x = -(l/2)+ox; A.y = -(l*sqrt(3)/4)+oy;
B.x = l/2+ox; B.y = A.y;
C.x = 0+ox; C.y = (l*sqrt(3)/4)+oy;
glBegin (GL_QUADS);
glColor3f(0.93,0.84,0.82); glVertex3d(-1, 1, 0);
glColor3f(0.01,0.95,0.83); glVertex3d(-1, -1, 0);
glColor3f(0.80,0.71,0.80); glVertex3d(1, -1, 0);
glColor3f(0.8,1,0.8); glVertex3d(1, 1, 0);
glEnd ();
glBegin (GL_TRIANGLES);
glColor3f(0,0.6,0.88); glVertex3d(C.x, C.y, 0);
glColor3f(0,0.77,0.73); glVertex3d(B.x, B.y, 0);
glColor3f(0.01,0.66,0.62); glVertex3d(A.x, A.y, 0);
glEnd ();
if (mode==0) {
glLineWidth (0.1);
glColor3f(0,0,0.36);
glBegin (GL_LINE_LOOP);
glVertex3d(C.x, C.y, 0);
glVertex3d(B.x, B.y, 0);
glVertex3d(A.x, A.y, 0);
glEnd ();
}
}void divide (punct A, punct B, punct C, int i) {
if(i<=n) {
punct a, b, c, G;
c=mid(A,B);
b=mid(A,C);
a=mid(B,C);
G.x=(A.x+B.x+C.x)/3;
G.y=(A.y+B.y+C.y)/3;
if(mode==1) {
triangle(G,a,C);
triangle(G,b,C);
triangle(G,a,B);
triangle(G,c,B);
triangle(G,c,A);
triangle(G,b,A);
}
line(c,C);
line(a,A);
line(b,B);
divide(G,a,C,i+1);
divide(G,b,C,i+1);
divide(G,a,B,i+1);
divide(G,c,B,i+1);
divide(G,c,A,i+1);
divide(G,b,A,i+1);
}
}
void line (punct A, punct B) {
glBegin (GL_LINE_STRIP);
glVertex3d(A.x,A.y,0);
glVertex3d(B.x,B.y,0);
glEnd ();
}
void triangle (punct A, punct B, punct C) {
glBegin (GL_TRIANGLES);
glColor3f(0,0.6,0.88); glVertex3d(C.x, C.y, 0);
glColor3f(0,0.77,0.73); glVertex3d(B.x, B.y, 0);
glColor3f(0.01,0.66,0.62); glVertex3d(A.x, A.y, 0);
glEnd ();
}
Как и многие другие, вы ошиблись, считая, что OpenGL — это граф сцены. Это не вариант.
OpenGL — это API для рисования. Ваша ОС предоставляет холст (окно, PBuffer, Pixmap и т. Д.), А OpenGL предоставляет инструменты рисования в виде точек, линий или треугольников.
Функции OpenGL для изменения перспективы и точки обзора (gluPerspective (), gluLookAt (), glFrustum () и т. Д.) Перерисовывают весь рисунок с разными координатами,
Все, что они делают, это изменяют значения нескольких матриц. Ничто на экране не изменяется этим. Вы должны перерисовать все это, чтобы внести видимые изменения.
Других решений пока нет …