dir.by  
  Поиск  
Программирование, разработка, тестирование
C++
OpenGL
Создаем новое OpenGL ES2 приложение на C++ в Windows | Visual Studio, Desktop application
  Посмотрели 1290 раз(а)    
 Создаем новое OpenGL ES2 приложение на C++ в Windows | Visual Studio, Desktop application 
последнее обновление: 30 декабря 2024
Скачать пример на OpenGL ES2
ProjectWindowsC++.zip ...
размер: 3 мегабайта

На заметку! OpenGL ES2 используется на Android и очень удобно сначала писать в Windows и потом программу писать на Android.
Шаг 1. Открываем Visual Studio
Если у вас не установлена Visual Studio нужно установить Visual Studio...
Открываем Visual Studio 2022
или
Открываем Visual Studio 2019
Шаг 2. Давайте создадим новое десктопное приложение на C++
Выбираем: Console App
 
Создался вот такой проект:
 
Запустим программу:
 
Увидим результат:
Шаг 3. Скачаем библиотеку OpenGL ES2 как zip
opengl_es_windows.zip ...
размер: 3 мегабайта
 
Внутри opengl_es_windows.zip вот такие файлы:
Шаг 4. Добавим файлы OpenGL ES2 в C++ проект
Мой C++ проект находится в папке: D:\ProjectWindowsC++

Скопируем файлы из opengl_es_windows.zip внутрь C++ проекта вот так:
 
D:\ProjectWindowsC++
    opengl_es_windows
        libEGL.dll
        libEGL.lib
        libGLESv2.dll
        libGLESv2.lib
        include
            EGL
                egl.h
                eglplatform.h
            GLES2
                gl2.h
                gl2platform.h
            KHR
                khrplatform.h

Нажмем правой клавишей мыши в Visual Studio и добавим dll, lib файлы в проект:
 
увидим добавленные файлы:
 
Нажмем правой клавишей мыши на libEGL.dll и нажмем на Properties
 
Поставим Copy file чтобы при сборке dll копировалась:
 
Поставим также Copy file для libGLESv2.dll.
 
Нажмем правой клавишей мыши на Properties:
 
Добавим:
./opengl_es_windows/include/;
Шаг 5. Добавим новые файлы my_game.cpp, my_game.h в Visual Studio проект
Создадим новые файлы тут:
D:\ProjectWindowsC++\
    my_game.cpp
    my_game.h
  C++     Файл my_game.cpp
#include "my_game.h"
#include <EGL/eglplatform.h>
#include "opengl_es_windows/include/EGL/egl.h"

MyGame::MyGame()
{
     m_Width = 0;
     m_Height = 0;
}

void MyGame::OnActiveFocus()
{
}

void MyGame::OnLostFocus()
{
}

bool MyGame::OnHandleTouch()
{
     return false; // event not handled
}

void MyGame::OnNextTick()
{
}

// open GL
void MyGame::DrawGraphic_OpenGL()
{
     if (m_Display == EGL_NO_DISPLAY || m_Surface == EGL_NO_SURFACE || m_Context == EGL_NO_CONTEXT)
          return;

     // green color
     glClearColor(0.72f, 0.87f, 0.55f, 1);
     glClear(GL_COLOR_BUFFER_BIT);

     eglSwapBuffers(m_Display, m_Surface);
}

void MyGame::CreateSurfaceFromWindow_OpenGL(HWND window)
{
     const EGLint attribs[] = {EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
                                   EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
                                   EGL_BLUE_SIZE, 8,
                                   EGL_GREEN_SIZE, 8,
                                   EGL_RED_SIZE, 8,
                                   EGL_NONE};
     EGLint format;
     EGLint numConfigs;

     eglChooseConfig(m_Display, attribs, &m_configOpenGL, 1, &numConfigs);

     eglGetConfigAttrib(m_Display, m_configOpenGL, EGL_NATIVE_VISUAL_ID, &format);

     m_Surface = eglCreateWindowSurface(m_Display, m_configOpenGL, window, NULL);
}

void MyGame::KillSurface_OpenGL()
{
     eglMakeCurrent(m_Display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
     if (m_Surface != EGL_NO_SURFACE)
     {
          eglDestroySurface(m_Display, m_Surface);
          m_Surface = EGL_NO_SURFACE;
     }
}

bool MyGame::MakeCurrent_Display_Surface_Context_OpenGL()
{
     if (eglMakeCurrent(m_Display, m_Surface, m_Surface, m_Context) == EGL_FALSE)
          return false;
     return true;
}

bool MyGame::InitGraphic_OpenGL(HWND window)
{
     // init Display
     m_Display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     eglInitialize(m_Display, nullptr, nullptr);

     // init Surface
     CreateSurfaceFromWindow_OpenGL(window);

     // init Context
     EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2,EGL_NONE };
     m_Context = eglCreateContext(m_Display, m_configOpenGL, NULL, contextAttribs);

     if (!MakeCurrent_Display_Surface_Context_OpenGL())
          return false;

     EGLint w, h;
     eglQuerySurface(m_Display, m_Surface, EGL_WIDTH, &w);
     eglQuerySurface(m_Display, m_Surface, EGL_HEIGHT, &h);

     m_Width = w;
     m_Height = h;

     // Open GL states
     glDisable(GL_CULL_FACE);
     glDisable(GL_DEPTH_TEST);
     glEnable(GL_TEXTURE_2D);

     // for alpha color (transparency)
     glEnable( GL_BLEND );
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

     return true;
}

