LINUX.ORG.RU

OpenGL: освещение


0

0

Фигура - треугольная призма.

Как сделать освещение этой фигуры (сцены?)

#include <GL/glut.h>

void Display()
{
	glRotatef(20, 1.0, 0.0, 0.0);
    glRotatef(20, 0.0, 1.0, 0.0);
	
	glClearColor(1, 1, 1, 1); 
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	/* Начало фигуры (треугольньная пирамида) */
	glBegin(GL_QUADS);

	glVertex3f(-0.5, 0, 0);
	glVertex3f(0, 0, -0.5);
	glVertex3f(0.5, 0, 0);
	glVertex3f(0, 0, 0.5);

	glEnd();

	glBegin(GL_TRIANGLES);

	glVertex3f(0, 0, 0.5);
	glVertex3f(0.5, 0, 0);
	glVertex3f(0, 0.7, 0);

	glVertex3f(0, 0, -0.5);
	glVertex3f(-0.5, 0, 0);
	glVertex3f(0, 0.7, 0);

	glVertex3f(0, 0, 0.5);
	glVertex3f(-0.5, 0, 0);
	glVertex3f(0, 0.7, 0);

	glVertex3f(0, 0, -0.5);
	glVertex3f(0.5, 0, 0);
	glVertex3f(0, 0.7, 0);

	glEnd();
	/* Конец описания фигуры */
	
	glFinish();
}

/* Перерисовка окна */
void Reshape(GLint w, GLint h)
{
	glViewport(0,0,w,h);
	glLoadIdentity();
}

int main(int argc, char **argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB);
	glutInitWindowSize(640, 480);
	glutCreateWindow("Чекунов Николай - ИТ0502");

	glutDisplayFunc(Display);
	glutReshapeFunc(Reshape);
	glutMainLoop();

	return 0;
}
anonymous

Могу сказать как создать spot-источник:

// Во время инициализации GL

float pos[4], diff[4], cutff;

glEnable (GL_LIGHTING); пlLightfv (GL_LIGHT0, GL_POSITION, pos); glLightfv (GL_LIGHT0, GL_DIFFUSE, diff); glLightf (GL_LIGHT0, GL_SPOT_EXPONENT, 4); glLightf (GL_LIGHT0, GL_SPOT_CUTOFF, cutoff); glEnable (GL_LIGHT0);

Первые три элемента pos-координаты, четвертый-1.0 (Не помню точно что это значит). Первые три элемента diff-диффузные r,g,b, четвертый-1.0 (тоже не помню что это). cutoff-дальность.

Nazgul
()
Ответ на: комментарий от Nazgul

Сорри за формат. Не так давно на этом форуме. Не привык еще...

Nazgul
()

параметр w определяет, учитывать ли при расчете освещения угол между
нормалью к поверхности и падающим лучем света и расстояние до источника
света, или же только угол

