В общем, нужно отобразить простую геометрическую фигуру в пределах нормализованного объема видимости. Нужно нарисовать пятиугольник с двумя диагоналями, используя геометрические примитивы: треугольник (GL_TRIANGLES) и отрезок (GL_LINES), а также использовать: Команды инициализации: auxInitWindowPosition, auxInitWindowSize, glutInitWindowPosition, glutInitWindowSize. Команды настройки цветов фона и изображения: glClearColor, glClear, glColor. Команды рисования геометрических примитивов: glVertex, glBegin – glEnd. Команды задания стиля вычерчивания: glLineWidth, glEnable(GL_LINE_SMOOTH), glEnable(GL_POINT_SMOOTH).
Документация по OpenGL для Delphi есть? Если нет, то http://www.google.com/search?client=opera&...=utf-8&oe=utf-8 По первой же ссылке какой-то архив есть, я не поверял, но книгу знаю, к ней примеры прилигаются (я эту книгу покупал в бумажном варианте, примеры прилагались на дискете).
Документация по OpenGL для Delphi есть? Если нет, то [ссылка]. По первой же ссылке какой-то архив есть, я не поверял, но книгу знаю, к ней примеры прилигаются (я эту книгу покупал в бумажном варианте, примеры прилагались на дискете).
Спасибо, посмотрю, что там Насчёт документации: до этого не было.
В общем, программу я сделал, только подскажите, пожалуйста, как закрасить полученный пятиугольник, а также немного повернуть его, чтобы он стоял ровно в центре, без наклона. Вот код:
{======================================================================= Перерисовка окна} procedure TfrmGL.FormPaint(Sender: TObject); var i : 0..3; begin wglMakeCurrent(Canvas.Handle, hrc);
glViewPort (0, 0, ClientWidth, ClientHeight); // область вывода
glClearColor (0.75, 0.75, 0.5, 1.0); // определение цвета фона glClear (GL_COLOR_BUFFER_BIT); // очистка буфера цвета
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glColor3f (1.0, 0.0, 0.5); glBegin (GL_TRIANGLE_FAN); glVertex2f (0, 0); For i := 0 to 3 do glVertex2f (0.9 * cos (2 * Pi * i / 5), 0.9 * sin (2 * Pi * i / 5)); glEnd;
SwapBuffers(Canvas.Handle); // содержимое буфера - на экран wglMakeCurrent(0, 0); end;
{======================================================================= Формат пикселя} procedure SetDCPixelFormat (hdc : HDC); var pfd : TPixelFormatDescriptor; nPixelFormat : Integer; begin FillChar (pfd, SizeOf (pfd), 0); pfd.dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER; nPixelFormat := ChoosePixelFormat (hdc, @pfd); SetPixelFormat (hdc, nPixelFormat, @pfd); end;
{======================================================================= Создание формы} procedure TfrmGL.FormCreate(Sender: TObject); begin SetDCPixelFormat(Canvas.Handle); hrc := wglCreateContext(Canvas.Handle); end;
{======================================================================= Конец работы приложения} procedure TfrmGL.FormDestroy(Sender: TObject); begin wglDeleteContext(hrc); end;
glBegin (GL_TRIANGLE_FAN); glVertex2f (0, 0); For i := 0 to 3 do glVertex2f (0.9 * cos (2 * Pi * i / 5), 0.9 * sin (2 * Pi * i / 5)); glEnd;
А почему 4 точки задаются?
glBegin (GL_POLYGON); // как-то так называется константа glVertex2f (0, 0); For i := 0 to 4 do glVertex2f (0.9 * cos (2 * Pi * i / 5), 0.9 * sin (2 * Pi * i / 5)); glEnd;
Просто у меня при задании 4 точек почему-то получается не пятиугольник, а шестиугольник... Насчёт процедуры POLYGONE - почему-то при её задании и вписании (замены TRIANGLE или вписании до/после него) кода, описанного выше, получается такой же результат, что был и до этого...
{======================================================================= Перерисовка окна} procedure TfrmGL.FormPaint(Sender: TObject); var i : 0..3; begin wglMakeCurrent(Canvas.Handle, hrc);
glViewPort (0, 0, ClientWidth, ClientHeight); // область вывода
glClearColor (0.75, 0.75, 0.5, 1.0); // определение цвета фона glClear (GL_COLOR_BUFFER_BIT); // очистка буфера цвета
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glColor3f (1.0, 1.0, 1.0); glBegin (GL_POLYGON); // как-то так называется константа glVertex2f (0, 0); For i := 0 to 3 do glVertex2f (0.9 * cos (2 * Pi * i / 5), 0.9 * sin (2 * Pi * i / 5)); glEnd;
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glColor3f (0.0, 0.0, 0.0); glBegin (GL_TRIANGLE_FAN); glVertex2f (0, 0); For i := 0 to 3 do glVertex2f (0.9 * cos (2 * Pi * i / 5), 0.9 * sin (2 * Pi * i / 5)); glEnd;
SwapBuffers(Canvas.Handle); // содержимое буфера - на экран wglMakeCurrent(0, 0); end;
{======================================================================= Формат пикселя} procedure SetDCPixelFormat (hdc : HDC); var pfd : TPixelFormatDescriptor; nPixelFormat : Integer; begin FillChar (pfd, SizeOf (pfd), 0); pfd.dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER; nPixelFormat := ChoosePixelFormat (hdc, @pfd); SetPixelFormat (hdc, nPixelFormat, @pfd); end;
{======================================================================= Создание формы} procedure TfrmGL.FormCreate(Sender: TObject); begin SetDCPixelFormat(Canvas.Handle); hrc := wglCreateContext(Canvas.Handle); end;
{======================================================================= Конец работы приложения} procedure TfrmGL.FormDestroy(Sender: TObject); begin wglDeleteContext(hrc); end;
glBegin (GL_TRIANGLE_FAN); // glVertex2f (0, 0); это нафиг For i := 0 to 4 do glVertex2f (0.9 * cos (2 * Pi * i / 5), 0.9 * sin (2 * Pi * i / 5)); glEnd;
Да, нулевая вершина в начале нужна, если через fan (я эту команду просто не знаю). Вроде, оптимальнее считается через gl_triangle_strip. Ну в общем, по этой картинке разберись.
{=======================Рисование окна=======================} procedure TForm1.FormPaint(Sender: TObject); // форма рисования const Color:array[1..3] of real=(0.8,0.8,0.8); // набор цветов red_color: array[1..3] of GLfloat=(1,0,0); green_color: array[1..3] of GLfloat=(0,1,0); blue_color: array[1..3] of GLfloat=(0,0,1); black_color: array[1..3] of GLfloat=(0,0,0); begin
wglMakeCurrent(Canvas.Handle, hrc); // прорисовка поля glClearColor(0.9,0.6,0.2,1.0); // цвет фона glClear(GL_COLOR_BUFFER_BIT); // очистка буфера цвета glColor3fv(@Color); glLineWidth(5); // толщина линий glEnable (GL_POINT_SMOOTH); // сглаживание точек glEnable (GL_LINE_SMOOTH); // сглаживание линий
glPolygonMode(GL_Front_and_Back, GL_LINE); glBegin (GL_TRIANGLES); {===== рисуем треугольник слева =====} glColor3f (0.3,0.4,0.7); // цвет линий треугольника glVertex3f (-0.4, 0, 0); // средняя точка, координаты по x, y, z glVertex3f (0, 0.4, 0); // верхняя точка, координаты по x, y, z glVertex3f (-0.3, -0.4, 0); // нижняя точка, координаты по x, y, z {===== рисуем треугольник справа =====} glColor3f (0.3,0.4,0.7); // цвет линий треугольника glVertex3f (0.4, 0, 0); // средняя точка, координаты по x, y, z glVertex3f (0, 0.4, 0); // верхняя точка, координаты по x, y, z glVertex3f (0.3, -0.4, 0); // нижняя точка, координаты по x, y, z {===== рисуем треугольник в центре =====} glColor3f (0.3,0.4,0.7); // цвет линий треугольника glVertex3f (-0.3, -0.4, 0); // средняя точка, координаты по x, y, z glVertex3f (0, 0.4, 0); // верхняя точка, координаты по x, y, z glVertex3f (0.3, -0.4, 0); // нижняя точка, координаты по x, y, z glEnd;
glBegin (GL_LINES); glColor3f (0.8,0.2,0.6); // цвет линии glVertex3f (-0.3, -0.4, 0); // координаты нижней линии по x, y, z glVertex3f (0, 0.4, 0); // координаты верхней линии по x, y, z glColor3f (0.8,0.2,0.6); // цвет линии glVertex3f (0.3, -0.4, 0); // координаты нижней линии по x, y, z glVertex3f (0, 0.4, 0); // координаты верхней линии по x, y, z glEnd;
{==================Конец работы приложения==================} procedure TForm1.FormDestroy(Sender: TObject); begin wglDeleteContext(hrc); end;
end.
Ещё в моём задании указывалось: Задать координату z одной из вершин равной +0.5, затем -0.5. Объяснить наблюдаемый эффект. Задать координату z одной из вершин равной +5, затем -5. Объяснить наблюдаемый эффект.
Помогите, пожалуйста, с выше заданным мною вопросом - т.е. помогите сформулировать ответ.
А какой эффект наблюдается? То, что отсекается часть, вылезающая за плоскость Z=0?
Да, там так получается, но почему-то когда z=2 и более, а что минус, что плюс, всё одинаково отсекается - и отсекается из-за того, что просто выходит за Z или как-то проектируется точка на него, принимая значение координаты Z? И здесь правосторонняя или левосторонняя (я полагаю, что левосторонняя) система координат используется?
> И здесь правосторонняя или левосторонняя (я полагаю, что левосторонняя) система координат используется?
Пока без разницы, это только для односторонних полигонов имеет значение.
> но почему-то когда z=2 и более, а что минус, что плюс, всё одинаково отсекается
Не, отсечка, когда z по модулю больше 1. Просто по умолчанию ближняя плоскость отсечения - z=-1, а дальняя - z=1
А, теперь понятно. Только ещё один вопрос: координата Z, если всё равно какая система координат используется, отсекает части отрезков относительно точки (т.е. у средней точки левого треугольника координата Z будет проходить именно мимо неё и её конкретно заданных других координат) или относительно осей координат X и Y ?
Хорошо, тогда выкладываю картинки. На первой я выделил среднюю точку в левом треугольнике и провёл около неё координату Z, которая после экспериментом с заданием Z=5 отсекла часть треугольника так, как я прочертил белыми стрелками на картинке. На второй, третьей и четвёртой выделил всевозможные оси Z (лево-, право- и многостороннее, хотя как было сказано выше, это только для односторонних полигонов имеет значение), которые расположены относительно осей X и Y, а не точек, как в первом примере.
Кхм... Не пугай меня так. Ось z на этой картинке вообще не видна - она поперёк экрана идёт.
Представь, что мы эту вершину тянем на себя, из экрана прямо на себя, и всё, что дальше, чем на сантиметр от экрана, сгорает. Тогда треугольник, содержащий эту вершину, как раз будет вот так отсекаться.
Белая линия на первой картинке - это не ось z, это просто сечение плоскости, содержащей левый треугольник, плоскостью z=1.
TarasBer, спасибо за помощь! Насчёт 2-й картинки - там косяк - не нарисована линия вообще, а должна идти вниз - в принципе, обычно координата Z так и ставится в системах координат. Кому интересно, вот ответ на вопрос, что будет, если задать Z=5: Если задать координаты z = 5 одной из вершин треугольника (например, верхней вершины левого треугольника), то можно увидеть эффект, обусловленный тем, что точка выходит за границу видимости (проецируется), и часть фигуры при этом отсекается.
Если Z=0...1, то точка находится в границе видимости, и фигура не отсекается при этом.
{=======================Рисование окна=======================} procedure TForm1.FormPaint(Sender: TObject); // форма рисования begin
wglMakeCurrent(Canvas.Handle, hrc); // прорисовка поля glClearColor(0.9,0.6,0.2,1.0); // цвет фона glClear(GL_COLOR_BUFFER_BIT); // очистка буфера цвета glLineWidth(5); // толщина линий glEnable (GL_LINE_SMOOTH); // сглаживание линий
glPolygonMode(GL_Front_and_Back, GL_LINE); glBegin (GL_TRIANGLES); {===== рисуем треугольник слева =====} glColor3f (0.3,0.4,0.7); // цвет линий треугольника glVertex3f (-0.4, 0, 0); // средняя вершина glVertex3f (0, 0.4, 0); // верхняя вершина glVertex3f (-0.3, -0.4, 0); // нижняя вершина {===== рисуем треугольник справа =====} glColor3f (0.3,0.4,0.7); // цвет линий треугольника glVertex3f (0.4, 0, 0); // средняя вершина glVertex3f (0, 0.4, 0); // верхняя вершина glVertex3f (0.3, -0.4, 0); // нижняя вершина {===== рисуем треугольник в центре =====} glColor3f (0.3,0.4,0.7); // цвет линий треугольника glVertex3f (-0.3, -0.4, 0); // средняя вершина glVertex3f (0, 0.4, 0); // верхняя вершина glVertex3f (0.3, -0.4, 0); // нижняя вершина glEnd;
glBegin (GL_LINES); glColor3f (0.8,0.2,0.6); // цвет линии glVertex3f (-0.3, -0.4, 0); // координаты нижней вершины левой линии glVertex3f (0, 0.4, 0); // координаты верхней вершины левой линии glColor3f (0.8,0.2,0.6); // цвет линии glVertex3f (0.3, -0.4, 0); // координаты нижней вершины правой линии glVertex3f (0, 0.4, 0); // координаты верхней вершины правой линии glEnd;
SwapBuffers(Canvas. Handle); // содержимое буфера - на экран
{==================Конец работы приложения==================} procedure TForm1.FormDestroy(Sender: TObject); begin wglDeleteContext(hrc); end;
end.
При этом крайне рекомендуется сделать размер выводимого окна с одинаковым разрешением, например, 600Х600, чтобы координаты ложились на окно соответственно заданным координатам, иначе будет искажения.