IPB
ЛогинПароль:

> ВНИМАНИЕ!

Прежде чем задать вопрос, смотрите FAQ.
Рекомендуем загрузить DRKB.

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

 
 Ответить  Открыть новую тему 
> Система координат и примитивы OpenGL
сообщение
Сообщение #1


Новичок
*

Группа: Пользователи
Сообщений: 48
Пол: Мужской

Репутация: -  0  +


В общем, нужно отобразить простую геометрическую фигуру в пределах нормализованного объема видимости.
Нужно нарисовать пятиугольник с двумя диагоналями, используя геометрические примитивы: треугольник (GL_TRIANGLES) и отрезок (GL_LINES), а также использовать:
Команды инициализации:
auxInitWindowPosition, auxInitWindowSize, glutInitWindowPosition, glutInitWindowSize.
Команды настройки цветов фона и изображения: glClearColor, glClear, glColor.
Команды рисования геометрических примитивов: glVertex, glBegin – glEnd.
Команды задания стиля вычерчивания: glLineWidth, glEnable(GL_LINE_SMOOTH), glEnable(GL_POINT_SMOOTH).
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Документация по OpenGL для Delphi есть?
Если нет, то http://www.google.com/search?client=opera&...=utf-8&oe=utf-8
По первой же ссылке какой-то архив есть, я не поверял, но книгу знаю, к ней примеры прилигаются (я эту книгу покупал в бумажном варианте, примеры прилагались на дискете).


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Новичок
*

Группа: Пользователи
Сообщений: 48
Пол: Мужской

Репутация: -  0  +


Цитата(TarasBer @ 14.10.2010 16:33) *

Документация по OpenGL для Delphi есть?
Если нет, то [ссылка].
По первой же ссылке какой-то архив есть, я не поверял, но книгу знаю, к ней примеры прилигаются (я эту книгу покупал в бумажном варианте, примеры прилагались на дискете).

Спасибо, посмотрю, что там smile.gif
Насчёт документации: до этого не было.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Новичок
*

Группа: Пользователи
Сообщений: 48
Пол: Мужской

Репутация: -  0  +


В общем, программу я сделал, только подскажите, пожалуйста, как закрасить полученный пятиугольник, а также немного повернуть его, чтобы он стоял ровно в центре, без наклона.
Вот код:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
OpenGL;

type
TfrmGL = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormDestroy(Sender: TObject);

private
hrc: HGLRC;
end;

var
frmGL: TfrmGL;

implementation

{$R *.DFM}

{=======================================================================
Перерисовка окна}
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;

end.

 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +



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;





--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Новичок
*

Группа: Пользователи
Сообщений: 48
Пол: Мужской

Репутация: -  0  +


Цитата(TarasBer @ 20.10.2010 10:34) *

А почему 4 точки задаются?

Просто у меня при задании 4 точек почему-то получается не пятиугольник, а шестиугольник...
Насчёт процедуры POLYGONE - почему-то при её задании и вписании (замены TRIANGLE или вписании до/после него) кода, описанного выше, получается такой же результат, что был и до этого...
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Новичок
*

Группа: Пользователи
Сообщений: 48
Пол: Мужской

Репутация: -  0  +


Ну вот, что-то сделал вроде этого, получилось вроде (используя при этом Polygon): smile.gif
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
OpenGL;

type
TfrmGL = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormDestroy(Sender: TObject);

private
hrc: HGLRC;
end;

var
frmGL: TfrmGL;

implementation

{$R *.DFM}

{=======================================================================
Перерисовка окна}
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;

end.

 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


А, я проглядел лишнее glVertex2f (0, 0);


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;



--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Изображение

Да, нулевая вершина в начале нужна, если через fan (я эту команду просто не знаю).
Вроде, оптимальнее считается через gl_triangle_strip. Ну в общем, по этой картинке разберись.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Новичок
*

Группа: Пользователи
Сообщений: 48
Пол: Мужской

Репутация: -  0  +


TarasBer, спасибо за помощь!
Вот я нарисовал этот пятиугольник с двумя диагоналями:
unit Unit1;
interface

uses
Windows, Messages, Forms, Dialogs, Classes, Controls, ExtCtrls, StdCtrls,
OpenGL;

type
TForm1 = class(TForm)
procedure FormPaint(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);

private
hrc: HGLRC;
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

{=======================Рисование окна=======================}
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;

wglMakeCurrent (0, 0);
end;

{=======================Формат пикселя=======================}
procedure SetDCPixelFormat (hdc : HDC);
var
pfd : TPIXELFORMATDESCRIPTOR;
nPixelFormat : Integer;
begin
FillChar(pfd, SizeOf(pfd), 0);
nPixelFormat := ChoosePixelFormat (hdc, @pfd);
SetPixelFormat (hdc, nPixelFormat, @pfd);
end;

{=======================Создание формы=======================}
procedure TForm1.FormCreate(Sender: TObject);
begin
SetDCPixelFormat(Canvas.Handle);
hrc := wglCreateContext(Canvas.Handle);
end;

{==================Конец работы приложения==================}
procedure TForm1.FormDestroy(Sender: TObject);
begin
wglDeleteContext(hrc);
end;

end.



Ещё в моём задании указывалось:
Задать координату z одной из вершин равной +0.5, затем -0.5. Объяснить наблюдаемый эффект. Задать координату z одной из вершин равной +5, затем -5. Объяснить наблюдаемый эффект.

Помогите, пожалуйста, с выше заданным мною вопросом - т.е. помогите сформулировать ответ.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