а все из-за Игоря Тарасова, ошибочная глава из чьей книги до сих пор
первой вылазит, если загуглить на тему "OpenGL освещение" ( http://www.codenet.ru/progr/opengl/opengl_06.php ) - я на его форуме специально когда-то демку писал, может поможет:

Anonymous ★★★★★
()
Ответ на: комментарий от Anonymous

                           /* 
                           Кнопки: 
                           "N" одна нормаль/нормаль для каждой вершины 
                           "W" источник света с координатами/бесконечно удаленный 
                           "+","-" движение источника света 
                           "P" форма поверхности 
                           "S" solid/wire-frame 
                           */ 
#include <GL/glut.h>
#include <math.h>

                           GLfloat camLP=45, camWN=-45, camX=-20, camY=26, camZ=-20,ugan=0; 
                           GLboolean Normals=1, Solid=1; 
                           GLint Ploscost=0; 
                           GLfloat Rast=1,paramW=0; 

                           void drawMap(void); 
                           GLfloat Yi(int X,int Z); 

                           void initGL(void)
                           { 
                           //glShadeModel(GL_FLAT); //вся грань закрашивается с использованием цвета и освещенности расчитанных для ее первой                           вершины("Ребристые" объекты) 
                           glShadeModel(GL_SMOOTH);//освещение и цвет расчитываются для каждой вершины и интерполируются("Округлые" объекты)(Default) 
                           glEnable(GL_NORMALIZE); /*Автоматическая нормализация нормалей- 
                           -приведение вектора нормали к еденичныму 
                           (используйте только если это не сделано при расчете нормалей или если использовалось glScale(,,,) etc.(жрет ресурсы) )*/ 
                           //glEnable(GL_RESCALE_NORMAL_EXT);Хм????????? 
                           glDepthFunc(GL_LESS); 
                           glEnable(GL_DEPTH_TEST); 
                           glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); 
                           glEnable(GL_LIGHTING); 
                           } 

      void display(void) 
           {
	int i; 
	GLfloat Light0Pos[]={-6.0*Rast, 12.0*Rast, -2.0*Rast, paramW}; //A0( x0,y0,z0) ,W 
                           GLfloat Light0Dir[]={0,0,0}; //A1(x1,y1,z1) 
                           /*Если W=0 источник света считается бесконечно удаленным(а-ля солнечный свет) - лучи в любой точке паралельны вектору A0A1, растояние до источника не учитывается, учитывается только угол падения лучей на поверхность, точнее угол между заданным програмистом вектором нормали и направлением освещения*/ 

                           glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
                           glLoadIdentity(); 

                           gluLookAt(camX,camY,camZ,camX+sin(camLP*M_PI/180),camY+tan(camWN*M_PI/180),camZ+
cos(camLP*M_PI/180),0,1,0); 

                           //glLightfv(GL_LIGHT0,GL_DIFFUSE,blue); 
                           glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,180); 
                           glLightfv(GL_LIGHT0,GL_POSITION,Light0Pos);
                           glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,Light0Dir); 
                           glEnable(GL_LIGHT0); 

                           glPushMatrix(); 
                           glRotatef(ugan,0,1,0); 
                           glTranslatef(-36,0,-36); 
                           drawMap(); 
                           glPopMatrix(); 
                           glDisable(GL_LIGHT0); 
                           glDisable(GL_LIGHTING); 
                           /**/ 
                           glTranslatef(Light0Pos[0],Light0Pos[1],Light0Pos[2]); 
                           if (paramW!=0) glutSolidSphere(0.4,6,6);//Обозначим положение источника, когда оно есть 
                           for (i=0;i<=40;i++) 
                           { 
                           glTranslatef(-Light0Pos[0]/6,-Light0Pos[1]/6,-Light0Pos[2]/6); 
                           glutSolidSphere(0.1,6,6);//и направление освещения 
                           } 
                           /**/ 
                           glEnable(GL_LIGHTING); 
                           glFinish(); 
                           glFlush(); 
                           glutSwapBuffers(); 
                           } 

                           void mutNormali(int X, int Z) 
                           { 
                           /* 
                           "Правильного" способа расчета нормалей не существует- 
                           - с точки зрения геометрии нормаль в вершине не определена 
                           и програмисты придумывают свои функции расчета нормалей 
                           исходя из неких эмпирических правил. 
                           Если необходимо получить округлый объект т.е. используется 
                           режим glShadeModel(GL_SMOOTH) нормаль в вершине выбирается 
                           как среднее нормалей прилигающих граней 
                           Если рисуется ребристый объект(glShadeModel(GL_FLAT);) то нормаль 
                           в первой вершине грани должна быть собственно нормалью к этой грани, 
                           нормали в остальных вершинах влияния на данную грань не окажут 
                           */ 
                           //но мы пока просто сжульничаем..... 
                           #define Ay Yi(X,Z-1)-Yi(X,Z+1) 
                           #define By Yi(X-1,Z)-Yi(X+1,Z) 
                           glNormal3f(By,2,Ay); 
                           } 

