dir.by  
  Search  
Programming, development, testing
C++
OpenGL
Create a new OpenGL ES2 app on C++ in Windows | Visual Studio, Desktop application
  Looked at 1289 times    
 Create a new OpenGL ES2 app on C++ in Windows | Visual Studio, Desktop application 
last updated: 30 December 2024
Download the example at OpenGL ES2
ProjectWindowsC++.zip ...
Size: 3 MB

Note! OpenGL ES2 is used on Android and it is very convenient to write in Windows first and then write the program in Android.
Step 1. Open Visual Studio
If you do not have Visual Studio installed you need install Visual Studio...
Open Visual Studio 2022
or
Open Visual Studio 2019
Step 2. Let's create a new C++ desktop application
Choose: Console App
 
The following project was created:
 
Let's run the program:
 
Let's see the result:
Step 3. Download the OpenGL ES2 library as zip
 
Inside opengl_es_windows.zip are the following files:
Step 4. Add the OpenGL ES2 files to the C++ project
My C++ project is in the folder: D:\ProjectWindowsC++

Let's copy the files from opengl_es_windows.zip inside the C++ project like this:
 
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

Right-click on Visual Studio and add dll, lib files to the project:
 
we will see the added files:
 
Right-click on libEGL.dll and click on Properties
 
Let's set Copy file so that dll is copied during the build:
 
Let's also put Copy file for libGLESv2.dll.
 
Right-click on Properties:
 
Add:
./opengl_es_windows/include/;
Step 5. Add new files my_game.cpp, my_game.h to the Visual Studio project
Let's create new files here:
D:\ProjectWindowsC++\
    my_game.cpp
    my_game.h
  C++     File 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++     File 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();
};
 
Right-click on Visual Studio and add my_game.cpp, my_game.h files to the project:
 
Here's how it turns out:
Step 6. Let's change the code in the file ProjectWindowsC++.cpp
  C++     File 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;
}
Step 7. Let's run the program
 
← Previous topic
Creating a OpenGL app with 3D pyramid drawing and a motion camera on C++ | Visual Studio | Library glut for using OpenGL
 
 
Your feedback ... Comments ...
   
Your Name
Your comment (www links can only be added by a logged-in user)

  Объявления  
  Объявления  
 
dynamic_cast in C++ (converting a pointer to a different type and checking validity in runtime)
std::map<Key, Value> is a set of keys and values in C++. An important feature of std::map is to quickly find a value by key
Pass a function as a parameter to a function (callback) | C++
OpenGL
Create a new OpenGL application on C++ | Library GLUT, Visual Studio
Creating a OpenGL app with 3D pyramid drawing and a motion camera on C++ | Visual Studio | Library glut for using OpenGL
Create a new OpenGL ES2 app on C++ in Windows | Visual Studio, Desktop application

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