Создание проекта в C# WinForms с использованием OpenGl
В данном уроке демонстрируется подключение интерфейса OpenGL и приводится пример создания простого изображения с использованием этой технологии.
Для создания проекта нам понадобится Microsoft Visual Studio 2015. Для версий 2010 и 2012 разработаны специальные расширения, однако в данном уроке будет использована именно MVS 2015, для которой OpenGL подключим вручную. Объяснения будут как на русском, так и на английским языках. Ссылка на бесплатную редакцию:
https://www.microsoft.com/ru-ru/SoftMicrosoft/vs2015Community.aspx
1. Создание Приложения WindowsForms / Windows Forms Application
1. Нажимаем CTRL+SHIFT+N или выбираем Файл (File)->Создать (New)->Проект (Project).
2. Слева в пункте Установленные (Installed) разворачиваем пункт Шаблоны (Templates) и выбираем пункт Visual C#.
3. В списке выбираем Приложение Windows Forms (Windows Forms Application), задаем имя проекта и нажимаем OK.
2. Скачиваем библиотеки SharpGl
Готовые файлы можно найти в материалах к уроку — это архив . SharpGL.WinForms.zip.
Также материалы можно скачать и с официального сайта, для этого надо перейти на
http://sharpgl.codeplex.com/releases или зайти через главную страницу
http://sharpgl.codeplex.com в раздел Downloads. Нам нужна версия SharpGL 2.3. Под тегом RECOMMENDED DOWNLOAD переходим по ссылке SharpGL Assemblies (WPF & Winforms), будет загружен архив с папкой Core. В ней нам понадобится не все — только файлы из папки SharpGL.WinForms. В разделе OTHER AVAILABLE DOWNLOADS. можно скачать примеры по Samples, о которых будет идти речь в следующих уроках. Тут же и расширения для MVS 2010 и MVS 2012. Версия 2.3 рабочая и для 2012 Студии. Иначе можно скачать и с GitHub по ссылке https://github.com/dwmkerr/sharpgl/releases/tag/v2.3.0.1.
3. Подключение ссылок
Для подключения существует два пути. Первый: раздел из вкладки Сервис(Tools) в Диспетчер пакетов Nuget (NuGet Package Manager)->Консоль диспетчера пакетов (Package Manager Console)–>Выбрать в качестве Источника пакетов (Package Source) «nuget.org»(можно оставить все)->Ввести Install-Package SharpGL->Ввести Install-Package SharpGL.WinForms.
Второй способ: найти в Обозревателе решений (Solution Explorer) раздел Cссылки (References)->Добавить ссылку (Add reference):
Откроется Менеджер ссылок, необходим Обзор, далее находим у себя в файловой системе папку SharpGL.WinForms, где и лежат требуемые библиотеки SharpGl.dll, SharpGl.SceneGraph.dll, SharpGl.WinForms.dll:
Далее надо проверить в Обозревателе решений, в пункте Ссылки (References), появились ли ссылки SharpGl, SharpGl.SceneGraph, SharpGl.WinForms:
3. Добавление в панель элементов новых элементов
Первый шаг – простой, но не обязательный. Чтобы не добавить элементы в вкладку Общие, сделаем следующее. Свернем все группы элементов, последняя вкладка – Общие — обычно пустая, и если ее открыть, выскакивает надпись, что в данной группе элементов нет. Давайте щелкнем в свободной области панели правой кнопкой мыши и выберем «Добавить вкладку» из выпадающего списка. Создадим новую вкладку элементов, например, «MyOpenGL» – «группу» можно назвать как угодно:
Так как вкладка новая, увидим, что там элементов нет, щелкнем правой кнопкой по полоске с названием вкладки и далее из списка в «Выбрать элементы»:
В новом окне будет много вкладок, требуемая — «Компоненты .NET Framework». Зайдем в обзор и найдем в наших файлах SharpGL.WinForms.dll. Открываем, в списке можно глянуть, добавились ли элементы, жмем OK:
Во вкладке MyOpenGL должны появиться элементы Указатель (Стандартно), GLColorPicker, OpenGLControl, SceneControl, VertexControl. Новые элементы добавлены и теперь можно наконец-то приступать к разработке.
4. Создание экземпляра OpenGL-формы
Для этого располагаем OpenGLControl на нашу форму и заходим в свойства нового объекта. Для лучшей ориентации рекомендуется использование категорий. Находим в первой же категории SharpGL такие атрибуты:
Dock – позиция нового «контрола» на форме. Введем «Fill», чтобы наш «контрол» занял всю площадь. Также можно из выпадающего списка выбрать «Центр», интуитивно будет понятно, что имеется в виду.
FrameRate – количество кадров, которые будут отрисованы в секунду. По умолчанию там 20, изменим на 30. Однако этот параметр зависит от того, насколько «тяжелое» приложение и FPS может быть и ниже.
OpenGLVersion – версия технологии, которую мы реализовываем – это OpenGL2_1, и она уже задана по умолчанию. На момент создания урока последняя версия – OpenGL4_4.
RenderTrigger – один из контекстов рендеринга, можно выбрать TimerBased – тогда каждый кадр будет отрисовываться на основании времени, т.е. с определенной частотой секунд. Если мы зададим Manual – рендеринг каждого кадра надо будет реализовывать вручную.
Последний, и самый интересный – DrawFPS.
Его используют, если хотят проверить, как работает приложение. Можете сразу перейти к выполнению следующего пункта, но лучше прочитайте его до конца.
Зададим значение атрибута DrawFPS равным True. После запуска проекта получим ошибку типа System.NullReferenceException и следующие:
«Элемент управления Sharp.OpenGL вернул в конструкторе необработанное исключение и был отклонен. Исключение: Ссылка на объект не указывает на экземпляр объекта.»
Это происходит, если предварительно не задать в событиях нашего «контрола» свойство атрибута OpenGLDraw, просто щелкнув мышью по незаполненному полю атрибута. Перейдем из конструктора к коду, для этого можно нажать F7 или на поле формы щелкнуть правой кнопкой мыши и выбрать этот пункт из выпадающего списка. Увидим, что появилась следующая функция – обработчик событий, которая и отрисовывает «контрол»:
private void openGLControl1_OpenGLDraw ( object sender, RenderEventArgs args )
Она будет вызываться каждый раз при отрисовке нашего кадра – как в цикле.
Теперь можно запустить проект и он успешно выполнится. Вывод будет состоять из просто черного экрана. На форме в конструкторе будет отображаться текст ошибки:
Это будет оставаться, пока не реализуем пункт 5, и поэтому не стоит обращать внимание. Все же лучше этого не видеть и сделать все сразу правильно.
5. Очистка буфера и создание. Реализация отрисовки
После всех операций при запуске приложения внизу все равно будут отображаться непонятные цифры и символы:
Это происходит, потому что картинка обновляется очень много раз в секунду, но мы ее не очищаем и она заполняет буфер. Устраним это.
Для того, чтобы не использовать полные имена типов, сначала просто пропишем вверху пространства имен:
Там находятся все те функции, которые нам необходимы для работы в этом примере. В коде мы видим Инициализатор формы InitializeComponent(); – ее конструктор, который создан автоматически.
В обработчике событий пропишем следующие команды. Т.к. мы реализуем ООП, то сначала создаем экземпляр окна, в котором будем рисовать, чтобы было удобно обращаться к нашему «контролу».
OpenGL gl = this . openGLControl1 . OpenGL ;
После вызываем функцию очистки буфера и очищаем и цветовой буфер – буфер, в котором хранятся цвета объектов, и буфер глубины – уже с «глубинами» этих объектов с помощью операции «ИЛИ» (|). Дело в том, что без этой операции изображения и цифры просто будут накладываться друг на друга, и мы будем видеть то изображение, которое получили в пункте 4.
gl . Clear ( OpenGL . GL_COLOR_BUFFER_BIT | OpenGL . GL_DEPTH_BUFFER_BIT ) ;
Далее возвращаем центр координат в начальную точку и сбрасываем модельно-видовую матрицу, которая реализовывает передвижение, вращение и подобные операции над объектами.
После выполняем сдвиг пера, которым будем рисовать объекты, с помощью метода gl.Translate(X.Xf, Y.Yf, Z.Zf). Для этого устанавливаем Z.Zf = -5.0f, а остальное – по нулям. И, наконец, рисуем белый треугольник.
Задание цвета производится методом gl.Color(R.rf, G.gf, B.bf);, принимающего на вход три вещественных параметра в диапазоне [0.0; 1.0] — интенсивность красного, зеленого и синего цветов соответственно.
Ниже приведенный код при запуске выводит нам такую фигуру:
Работа с WinForms и OpenGL
Контекст opengl на winforms
Собственно вопрос, как отрисовывать на панели вин формс, чтобы рядом были баттоны и т.д.? А то.
Посоветуйте пожалуйста литературу по С++(WinForms, OpenGL)
Посоветуйте пожалуйста ,краткий справочник,чтобы писать приложения windows form в Visual Studio и.
Работа с datagridview в winforms
Уважаемые знатоки, посоветуйте пожалуйста литературу (видео, книги, статьи) по работе с.
Работа со стандартными элементами WinForms
Здарова, мужики. Есть пара вопросов по стандартным формам (искал ответы в интере, но там.
Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь или здесь.
Вызвать консольное приложение C# из проекта winforms и дать команду завершения также из winforms
Добрый день ! у меня есть проект на C# на winforms. я написал также консольное приложение на.
Переписать код с WinForms на WPF (Работа с DGV)
Есть такой вот код, товарищи, только он для Windows Form, а мне бы его реализовать для Wpf. Был бы.
Переделать консольное приложение в WinForms (работа с SMTP)
Есть классное приложение которым можно тестировать почтовики, но написано в console. Помогите.
Идеалогически правильная работа с WCF-службой через WinForms приложение
Подскажите, а как идеалогически правильно работают с WCF-службой в WinForms приложении? Текущая.
OpenGL и Form’a
=(( все очень плохо =(( C++
никак не могу сделать что бы можно было OpenGL выводить допустим на панель
мне нужно что бы все выводилось на панель
я знаю что таких тем тут много но внятного ответа нигде не было
можете РАЗЪЯСНИТЬ не просто написать а разъяснить на русском как это сделать я уже 2 неделю пытаюсь сделать и никак
но что бы выводило именно на форму мне надо
О_о
что, где, зачем??
вот создал Window Form Application потом создал на нем Panel1
как теперь вывести на нее.
и что такое Handle и зачем он и где он
Когда контекст OpenGL создаешь, указываешь хендл не окна, а панели. (параметр в GetDC)
Что такое ОпенГЛ знаем, а что такое Хэндл — нет? Не верю. Мне кажется, автор пытается что-то сделать с примером, который писал не он и в котором он ничего не понимает. А так не надо. Надо сначала понять, а потом что-то делать.
. что такое ОпенГЛ я знаю нароботался с ним
но с оконными приложениями в С++ не сталкивался только на C#
а можете пример кода показать?? ну как сделать что бы на панели все было. и как узнать хендл панели?? и что это такое
Если вкратце, то для Windows Forms так делается:
HDC hdc;
HGLRC hrc;
HWND Handle;
при инициализации opengl (можно в событии Form1_Load()) :
wglMakeCurrent(0, 0);
Handle=(HWND)Panel1->Handle.ToPointer();
hdc=GetDC(Handle);
// . настраиваем формат пикселя
int PixelFormat=ChoosePixelFormat( hdc, &pfd );
SetPixelFormat( hdc, PixelFormat ,&pfd );
hrc=wglCreateContext(hdc);
в функции отрисовки:
glViewport( 0, 0, Panel1->Width, Panel1->Height );
wglMakeCurrent( hdc, hrc );
//. здесь собственно opengl код сцены
SwapBuffers(hdc);
wglMakeCurrent(0, 0);
Тока есть как минимум один недостаток: при изменении размеров панели, размер самого opengl окна изменить скорее всего не удастся.
Как альтернативу — можно борландский VCL юзать, он с opengl более дружен.
Ну а handle окна, панели и т.п. — это его Id. Вообще, такие вопросы надо гуглу задавать, а не на форумах. Либо по книжкам изучать.
а что за VCL и как с ним работать??
а у меня ошибок много =(( при компиляции
Стукнись в аську, расскажу что да как..
Народ тебе верно говорит, надо юзать хендл.
Причём абсолютно пофиг хендл чего: окна, панели.
Если тебе нужно выводить на панель. то запрашивай хендл данной панели.
Пример:
Правка:
Не посмотрел, тебе товарищ Divait_Fir уже всё расписал. Ошибки если тупые то правь, если уж совсем никак, кидай сюда, а телепаты щас в отпуске, так что сказать что они у тебя просто есть недостаточно..
jec
ну что за вопросы «что», да «как»?
Как я уже говорил, для таких вопросов поисковик предначен.
А раз есть ошибки — исправляй))
Единственную сложную вещь (как хендл конвертнуть) я показал в коде.
Далее не сложно использовать приведенный код, если есть опыт работы с opengl и хотя-бы небольшие навыки работы с windows forms.
А вообще, советую сесть и разобраться как оконные приложения писать, а не пытаться сразу переходить на следующий шаг.
Можно конечно скинуть рабочий пример, но сомневаюсь, что у кого-нибудь появиться желание помогать тому, кто сам не хочет разбираться.
Divait_Fir
разобраться то я и хочу, и вот пытаюсь.
блин никак не понятно =((
что куда писать =((
а можно такую панельку написать самому?? ну ставишь ее на окно и в нее все выводится, и сделать что бы она этот хендл передовала. это что бы не мучаться не писать все это
а у меня что то получилось =))
нашел код где все это есть =))))
правда там очень много чего лишнего было так что я почистил и вот как выглядит конечный вариант =))
using namespace System::Windows::Forms;
namespace OpenGLForm
<
public ref class COpenGL: public System::Windows::Forms::NativeWindow
<
public:
COpenGL(System::Windows::Forms::Form ^ parentForm, GLsizei iWidth, GLsizei iHeight)
<
CreateParams^ cp = gcnew CreateParams;
cp->X = 0;
cp->Y = 0;
cp->Height = iHeight;
cp->Width = iWidth;
cp->Style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
if(m_hDC)
<
MySetPixelFormat(m_hDC);
ReSizeGLScene(iWidth, iHeight);
InitGL();
>
>
System::Void Render(System::Void)
<
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
>
void SwapOpenGLBuffers()
<
SwapBuffers(m_hDC) ;
>
private:
HDC m_hDC;
HGLRC m_hglrc;
GLint MySetPixelFormat(HDC hdc)
<
static PIXELFORMATDESCRIPTOR pfd=
<
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
16,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
16,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
>;
if((m_hglrc = wglCreateContext(m_hDC)) == NULL)
<
MessageBox::Show(«wglCreateContext Failed»);
return 0;
>
if((wglMakeCurrent(m_hDC, m_hglrc)) == NULL)
<
MessageBox::Show(«wglMakeCurrent Failed»);
return 0;
>
void InitGL()
<
glShadeModel(GL_SMOOTH);
glClearColor(0.0, 0.0, 0.0, 0.5);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
>
void ReSizeGLScene(GLsizei width, GLsizei height)
<
glViewport(0, 0, width, height);
gluPerspective(45, (float)width / (float)height, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
>
>;
>
можете помочь упорядочить код (без лишнего)
и разобрать его (каждую строчку кроме ReSizeGLScene, InitGL, Render)
сам пробовал написать по нехеховским урокам но не получилось
и еще мне надо сделать что бы все выводилось на панель а не тупо по размеру. а то я пробовал но не работало
jec
> вот создал Window Form Application потом создал на нем Panel1
> как теперь вывести на нее.
> и что такое Handle и зачем он и где он
> как узнать хендл панели?? и что это такое
> блин никак не понятно =((
> что куда писать =((
> =(( все очень плохо =((
> что, где, зачем??
Кастую slava_mib в топик для доходчивого объяснения.
jec
Уточнять надо, чего конкретно не получается. Телепаты вернулись из отпуска и догдались, что ты пишешь на Windows.Forms и VC++.NET. Половина советов с начала была про Borland C++ Builder (и таинственный VCL).
Для максимальной аналогии представь, что ты спросил так:
— Ой, у меня машина не едет. Чего делать ?
Тебе отвечают:
— Залей туда дизельного топлива.
Ты делаешь по совету (попутно выясняя где ж это топливо продают и как заливать)
Ну а потом выясняется, что машина с бензиновым двигателем.
а entryway нагуглил, видимо, примерно это
http://www.codeproject.com/KB/miscctrl/OpenGLViewWinForms.aspx?msg=2831562
Прочитай, там действительно есть ответы на всё. (предвижу ответ «У меня с английским не очень» 🙂 )
Как написать свою панельку — это вообще ликбез по .NET
Divait_Fir тоже верно сказал про хэндлы. Всё ж просто, если разобраться.