А какой эффект наблюдается? То, что отсекается часть, вылезающая за плоскость Z=0?


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Новичок
*

Группа: Пользователи
Сообщений: 48
Пол: Мужской

Репутация: -  0  +


Цитата(TarasBer @ 4.11.2010 22:38) *

А какой эффект наблюдается? То, что отсекается часть, вылезающая за плоскость Z=0?

Да, там так получается, но почему-то когда z=2 и более, а что минус, что плюс, всё одинаково отсекается - и отсекается из-за того, что просто выходит за Z или как-то проектируется точка на него, принимая значение координаты Z?
И здесь правосторонняя или левосторонняя (я полагаю, что левосторонняя) система координат используется?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


> И здесь правосторонняя или левосторонняя (я полагаю, что левосторонняя) система координат используется?

Пока без разницы, это только для односторонних полигонов имеет значение.

> но почему-то когда z=2 и более, а что минус, что плюс, всё одинаково отсекается

Не, отсечка, когда z по модулю больше 1.
Просто по умолчанию ближняя плоскость отсечения - z=-1, а дальняя - z=1


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Новичок
*

Группа: Пользователи
Сообщений: 48
Пол: Мужской

Репутация: -  0  +


Цитата(TarasBer @ 4.11.2010 22:59) *

> И здесь правосторонняя или левосторонняя (я полагаю, что левосторонняя) система координат используется?

Пока без разницы, это только для односторонних полигонов имеет значение.

> но почему-то когда z=2 и более, а что минус, что плюс, всё одинаково отсекается

Не, отсечка, когда z по модулю больше 1.
Просто по умолчанию ближняя плоскость отсечения - z=-1, а дальняя - z=1

А, теперь понятно. Только ещё один вопрос: координата Z, если всё равно какая система координат используется, отсекает части отрезков относительно точки (т.е. у средней точки левого треугольника координата Z будет проходить именно мимо неё и её конкретно заданных других координат) или относительно осей координат X и Y ?

Сообщение отредактировано: mitz -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Ничего не понял. Повтори вопрос с картинками.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


Новичок
*

Группа: Пользователи
Сообщений: 48
Пол: Мужской

Репутация: -  0  +


Цитата(TarasBer @ 5.11.2010 0:29) *

Ничего не понял. Повтори вопрос с картинками.

Хорошо, тогда выкладываю картинки.
На первой я выделил среднюю точку в левом треугольнике и провёл около неё координату Z, которая после экспериментом с заданием Z=5 отсекла часть треугольника так, как я прочертил белыми стрелками на картинке.
На второй, третьей и четвёртой выделил всевозможные оси Z (лево-, право- и многостороннее, хотя как было сказано выше, это только для односторонних полигонов имеет значение), которые расположены относительно осей X и Y, а не точек, как в первом примере.


Эскизы прикрепленных изображений
Прикрепленное изображение Прикрепленное изображение Прикрепленное изображение Прикрепленное изображение
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Кхм... Не пугай меня так.
Ось z на этой картинке вообще не видна - она поперёк экрана идёт.

Представь, что мы эту вершину тянем на себя, из экрана прямо на себя, и всё, что дальше, чем на сантиметр от экрана, сгорает. Тогда треугольник, содержащий эту вершину, как раз будет вот так отсекаться.

Белая линия на первой картинке - это не ось z, это просто сечение плоскости, содержащей левый треугольник, плоскостью z=1.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #18


Новичок
*

Группа: Пользователи
Сообщений: 48
Пол: Мужской

Репутация: -  0  +


TarasBer,
спасибо за помощь!
Насчёт 2-й картинки - там косяк - не нарисована линия вообще, а должна идти вниз - в принципе, обычно координата Z так и ставится в системах координат.
Кому интересно, вот ответ на вопрос, что будет, если задать Z=5:
Если задать координаты z = 5 одной из вершин треугольника (например, верхней вершины левого треугольника), то можно увидеть эффект, обусловленный тем, что точка выходит за границу видимости (проецируется), и часть фигуры при этом отсекается.

Если Z=0...1, то точка находится в границе видимости, и фигура не отсекается при этом.

З.Ы. Программный код задачки на Delphi:

unit Unit1;
interface

uses
Windows, Messages, Forms, Dialogs, Classes, Controls, ExtCtrls, StdCtrls,
OpenGL;

type
TForm1 = class(TForm)
procedure FormPaint(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);

private
hrc: HGLRC;
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

{=======================Рисование окна=======================}
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); // содержимое буфера - на экран

end;

{=======================Формат пикселя=======================}
procedure SetDCPixelFormat (hdc : HDC);
var
pfd : TPIXELFORMATDESCRIPTOR;
nPixelFormat : Integer;
begin
FillChar(pfd, SizeOf(pfd), 0);
nPixelFormat := ChoosePixelFormat (hdc, @pfd);
SetPixelFormat (hdc, nPixelFormat, @pfd);
end;

{=======================Создание формы=======================}
procedure TForm1.FormCreate(Sender: TObject);
begin
SetDCPixelFormat(Canvas.Handle);
hrc := wglCreateContext(Canvas.Handle);
end;

{==================Конец работы приложения==================}
procedure TForm1.FormDestroy(Sender: TObject);
begin
wglDeleteContext(hrc);
end;

end.


При этом крайне рекомендуется сделать размер выводимого окна с одинаковым разрешением, например, 600Х600, чтобы координаты ложились на окно соответственно заданным координатам, иначе будет искажения.

Сообщение отредактировано: mitz -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 21.12.2024 19:32
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name