OpenGL
Я имею к вам простой и, возможно, глупый вопрос, но он мне не даёт уже очень долго покоя.
Объясняю в чём моя проблема.
Надо отобразить что-нибудь на форме с помощью OpenGL, например белый квадрат на чёрном фоне... Меня многие гугают за этот
тупой вопрос, велят почитать дельные книжки по OpenGL... НО! Я читал! И неодну! Но во всех написано как подобное сделать,
используя GLUT, и т. п. Я же хочу это сделать лишь используя C++ Builder6 и WindowsXP, а использование каких-либо иных библиотек
типа глута я считаю нерациональным, загромождающим программу. Программист должен хорошо овладеть работой с OpenGL, а не
заниматься изучением каких-то ещё дополнительных надстроек.
Я видел, что борландовские умельцы сделали для всех примеры статического отображения и анимации посредством OpenGL,
но я несмог толком разобраться с их примером, поэтому прошу вас помочь мне. Для начала хватит и статического отображения
графики.
Я слышал, что каким-то образом надо указать OpenGL'y, что он должен выводить графику на канву нужной мне формы, или чего-то
химичить с handle'ми, или короче что-то вроде того...
Короче, помогите, уважаемые кодеры, тем более что мне ещё пока только 15 лет...
ПОМОГИТЕ!!!
DC = GetDC (Handle);//Получаем контекст изображения окна(функция WinAPI)
FillChar (&pfd, SizeOf (pfd), 0);
//Заполняем формат пикселя
pfd.nSize=SizeOf (TPixelFormatDescriptor);//Размер структуры
pfd.nVersion=1;//Версия
pfd.dwFlags = PFD_DRAW_TO_WINDOW || PFD_SUPPORT_OPENGL || PFD_DOUBLEBUFFER;
pfd.iPixelType=PFD_TYPE_RGBA;//Тип пикселя(значения составляющих цветов)
pfd.cColorBits=24;//Битов на цвет
pfd.cDepthBits=32;//Глубина z-буфера
pfd.iLayerType=PFD_MAIN_PLANE;//
nPixelFormat = ChoosePixelFormat(DC,&pfd);//Выбираем индекс формата пикселя, лучше всего соответсивующего заполненной нами структурке
SetPixelFormat (DC, nPixelFormat, &pfd);//Устанавливаем формат пикселя
hrc = wglCreateContext(DC);//Создаем OpenGL КОНТЕКСТ отоБРАЖЕНИЯ
wglMakeCurrent(DC, hrc);//Активизируем его
glClearColor (0.9,0.9,0.9,1);// цвет фона
в FormDestroy:
//Пры выходе
wglMakeCurrent(0, 0);//
wglDeleteContext(hrc);//Убиваем контекст OpenGL
ReleaseDC (Handle,DC);//освобождаем контекст устройства
в FormResize:
w:=ClientWidth;
h:=ClientHeight;
if h=0 then h:=1;
if w=0 then w:=1;
if w>h then
glViewPort(round(w/2-h/2),0,h,h)//новое окно отбражения отображения
else
glViewPort(0,round(h/2-w/2),w,w);
//glViewPort(0,round(h/2-w/2),0,0);
glMatrixMode(GL_PROJECTION);//
glLoadIdentity;//Перобразование - идентичное
n:=100;
{if w<=h then glOrtho(-n,n,-n*h/w,n*h/w,-n,n)
else glOrtho(-n*h/w,n*h/w,-n,n,-n,n) ;}
glOrtho(-n,n,-n,n,-n,n);//Умножаем матрицу преобразования на ортографическую
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
Римование:
glBegin(GL_POLYGON);
glVertex(0,0,0);
glVertex(50,0,0);
glVertex(50,50,0);
glVertex(0,50,0);
glEnd;
Примерно так.
Впихни в FormCreate вот что:
DC = GetDC (Handle);//Получаем контекст изображения окна(функция WinAPI)
FillChar (&pfd, SizeOf (pfd), 0);
//Заполняем формат пикселя
pfd.nSize=SizeOf (TPixelFormatDescriptor);//Размер структуры
pfd.nVersion=1;//Версия
pfd.dwFlags = PFD_DRAW_TO_WINDOW || PFD_SUPPORT_OPENGL || PFD_DOUBLEBUFFER;
pfd.iPixelType=PFD_TYPE_RGBA;//Тип пикселя(значения составляющих цветов)
pfd.cColorBits=24;//Битов на цвет
pfd.cDepthBits=32;//Глубина z-буфера
pfd.iLayerType=PFD_MAIN_PLANE;//
nPixelFormat = ChoosePixelFormat(DC,&pfd);//Выбираем индекс формата пикселя, лучше всего соответсивующего заполненной нами структурке
SetPixelFormat (DC, nPixelFormat, &pfd);//Устанавливаем формат пикселя
hrc = wglCreateContext(DC);//Создаем OpenGL КОНТЕКСТ отоБРАЖЕНИЯ
wglMakeCurrent(DC, hrc);//Активизируем его
glClearColor (0.9,0.9,0.9,1);// цвет фона
в FormDestroy:
//Пры выходе
wglMakeCurrent(0, 0);//
wglDeleteContext(hrc);//Убиваем контекст OpenGL
ReleaseDC (Handle,DC);//освобождаем контекст устройства
в FormResize:
w:=ClientWidth;
h:=ClientHeight;
if h=0 then h:=1;
if w=0 then w:=1;
if w>h then
glViewPort(round(w/2-h/2),0,h,h)//новое окно отбражения отображения
else
glViewPort(0,round(h/2-w/2),w,w);
//glViewPort(0,round(h/2-w/2),0,0);
glMatrixMode(GL_PROJECTION);//
glLoadIdentity;//Перобразование - идентичное
n:=100;
{if w<=h then glOrtho(-n,n,-n*h/w,n*h/w,-n,n)
else glOrtho(-n*h/w,n*h/w,-n,n,-n,n) ;}
glOrtho(-n,n,-n,n,-n,n);//Умножаем матрицу преобразования на ортографическую
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
Римование:
glBegin(GL_POLYGON);
glVertex(0,0,0);
glVertex(50,0,0);
glVertex(50,50,0);
glVertex(0,50,0);
glEnd;
Примерно так.
Тока щас увидал ответ на мой вопрос - буду пробовать. А пока спасибо. Большое. Вот.
Тока щас увидал ответ на мой вопрос - буду пробовать. А пока спасибо. Большое. Вот.
Вот такая ботва, приятель! Давай помога! Смотри файл мой!
Вот такая ботва, приятель! Давай помога! Смотри файл мой!
Во первых не забудь про onDestroy:
//Пры выходе
wglMakeCurrent(0, 0);//
wglDeleteContext(hrc);//Убиваем контекст OpenGL
ReleaseDC (Handle,DC);//освобождаем контекст устройства
Работать то будет и без этого, но может сглючить.
Во вторых, надо же и рисовать чего нибудь.
Лучше всего сделать отдельную процедурку DrawObject, и вызывать ее при каждой пререрисовке
так:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//очиска экрана
DrawObject();//Рисование
glFlush();//Спихиваем на экран из буфера
SwapBuffers(DC);
Внутре у нея примерно так:
void Form1.DrawObject()
{
glcolor3d(1.,1.,0.);
glBegin(GL_LINE_STRIP);
glVertex(-100,-50,0);
glVertex(100,-50,0);
glVertex(0,50,0);
glVertex(-100,-50,0);
glEnd;
}
//Должон быть треугольник
Примечание: как показывает практика, рисовать в FormCreate он почемуто не любит, поэтому можно присобачить таймер, в котором ты будешы вызывать
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//очиска экрана
DrawObject();//Рисование
glFlush();//Спихиваем на экран из буфера
SwapBuffers(DC);
Во первых не забудь про onDestroy:
//Пры выходе
wglMakeCurrent(0, 0);//
wglDeleteContext(hrc);//Убиваем контекст OpenGL
ReleaseDC (Handle,DC);//освобождаем контекст устройства
Работать то будет и без этого, но может сглючить.
Во вторых, надо же и рисовать чего нибудь.
Лучше всего сделать отдельную процедурку DrawObject, и вызывать ее при каждой пререрисовке
так:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//очиска экрана
DrawObject();//Рисование
glFlush();//Спихиваем на экран из буфера
SwapBuffers(DC);
Внутре у нея примерно так:
void Form1.DrawObject()
{
glcolor3d(1.,1.,0.);
glBegin(GL_LINE_STRIP);
glVertex(-100,-50,0);
glVertex(100,-50,0);
glVertex(0,50,0);
glVertex(-100,-50,0);
glEnd;
}
//Должон быть треугольник
Примечание: как показывает практика, рисовать в FormCreate он почемуто не любит, поэтому можно присобачить таймер, в котором ты будешы вызывать
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//очиска экрана
DrawObject();//Рисование
glFlush();//Спихиваем на экран из буфера
SwapBuffers(DC);
Спасибо! Буду пробовать!
Спасибо! Буду пробовать!
Не мог бы ты сдклать мне готовый пример? Очень тебя прошу!
Всё сделал, как ты велел, но нифига не получилось - форма осталась такая, кк и была,
ничего на ней не нарисовалось. Очень тебя прошу, помоги!
А я тебе даже подарю GUI для утилиты ImpLib(сам делал - для тебя специально старался!)...
Выручай, друг!