void MyGame::CloseGraphic_OpenGL()
{
     if (m_Display != EGL_NO_DISPLAY)
     {
          eglMakeCurrent(m_Display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);

          if (m_Context != EGL_NO_CONTEXT) {
               eglDestroyContext(m_Display, m_Context);
          }

          if (m_Surface != EGL_NO_SURFACE) {
               eglDestroySurface(m_Display, m_Surface);
          }

          eglTerminate(m_Display);
     }

     m_Display = EGL_NO_DISPLAY;
     m_Context = EGL_NO_CONTEXT;
     m_Surface = EGL_NO_SURFACE;
}
  C++     Файл my_game.h
#include "opengl_es_windows/include/EGL/egl.h"
#include "opengl_es_windows/include/GLES2/gl2.h"

class MyGame
{
     // constructor
     public: MyGame();

     // fields
     protected: EGLDisplay m_Display = EGL_NO_DISPLAY;
     protected: EGLSurface m_Surface = EGL_NO_SURFACE;
     protected: EGLContext m_Context = EGL_NO_CONTEXT;
     protected: EGLConfig m_configOpenGL = nullptr;
     protected: int m_Width;
     protected: int m_Height;

     // events
     public: void OnActiveFocus();
     public: void OnLostFocus();
     public: bool OnHandleTouch();
     public: void OnNextTick();

     // OpenGL
     public: void CreateSurfaceFromWindow_OpenGL(HWND window);
     public: void KillSurface_OpenGL();
     public: bool MakeCurrent_Display_Surface_Context_OpenGL();
     public: bool InitGraphic_OpenGL(HWND window);
     public: void CloseGraphic_OpenGL();
     public: void DrawGraphic_OpenGL();
};
 
Нажмем правой клавишей мыши в Visual Studio и добавим my_game.cpp, my_game.h файлы в проект:
 
Вот так получится:
Шаг 6. Поменяем код в файле ProjectWindowsC++.cpp
  C++     Файл ProjectWindowsC++.cpp
#include "framework.h"
#include "ProjectWindowsC++.h"

#include "my_game.h"

#define MAX_LOADSTRING 100
HINSTANCE hInst; // current instance
WCHAR szTitle[MAX_LOADSTRING]; // The title bar text
WCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name

ATOM MyRegisterClass(HINSTANCE hInstance);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);

constexpr static const float TURN_TIMES_IN_SECONDS = 1.0f / 50.0f; // 50 times per second
bool g_isApplicationClosed = false;
MyGame g_game;


int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
     UNREFERENCED_PARAMETER(hPrevInstance);
     UNREFERENCED_PARAMETER(lpCmdLine);
     hInst = hInstance;

     // Initialize global strings
     LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
     LoadStringW(hInstance, IDC_PROJECTWINDOWSC, szWindowClass, MAX_LOADSTRING);
     MyRegisterClass(hInstance);

     // initialization:
     HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
     if (!hWnd)
          return FALSE;

     ShowWindow(hWnd, nCmdShow);
     UpdateWindow(hWnd);

     g_game.InitGraphic_OpenGL(hWnd);

     HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_PROJECTWINDOWSC));

     // Main message loop:
     MSG msg;
     auto prev_inMilliseconds = GetTickCount64();
     while (true)
     {
          if (g_isApplicationClosed)
               break;

          while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) > 0) {
               TranslateMessage(&msg);
               DispatchMessage(&msg);
          }

          auto now_inMilliseconds = GetTickCount64();
          if (((now_inMilliseconds - prev_inMilliseconds) / 1000.0 /*milliseconds to seconds*/) > TURN_TIMES_IN_SECONDS)
          {
               // my game render
               g_game.DrawGraphic_OpenGL();

               // my game next tick
               g_game.OnNextTick();
          }

     }

     return 0;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
     WNDCLASSEXW wcex;

     wcex.cbSize = sizeof(WNDCLASSEX);

     wcex.style = CS_HREDRAW | CS_VREDRAW;
     wcex.lpfnWndProc = WndProc;
     wcex.cbClsExtra = 0;
     wcex.cbWndExtra = 0;
     wcex.hInstance = hInstance;
     wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PROJECTWINDOWSC));
     wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
     wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
     wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_PROJECTWINDOWSC);
     wcex.lpszClassName = szWindowClass;
     wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

     return RegisterClassExW(&wcex);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     switch (message)
     {
          case WM_PAINT:
          {
               PAINTSTRUCT ps;
               HDC hdc = BeginPaint(hWnd, &ps);
               // TODO: Add any drawing code that uses hdc here...
               EndPaint(hWnd, &ps);
               break;
          }

          case WM_DESTROY:
               g_isApplicationClosed = true;
               g_game.CloseGraphic_OpenGL();

               PostQuitMessage(0);
               break;

          case WM_SIZE:
               break;

          default:
               return DefWindowProc(hWnd, message, wParam, lParam);
     }
     return 0;
}
Шаг 7. Запустим программу
 
← Предыдущая тема
Создаю OpenGL приложение с рисованием 3D пирамид и движущей камерой на C++ | Visual Studio | Библиотека glut для использования OpenGL
 
 
Ваши Отзывы ... комментарии ...
   
Вашe имя
Ваш комментарий (www ссылки может добавлять только залогиненный пользователь)

  Объявления  
  Объявления  
 
dynamic_cast в C++ (преобразование указателя в другой тип и проверка валидности во время выполнения)
std::map<Key, Value> это набор ключей и значений в C++. Важная особенность std::map это быстро найти значение по ключу
Передаем функцию как параметр в функцию (callback) | C++
OpenGL
Создаем новое OpenGL приложение на C++ | библиотека GLUT, Visual Studio
Создаю OpenGL приложение с рисованием 3D пирамид и движущей камерой на C++ | Visual Studio | Библиотека glut для использования OpenGL
Создаем новое OpenGL ES2 приложение на C++ в Windows | Visual Studio, Desktop application

  Ваши вопросы присылайте по почте: info@dir.by  
Яндекс.Метрика