Решил изучить OpenGL более тщательно, нашел пример:
#include <gl\glut.h> void Draw() { glClear( GL_COLOR_BUFFER_BIT); glColor3f( 0.0, 1.0, 0.0); glBegin( GL_POINTS); glVertex2f( 0.0, 0.0); glEnd( ); glFlush( );//только для GLUT_SINGLE } void Initialize( ) { glClearColor( 1.0, 0.0, 0.0, 1.0); glMatrixMode( GL_PROJECTION); glLoadIdentity( ); glOrtho( -200.0, 200.0, -200.0, 200.0, -5.0, 5.0); } int main( int argc, char** argv) { //Инициализация glutInit( &argc, argv); glutInitDisplayMode( GLUT_SINGLE|GLUT_RGB); glutInitWindowSize( 400, 400); glutInitWindowPosition( 100, 200); glutCreateWindow( "Lesson 01"); //Регистрация glutDisplayFunc( Draw);//Рисование Initialize( ); glutMainLoop( ); return 0; }
Я не сильно понимаю, в каком порядке вызывается какая функция
Сразу видимо срабатывает main
glutInit(&argc, argv); - Зачем эта строка я так и не понял, ведь по сути в main ничего не передается. Я даже не понял, зачем там параметры. Как я понял, main запускается автоматически.
glutDisplayFunc(Draw);
Эту строку я тоже не понял. Что-то вроде объявления функции рисования. Но я не нашел, где ее запуск происходит.
Подскажите пожалуйста...
GuitarFan
> glutInit(&argc, argv); - Зачем эта строка я так и не понял, ведь по сути в main
> ничего не передается. Я даже не понял, зачем там параметры. Как я понял, main
> запускается автоматически.
main - точка входа в программу, вызывается автоматически при старте приложения.
Затем тебе надо инициализировать OpenGL, для чего и вызывается glutInit.
В нее передаюся параметры вызова программы.
glutDisplayFunc(Draw);
Передает GLUT указатель на функцию рисования.
Внутри glutMainLoop эта функция и вызывается. Если поставить брейкпоинт в Draw посмотреть на стек вызовов, то наверху будет glutMainLoop
GuitarFan
> Решил изучить OpenGL
Не хотелось бы мне показаться троллем, но все-же, видимо ты решил не только OpenGL изучить, а еще и С/С++ от самых их основ. :)
GuitarFan
> int main(int argc, char** argv)
Это еси всия движения основа и исток всех русел - точка входа в твою программу. По окончании инициализации ресурсов программы указатель текущей операции будет перекинут на самое начало main().
GuitarFan
> void Draw()
GuitarFan
> glutDisplayFunc(Draw);
Этой функцией мы делегируем указатель на Draw() внутрь glut.
Если нам хочется вызвать функцию, мы пишем "Draw();". Если нам хочется получить указатель на функцию, то мы пишем "Draw".
glutDisplayFunc принимает указатель на глобальную функцию с методом вызова stdcall и общим видом "void (*func)(void);".
Как видно, в glutDisplayFunc можно скормить любой указатель на функцию процедурного типа и без параметров.
GuitarFan
> glutInit(&argc, argv); - Зачем эта строка я так и не понял
В языках программирования очень часто применяется так называемая техника нинзя-комментариев :) Или еще ее называют техникой автодокументирования.
В результате применения этой техники каждая функция, каждый класс и каждый операнд своим названием декларируют свою суть.
glutInit - [ gl ] - значит что это функция из пространства имен OpenGL (это старый C-шный способ организации своего функционала, банальные префиксы); [ u ] - значит что эта функция из области утилит OpenGL; [ Init ] - значит что эта функция выполняет инициализацию. Инициализацию чего и где - это я уже не смогу сказать. Тут поможет только документация по glut.
Draw() будет непрерывно вызываться изнутри glutMainLoop(), пока окно не будет закрыто. Для обеспечения этого факта и была вызвана glutDisplayFunc(Draw).
Спасибо всем за объяснение. Ситуация теперь более понятна.
У меня есть другой проект, сделанный в MFC, в котором есть функция void CPicture::OnShowPicture() { glClearColor( 0, 0.5, 0.99, 1); GLUquadricObj *quadObj; quadObj = gluNewQuadric( ); // создаем новый Quadric объект gluSphere( quadObj, 0.15, 100, 10); // рисуем сферу glFinish( ); //закончили с OpenGL SwapBuffers( wglGetCurrentDC( )); //вывод рисунка в контекст }
В программе не нашел никаких glInit(), glutMainLoop() и т.д. Только то, что в коде. Как же собственно у меня рисуется все, если у меня нет запуска OpenGL и прочего?
GuitarFan
> Как же собственно у меня рисуется все, если у меня нет запуска OpenGL и
> прочего?
Весь код покажи. Обязательно где-то есть создание контекста OpenGL. И совсем не обязательно, что это glutCreateWindow(). Даже скорее наоборот, глут сейчас это редкость, только в туторах наверное и остался.
Весь код? Ну я писать его не буду, много лишнего, лучше выложу саму программу
Я как бы думал, что в функции CPicture::OnShowPicture() находится весь код, связанный с OpenGL
Моя задача вообще, это сделать более сложную программу в MFC
Я как раз хотел перенести эту программу, о которой я писал в первом посту в MFC, заменив код CPicture::OnShowPicture() на код
//Инициализация glutInit(&argc, argv); glutInitDisplayMode( GLUT_SINGLE|GLUT_RGB); glutInitWindowSize( 400, 400); glutInitWindowPosition( 100, 200); glutCreateWindow( "Lesson 01"); //Регистрация glutDisplayFunc( Draw);//Рисование glClearColor( 1.0, 0.0, 0.0, 1.0); glMatrixMode( GL_PROJECTION); glLoadIdentity( ); glOrtho( -200.0, 200.0, -200.0, 200.0, -5.0, 5.0); glutMainLoop( );
И отдельно добавить функцию
void Draw() { glClear( GL_COLOR_BUFFER_BIT); glColor3f( 0.0, 1.0, 0.0); glBegin( GL_POINTS); glVertex2f( 0.0, 0.0); glEnd( ); glFlush( );//только для GLUT_SINGLE }
Но я слишком слаб в с++, чтобы это сделать правильным образом и с первого раза
Я понял что эта функция Draw() должна непрерывно выполнятся с помощью glutMainLoop();, но зачем - это я кажется не очень понимаю, только догадываюсь.
Вот примерно такой код должен быть
Правка
Это чтобы сферу на си нарисовать такой код подойдет, чё такое MFC я без понятия, мож там по другому как-то надо.
Правка
glClear() в Draw() забыл добавить.
Вы говорили, что OpenGL где-то инициализируется или создается, но где? Без него получается тоже работает...
Я понял что эта функция Draw() должна непрерывно выполнятся с помощью glutMainLoop();, но зачем?
Вы этом первом уроке описывается пример, в котором есть функция main c необходимыми параметрами, которая вызывается автоматически при запуске программы.
А как быть, если я делаю в шаблоне MFC? Я взял полностью идентичный код, но у меня ничего не получается. Без этой функции нельзя обойтись? У меня код OpenGL должен срабатывать при нажатии кнопки, а при нажатии кнопки может выполнятся только функция void. Как быть? Мне не нужно, чтобы main выполнялась автоматически...
Вот инициализация опенгл
//Инициализация
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(400, 400);
glutInitWindowPosition(100, 200);
glutCreateWindow("Lesson 01");
Вот создание контекста
glutCreateWindow("Lesson 01");
Вот этим будем рисовать
glutDisplayFunc(Draw);//Рисование
Цикл отрисовки. Выполняется пока пользователь не прибьет окно. Ну или какая-нибудь гадость не приключится.
glutMainLoop();
GuitarFan
> Я понял что эта функция Draw() должна непрерывно выполнятся с помощью
> glutMainLoop();, но зачем?
Затем, что обычно рисующие приложения рисуют каждый кадр немного по разному. Потом у нас с окном могут происходить разные вещи, типа ресайза, перекрытия другими окнами, окно получает сообщения различные, эти сообщения надо обрабатывать в цикле. glutMainLoop() и есть такой цикл.
GuitarFan
> Мне не нужно, чтобы main выполнялась автоматически...
Ну не пиши ее раз не нужно.
youtube, вы не так поняли на счет инциализации. Я спрашивал где она в той программе, что я ссылку на нее кидал. Ведь там этой инициализации нет и OpenGL работает.
Ну не пиши ее раз не нужно.
То есть я могу запустить свой код без фунции main? Ну ок, а как же тогда будет запускаться glutInit? Ведь параметров в ней не будет, по скольку в этой программе они передаются автоматически в функцию main, а если у меня не будет этой функции - то и параметры передаваться не будут, видимо.
GuitarFan
> То есть я могу запустить свой код без фунции main? Ну ок, а как же тогда будет
> запускаться glutInit?
char *str="progname"; int argc=1; char **argv; *argv=str; glutInit(&argc, argv);
GuitarFan
> youtube, вы не так поняли на счет инциализации. Я спрашивал где она в той
> программе, что я ссылку на нее кидал. Ведь там этой инициализации нет и OpenGL
> работает.
Чего-то не вижу ссылку.
Инициализация обязана быть. Иначе работать не будет. Показывай весь код - тебе покажут где инициализация.
Файл Picture.cpp
... bool CPicture::Init3d() { CMainFrame* pp = ( CMainFrame*)some; int pixelformat; pixelformat = ChoosePixelFormat( GetDC( )->GetSafeHdc( ),&( pp->pixel));//система выбирает подходящий формат пикселей SetPixelFormat( GetDC( )->GetSafeHdc( ), pixelformat, &( pp->pixel));//устанавливаем формат пискелей wglMakeCurrent( GetDC( )->GetSafeHdc( ), wglCreateContext( GetDC( )->GetSafeHdc( )));//создаём и присваиваем контекст return true; } ...
Вот там инициализируется. Только без глута. Прямые вызовы wgl*().
Правка:
Вообще ты не оттуда начал опенгл изучать.
Начинай отсюда http://nehe.gamedev.net/tutorial/lessons_01__05/22004/
Нафиг вообще этот глут нужен? Уроки которые я изучаю с глутом, другие мне пишут что глут с MFC не работает. В чем разница между глутом и остальным?
GuitarFan
> Нафиг вообще этот глут нужен?
Например создание контекста OpenGL в Windows выглядит так: wglCreateContext(), в X Window System - glxCreateContext(), в OpenGL ES - eglCreateContext(). А до этого обычно создают окно, в котором будет отрисовываться этот контекст. В каждой системе окна создаются с помощью разных вызовов, они нигде не совпадают, у всех функций инициализации разные параметры. Глут брал всю эту работу на себя. Т.е. тебе было достаточно написать glutCreateWindow, и использовать дальше команды опенгл. И работало это на любой системе. Сейчас тоже есть библиотеки, которые заменяют глут.
Тема в архиве.