Anonymous ★★★★★
()
Ответ на: комментарий от Anonymous

                           void drawMap(void) 
                           { 
                           int x=0,z=0; 
                           glEnable(GL_CULL_FACE); 
                           glCullFace(GL_FRONT); 
                           glNormal3f(1,4,6);   /*Варианта с освещением, но без нормалей в OpenGL нет, если для очередной вершины нормаль не задается, то используется последняя указанная нормаль, например если закомментировать вызов функции здесь будет использованна последняя нормаль использовавшаяся при прорисовке сфер в предидущем кадре. Данная нормаль выбрана произвольно,
если заменить (1,4,6) на (0,1,0) то для плоскости будет полученно коректное изображение */

                           while (x<66) 
                           { 
                           x++; 
                           if (Solid) glBegin(GL_TRIANGLE_STRIP); 
                           else glBegin(GL_LINE_STRIP); 
                           while ( z<66) 
                           { 
                           if (Normals) mutNormali(x,z); 
                           glVertex3f(x,Yi(x,z),z); 
                           if (Normals) mutNormali(x+1,z+1); 
                           glVertex3f(x+1,Yi(x+1,z+1),z+1); 
                           z++; 
                           } 
                           glEnd(); 
                           z=0; 
                           } 
                           glDisable(GL_CULL_FACE); 
                           glCullFace(GL_BACK); 
                           } 

                           GLfloat Yi(int X,int Z) 
                           { 
                           GLfloat Y,x=(GLfloat)X, z=(GLfloat)Z; 
                           switch (Ploscost) //рисуем разные поверхности в зависимости от значения Ploscost 
                           { 
                           case 0: 
                           return 0; 
                           break; 
                           case 1: 
                           return 0.6*(sin((GLfloat) x/4)*2+2+sin((GLfloat) z/6)*6+6); 
                           break; 

                           case 2: 
                           Y=16-(x-40)*(x-40)-(z-40)*(z-40); 
                           if (Y>0) return Y; 
                           Y=6-((x-20)*(x-20)+(z-26)*(z-26))/2; 
                           if (Y>0) return Y; 
                           Y=2-((x-10)*(x-10)+(z-26)*(z-26))/16; 
                           if (Y>0) return Y; 
                           Y=4-((x-60)*(x-60)+(z-46)*(z-46))/16; 
                           if (Y>0) return Y; 
                           return 0; 
                           break; 
                           default: 
                           return (sin((GLfloat) x*M_PI/40)*16+sin((GLfloat) z*M_PI/40)*16) -32; 
                           } 
                           }; 


                           void reshape (int w, int h) 
                           { 
                           glViewport(0, 0, w, h); 
                           glMatrixMode(GL_PROJECTION); 
                           glLoadIdentity(); 
                           glFrustum(-1.0/13, 1.0/13, -1.0/13, 1.0/13, 1.6/13, 20.0*6); 
                           glMatrixMode(GL_MODELVIEW); 
                           } 

                           void Timef(int it) 
                           { 
                           ugan++; 
                           glutTimerFunc(10,Timef,0); 
                           } 

                           static void Idle(void) 
                           { 
                           glutPostRedisplay(); 
                           } 

                           void keyboard(unsigned char key, int x, int y) 
                           { 
                           switch (key) { 
                           case 'N': 
                           case 'n': 
                           Normals=!Normals; 
                           break; 
                           case 'S': 
                           case 's': 
                           Solid=!Solid; 
                           break; 
                           case 'P': 
                           case 'p': 
                           if (Ploscost<=2) Ploscost++; 
                           else Ploscost=0; 
                           break; 
                           case 'W': 
                           case 'w': 
                           paramW=!paramW; 
                           break; 
                           case '+': 
                           Rast+=0.1; 
                           break; 
                           case '-': 
                           Rast-=0.1; 
                           break; 
                           case 27: 
                           exit(0); 
                           break; 
                           } 
                           } 

                           int main(int argc, char** argv) 
                           { 
                           glutInit(&argc, argv); 
                           glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 
                           glutInitWindowSize(600, 400); 
                           glutInitWindowPosition(0, 0); 
                           glutCreateWindow("Normals"); 
                           initGL(); 

                           glutDisplayFunc(display); 
                           glutReshapeFunc(reshape); 
                           glutKeyboardFunc(keyboard); 
                           glutIdleFunc(Idle); 
                           glutTimerFunc(100,Timef,10); 
                           glutMainLoop(); 
                           return 0; 
                           } 

Anonymous ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.