Отправлено: 09.01.10 18:21. Заголовок: Управление камерой OpenGL
Скажите, пожалуйста! Как можно код разделить на разные файлы, так что бы инициализация OpenGL была в одном “ini.cpp” файле а, загрузка или создание и вывод какова ни будь объекта в фтором “obyekt.cpp” а управление описывалось бы им в третьем и т.д. Можно ссылку на статью или книгу где это описывается. За ранее огромное спасибо!
Пост N: 18
Зарегистрирован: 10.05.07
Откуда: Россия, Казань
Рейтинг:
0
Отправлено: 09.01.10 18:42. Заголовок: Для этого есть загол..
Для этого есть заголовочные файлы(.h), в которых описываются прототипы функций, определения инлайн функций, описание классов и структур, определение новых типов, макросы и т.д. и т.п. Эти файлы инклудятся в основной файл либо иной другой (.cpp). Причём название заголовочного файла должно совпадать с названием исходного файла, с ккоторому он относится ( определение функций, прототипы которых находятся в заголовочном, и т.д и т.п.)
Пост N: 80
Зарегистрирован: 14.06.07
Откуда: РОССИЯ, Санкт-Петербург (Екатиренбург)
Рейтинг:
0
Отправлено: 10.01.10 11:53. Заголовок: ИМХО, Ламот - это уж..
ИМХО, Ламот - это уже совсем не то. Для того чтоб такие простые вещи понять я всем советую Лафоре, еще Липмана можно почитать. У Ламота такой жуткий стиль программирования - что аж зубы сводит. Но как теорию по визуализации для начинающих - вполне...
Пост N: 21
Зарегистрирован: 10.05.07
Откуда: Россия, Казань
Рейтинг:
0
Отправлено: 23.01.10 10:07. Заголовок: попробуй создать доч..
попробуй создать дочерние окна, с соответствующими стилями и на каждый свой девайс. Я давно конечно не работал уже с этим. И правда с опен жл не работал, но думаю там щас всё схоже с директх. Надеюсь суть понятна
Отправлено: 08.02.10 14:09. Заголовок: Переменная для имени текстуры
Подскажите, пожалуйста, как можно место phong3.bmp вставить переменную teks, что бы можно её было бы вводить texturer(a, teks); a = номер текстуры teks = имя текстуры texturer(1, phong3.bmp); texturer(2, phong7.bmp); итд.
char strPattern[] = "phongN.bmp"; for(int i=0; i<MAX_PHONG_NUM_0_9; i++) { strPattern[6] = i+0x30; // 'N' <- i+'0' texturer(i, strPattern); } Число одноимённых текстур в данном случаи 10 (0-9). Ну можно конечно и больше сделать. Есть воля для фантазий :)
Скажите, пожалуйста, почему вместе с объектом (кубом) вращается свет? Как можно сделать, что бы свет был независим от объекта? И в данном примере светил прямо на объект, а не периодически пропадал! За ранее огромное спасибо :)
#include <windows.h> #include <GL/gl.h> // Наша OpenGL библиотека #include <GL/glu.h> // Библиотека утилит OpenGL #include <GL/glaux.h> // И еще одна, с ее помощью можно рисовать стандартрые обьекты(сферы, кубы, и др.)
#pragma comment (lib, "OpenGL32.lib")
static GLint resW = 800, resH = 600; // Размер окна bool isFullscr = false; // Полноэкранный режим (по умолчанию - нет)
static GLdouble cntr; // Счетчик. Отвечает за вращение шарика BOOL keys[256]; // Массив для процедуры обработки клавиатуры
HGLRC hGLRC; // Контекст рендеринга OpenGL HDC hDC; // Контекст устройства Windows
GLvoid InitGL() // Вызвать после создания окна GL {
glClearColor (0.3f, 0.3f, 0.3f, 0.0f); //цвет фона // двухсторонний расчет освещения glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); // автоматическое приведение нормалей к единичной длине
LRESULT CALLBACK WindowFunc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { RECT Screen;
GLuint PixelFormat; static PIXELFORMATDESCRIPTOR pfd= { sizeof(PIXELFORMATDESCRIPTOR), //Размер структуры 1, // Номер версии PFD_DRAW_TO_WINDOW | // Рисовать будем в окно PFD_SUPPORT_OPENGL | // Установим поддержку OpenGL PFD_DOUBLEBUFFER, // Выберем двойной буфер PFD_TYPE_RGBA, // Режим цветности - RGBA 32, // Выберем 32 битную глубину цвета 0, 0, 0, 0, 0, 0, // Игнорирование цветовых битов 0, // Нет буфера прозрачности 0, // Игнорируем сдвиговый бит 0,//---------------------// Нет буфера аккумуляции 1, 1, 1, 1, // Биты аккумуляции игнорируются 32, // 32 битный Z-буфер (буфер глубины) 0, // Нет буфера траффарета 0, // Нет вспомогательных буферов PFD_MAIN_PLANE, // Рисовать в главный слой рисования 0, // Резерв 0, 0, 0 // Маски слоя игнорируются };
switch(message) { // сообщение WM_CREATE приходит // один раз при создании окна case WM_CREATE: hDC = GetDC(hWnd); // Получить контекст устройства для окна
PixelFormat = ChoosePixelFormat(hDC, &pfd);// Найти ближайшее совпадение для нашего формата пикселов if (!PixelFormat) // Если неудалось то... { // Выводим сообщение об ошибке MessageBox (0, "Не удается найти подходящий PixelFormat!", "Error", MB_OK | MB_ICONERROR); SendMessage(hWnd, WM_DESTROY, wParam, lParam);// Это сообщение говорит, что программа должна завершится break; //Предотвращение повтора кода }
SetPixelFormat (hDC, PixelFormat, &pfd); // Теперь нкжно установить наш формата пикселов if (!SetPixelFormat (hDC, PixelFormat, &pfd)) // Если неудалось то... { // Выводим сообщение об ошибке MessageBox (0, "Не удается установить PixelFormat!", "Ошибка!!!", MB_OK | MB_ICONERROR); // Уничтожаем окно! SendMessage(hWnd, WM_DESTROY, wParam, lParam); break; }
hGLRC = wglCreateContext (hDC); //Захватывает Контекст Рендеринга и сохраняет его в переменной hGLRC if (!hGLRC) // Захватить не удалось... { // Выводим сообщение об ошибке MessageBox (0, "Не удается создать контекст рендеринга OpenGL!", "Ошибка!!!", MB_OK | MB_ICONERROR); // Уничтожаем окно! SendMessage(hWnd, WM_DESTROY, wParam, lParam); break; }
// это сообщение приходит при уничтожении окна case WM_DESTROY: //Уничтожает окно case WM_CLOSE: //-|-|-|-|-|-|- ChangeDisplaySettings (NULL, 0);//Восстанавливает первоначальное разрешение if(hDC) wglMakeCurrent(hDC, NULL); // Освобождаем контекст рендеринга... if(hGLRC) wglDeleteContext(hGLRC); // ...и удаляем его if(hWnd) ReleaseDC(hWnd, hDC); // Рвем с ним всякие связи. PostQuitMessage(0); // Убиваем окно! break;
case WM_SIZE: GetClientRect (hWnd, &Screen);//Создает область рисования и возвращает высоту и ширину окна reshape(Screen.right, Screen.bottom ); break;
case WM_SYSKEYDOWN: case WM_KEYDOWN: //Если клавиша нажата то... keys[wParam] = TRUE; //В масив keys[key number] заносится TRUE break;
case WM_SYSKEYUP: case WM_KEYUP: //Если клавиша отпущена то... keys[wParam] = FALSE; //В масив keys[key number] заносится FALSE break;
default: // Реакция на все осталные сообщения ОС... return DefWindowProc(hWnd,message,wParam,lParam); // ...по умолчанию } // если гдето чтото не так... return 0; // ...возвращаем ошибку }
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR str,int nWinMode) { MSG msg;//Структура сообщения Windows WNDCLASS wc; //Структура класса Windows для установки типа окна HWND hWnd;//Сохранение дескриптора окна
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Стиль нашего окна wc.lpfnWndProc = WindowFunc; // Определяем ф-цию ответственную за обработку сообщений ОС wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = NULL; // иконка нашего окошка (по умолчанию) wc.hCursor = LoadCursor (NULL, IDC_ARROW); // Курсор который будет отображаться при наведении на наше окошко (стрелка) wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = "OpenGLWinClass"; // Определяем название класса окна
if (!RegisterClass(&wc)) // Если класс зарегистрировать не удалось... { MessageBox(0, "Ошибка при регистрации класса окна!","Ошибка!!!", MB_OK | MB_ICONERROR); return FALSE; }
if(isFullscr) // Если режим полноэкранный - создаем окно с соответствующими параметрами { // создаем окно hWnd = CreateWindow( "OpenGLWinClass", // название класса окна "УРОК 01 >OpenGL is COOL", // Заголовок окна WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, // Стиль (вид) окна 0, 0, resW, resH, // Размеры окна NULL, NULL, hInstance, NULL); } else // Иначе утанавливаем наше окошко, его вид и свойства { // создаем окно hWnd = CreateWindow( "OpenGLWinClass", // название класса окна "Игра №1 версия 1.0", // Заголовок окна WS_OVERLAPPEDWINDOW | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE | WS_SIZEBOX, // Стиль (вид) окна 0, 0, resW, resH, // Размеры окна NULL, NULL, hInstance, NULL); }
if (!hWnd) // если создать окно не удалось { MessageBox(0, "Ошибка при создании окна!","Ошибка!!!", MB_OK | MB_ICONERROR); return FALSE; }
if(isFullscr) { DEVMODE dmScreenSettings; // Режим работы устройства (видио платы) memset (&dmScreenSettings, 0, sizeof(DEVMODE));// Очистка для хранения установок dmScreenSettings.dmSize = sizeof(DEVMODE); // Размер структуры Devmode dmScreenSettings.dmPelsWidth = resW; // Ширина экрана dmScreenSettings.dmPelsHeight = resH; // Высота экрана dmScreenSettings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;// Режим Пиксела ChangeDisplaySettings (&dmScreenSettings, CDS_FULLSCREEN);// Переключение в полный экран } //else ChangeDisplaySettings (&dmScreenSettings, CDS_GLOBAL);
Во-первых, ОпенЖЛ никогда не пользовался. Во-вторых, когда я врубил твою демку куб вращался так что я даже не понял что там :) - добавил ограничение числа кадров 30 к/с. В-третьих я так посмотрел без запуска вроде всё норм было, однако предположил, что когда ты задаёшь матрицы вращения и перемещения ты воздействуешь и на вектор света, так и оказалось, так что я перенёс установку вектора света в область кода отрисовки и всё норм. Библиотеки и хидера glaux у меня нету. Скорее всего glTranslatef(0, 0, -10); glRotated(vv, 0.0f, 1.0f, 1.0f); мы задаем положение камеры, так как я в коде не увидел задание матрицы Камеры.
#include <windows.h> #include <GL/gl.h> // Наша OpenGL библиотека #include <GL/glu.h> // Библиотека утилит OpenGL //#include <GL/glaux.h> // И еще одна, с ее помощью можно рисовать стандартрые обьекты(сферы, кубы, и др.) #include <MMSystem.h>// Узнать время прошедшее с запуска Винды в миллисекундах //#pragma comment (lib, "OpenGL32.lib")
static GLint resW = 800, resH = 600; // Размер окна bool isFullscr = false; // Полноэкранный режим (по умолчанию - нет)
static GLdouble cntr; // Счетчик. Отвечает за вращение шарика BOOL keys[256]; // Массив для процедуры обработки клавиатуры
HGLRC hGLRC; // Контекст рендеринга OpenGL HDC hDC; // Контекст устройства Windows
LRESULT CALLBACK WindowFunc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { RECT Screen;
GLuint PixelFormat; static PIXELFORMATDESCRIPTOR pfd= { sizeof(PIXELFORMATDESCRIPTOR), //Размер структуры 1, // Номер версии PFD_DRAW_TO_WINDOW | // Рисовать будем в окно PFD_SUPPORT_OPENGL | // Установим поддержку OpenGL PFD_DOUBLEBUFFER, // Выберем двойной буфер PFD_TYPE_RGBA, // Режим цветности - RGBA 32, // Выберем 32 битную глубину цвета 0, 0, 0, 0, 0, 0, // Игнорирование цветовых битов 0, // Нет буфера прозрачности 0, // Игнорируем сдвиговый бит 0,//---------------------// Нет буфера аккумуляции 1, 1, 1, 1, // Биты аккумуляции игнорируются 32, // 32 битный Z-буфер (буфер глубины) 0, // Нет буфера траффарета 0, // Нет вспомогательных буферов PFD_MAIN_PLANE, // Рисовать в главный слой рисования 0, // Резерв 0, 0, 0 // Маски слоя игнорируются };
switch(message) { // сообщение WM_CREATE приходит // один раз при создании окна case WM_CREATE: hDC = GetDC(hWnd); // Получить контекст устройства для окна
PixelFormat = ChoosePixelFormat(hDC, &pfd);// Найти ближайшее совпадение для нашего формата пикселов if (!PixelFormat) // Если неудалось то... { // Выводим сообщение об ошибке MessageBox (0, "Не удается найти подходящий PixelFormat!", "Error", MB_OK | MB_ICONERROR); SendMessage(hWnd, WM_DESTROY, wParam, lParam);// Это сообщение говорит, что программа должна завершится break; //Предотвращение повтора кода }
SetPixelFormat (hDC, PixelFormat, &pfd); // Теперь нкжно установить наш формата пикселов if (!SetPixelFormat (hDC, PixelFormat, &pfd)) // Если неудалось то... { // Выводим сообщение об ошибке MessageBox (0, "Не удается установить PixelFormat!", "Ошибка!!!", MB_OK | MB_ICONERROR); // Уничтожаем окно! SendMessage(hWnd, WM_DESTROY, wParam, lParam); break; }
hGLRC = wglCreateContext (hDC); //Захватывает Контекст Рендеринга и сохраняет его в переменной hGLRC if (!hGLRC) // Захватить не удалось... { // Выводим сообщение об ошибке MessageBox (0, "Не удается создать контекст рендеринга OpenGL!", "Ошибка!!!", MB_OK | MB_ICONERROR); // Уничтожаем окно! SendMessage(hWnd, WM_DESTROY, wParam, lParam); break; }
// это сообщение приходит при уничтожении окна case WM_DESTROY: //Уничтожает окно case WM_CLOSE: //-|-|-|-|-|-|- ChangeDisplaySettings (NULL, 0);//Восстанавливает первоначальное разрешение if(hDC) wglMakeCurrent(hDC, NULL); // Освобождаем контекст рендеринга... if(hGLRC) wglDeleteContext(hGLRC); // ...и удаляем его if(hWnd) ReleaseDC(hWnd, hDC); // Рвем с ним всякие связи. PostQuitMessage(0); // Убиваем окно! break;
case WM_SIZE: GetClientRect (hWnd, &Screen);//Создает область рисования и возвращает высоту и ширину окна reshape(Screen.right, Screen.bottom ); break;
case WM_SYSKEYDOWN: case WM_KEYDOWN: //Если клавиша нажата то... keys[wParam] = TRUE; //В масив keys[key number] заносится TRUE break;
case WM_SYSKEYUP: case WM_KEYUP: //Если клавиша отпущена то... keys[wParam] = FALSE; //В масив keys[key number] заносится FALSE break;
default: // Реакция на все осталные сообщения ОС... return DefWindowProc(hWnd,message,wParam,lParam); // ...по умолчанию } // если гдето чтото не так... return 0; // ...возвращаем ошибку }
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR str,int nWinMode) { MSG msg;//Структура сообщения Windows WNDCLASS wc; //Структура класса Windows для установки типа окна HWND hWnd;//Сохранение дескриптора окна
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Стиль нашего окна wc.lpfnWndProc = WindowFunc; // Определяем ф-цию ответственную за обработку сообщений ОС wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = NULL; // иконка нашего окошка (по умолчанию) wc.hCursor = LoadCursor (NULL, IDC_ARROW); // Курсор который будет отображаться при наведении на наше окошко (стрелка) wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = "OpenGLWinClass"; // Определяем название класса окна
if (!RegisterClass(&wc)) // Если класс зарегистрировать не удалось... { MessageBox(0, "Ошибка при регистрации класса окна!","Ошибка!!!", MB_OK | MB_ICONERROR); return FALSE; }
if(isFullscr) // Если режим полноэкранный - создаем окно с соответствующими параметрами { // создаем окно hWnd = CreateWindow( "OpenGLWinClass", // название класса окна "УРОК 01 >OpenGL is COOL", // Заголовок окна WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, // Стиль (вид) окна 0, 0, resW, resH, // Размеры окна NULL, NULL, hInstance, NULL); } else // Иначе утанавливаем наше окошко, его вид и свойства { // создаем окно hWnd = CreateWindow( "OpenGLWinClass", // название класса окна "Игра №1 версия 1.0", // Заголовок окна WS_OVERLAPPEDWINDOW | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE | WS_SIZEBOX, // Стиль (вид) окна 0, 0, resW, resH, // Размеры окна NULL, NULL, hInstance, NULL); }
if (!hWnd) // если создать окно не удалось { MessageBox(0, "Ошибка при создании окна!","Ошибка!!!", MB_OK | MB_ICONERROR); return FALSE; }
if(isFullscr) { DEVMODE dmScreenSettings; // Режим работы устройства (видио платы) memset (&dmScreenSettings, 0, sizeof(DEVMODE));// Очистка для хранения установок dmScreenSettings.dmSize = sizeof(DEVMODE); // Размер структуры Devmode dmScreenSettings.dmPelsWidth = resW; // Ширина экрана dmScreenSettings.dmPelsHeight = resH; // Высота экрана dmScreenSettings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;// Режим Пиксела ChangeDisplaySettings (&dmScreenSettings, CDS_FULLSCREEN);// Переключение в полный экран } //else ChangeDisplaySettings (&dmScreenSettings, CDS_GLOBAL);
void progektor(int poz_x, int poz_y, int poz_z, float napravleniye, ?????) { glLoadIdentity(); glTranslated(poz_x, poz_y, poz_z); glRotated(0, 0.0f, 0.0f, 0.0f);
// прожектор // убывание интенсивности с расстоянием // отключено (по умолчанию) // половина угла при вершине 30 градусов // направление на центр плоскости
Пост N: 38
Зарегистрирован: 10.05.07
Откуда: Россия, Казань
Рейтинг:
1
Отправлено: 13.02.10 09:07. Заголовок: Я так понимаю GL_LIG..
Я так понимаю GL_LIGHT3 это определение типа #define GL_LIGHT3 3 // -это как я думаю системное определение ОпенЖЛ,тогда Скрытый текст
void progektor(int poz_x, int poz_y, int poz_z, float napravleniye, int nomer) { glLoadIdentity(); glTranslated(poz_x, poz_y, poz_z); glRotated(0, 0.0f, 0.0f, 0.0f);
// прожектор // убывание интенсивности с расстоянием // отключено (по умолчанию) // половина угла при вершине 30 градусов // направление на центр плоскости
// прожектор // убывание интенсивности с расстоянием // отключено (по умолчанию) // половина угла при вершине 30 градусов // направление на центр плоскости glEnable(nomer); glLightfv(nomer, GL_DIFFUSE, (GLfloat*)&light->diffuse ); glLightfv(nomer, GL_POSITION,(GLfloat*)&light->pos); glLightf(nomer, GL_SPOT_CUTOFF, 30); glLightfv(nomer, GL_SPOT_DIRECTION, (GLfloat*)&light->direction );
}
// отключение источников света //glDisable(nomer);
//Пример вызова Light light; //...заполнение структуры light// progektor(&light, GL_LIGHT3);
Отправлено: 11.04.10 08:38. Заголовок: ЗАГРУЗКА И ВЫВОД 3DS ОБЬЕКТА (OpenGL)
Подскажите пожалуйста как можно сделать в этом примере так, чтобы при загрузке модели можно было бы указывать переменную (имя или какой либо номер(tank, 1, 2)): Load3DS(переменная, “путь к объекту”); Load3DS(tank, 3ds/kkk3.3DS"); Load3DS(1, 3ds/kkk3.3DS"); Load3DS(2, 3ds/kkk3.3DS"); А при выводе указываешь эту переменную(tank, 1, 2) и он выводит этот объект. ris3DS(tank); ris3DS(1); ris3DS(2);
Пост N: 49
Зарегистрирован: 10.05.07
Откуда: Россия, Казань
Рейтинг:
2
Отправлено: 11.04.10 19:32. Заголовок: Правильно бы было на..
Правильно бы было написать две функции LoadObjectFrom3DS и UnLoadObject , первая ф-ия занимается следующим: открывает файл по указ. адресу, читает заголовок файла(делает проверку формата и т.п.), выделяет память под требуемое количество вершин(динамически, а не как у тебя статически массивом), производит чтение вершин и свойств в память из файла, закрывает файл; вторая ф-ция занимается освобождением памяти, выделенной первой. Я так думаю будет лучше. Насчет второго вопроса, используй ф-цию типа LoadSceneFrom3DS и UnLoadScene и структуру типа struct scene_3d { uint numobjects; object_3d* objects; }; Описанные ф-ии схожи с выше описанными
Отправлено: 30.04.10 17:58. Заголовок: Управление камерой OpenGL
Помогите! ) Когда двигаешься прямо и вращяешься вправо влево, то всё нормально работает но при вращении вверх и в низ, особенно разворот на 180 градусов сразу всё управление переворачивает! Вот эту простую проблему мне пока не получаеться решить! Скрытый текст
Все даты в формате GMT
3 час. Хитов сегодня: 5
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет