Skip to content

Instantly share code, notes, and snippets.

@lag945
Last active July 11, 2022 09:26
Show Gist options
  • Save lag945/e78b3ef9c22f2e80285e9c23eba94848 to your computer and use it in GitHub Desktop.
Save lag945/e78b3ef9c22f2e80285e9c23eba94848 to your computer and use it in GitHub Desktop.
Desktop 3D with EGL+ANGLE+Windows
#include <iostream>
#include <EGL/egl.h>
#include <EGL/eglplatform.h>
#include <GLES3/gl3.h>
#include <sstream>
using namespace std;
//based on https://github.com/SaschaWillems/openglcpp/blob/master/eglExample/eglExample/eglExample/eglExample.cpp
bool quit = false;
int winWidth = 800;
int winHeight = 600;
LRESULT CALLBACK wndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CLOSE:
{
quit = true;
DestroyWindow(hwnd);
PostQuitMessage(0);
return 0;
}
case WM_SIZE:
{
winWidth = LOWORD(lParam);
winHeight = HIWORD(lParam);
return 0;
}
}
return (DefWindowProc(hwnd, msg, wParam, lParam));
}
HWND createWindow(int width, int height)
{
HINSTANCE hInstance = GetModuleHandle(NULL);
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_OWNDC;
wcex.lpfnWndProc = &DefWindowProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = 0;
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"eglsamplewnd";
wcex.hIconSm = NULL;
wcex.lpfnWndProc = wndProc;
RegisterClassEx(&wcex);
RECT rect = { 0, 0, width, height };
int style = WS_BORDER | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME;
AdjustWindowRect(&rect, style, FALSE);
HWND hwnd = ::CreateWindow(L"eglsamplewnd", L"EGL OpenGL ES 3.0 example", style, CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, GetModuleHandle(NULL), NULL);
ShowWindow(hwnd, SW_SHOW);
return hwnd;
}
void outputGLESInfo() {
cout << "GL_VENDOR = " << glGetString(GL_VENDOR) << "\n";
cout << "GL_RENDERER = " << glGetString(GL_RENDERER) << "\n";
cout << "GL_VERSION = " << glGetString(GL_VERSION) << "\n";
cout << "GL_SHADING_LANGUAGE_VERSION = " << glGetString(GL_SHADING_LANGUAGE_VERSION) << "\n";
//TL;DW
/*cout << "Extensions :\n";
string extBuffer;
stringstream extStream;
extStream << glGetString(GL_EXTENSIONS);
while (extStream >> extBuffer) {
cout << extBuffer << "\n";
}
*/
}
void glErrorLog() {
GLuint glError = glGetError();
if (glError != GL_NO_ERROR) {
cout << "OpenGL Error : " << glError << "\n";
}
}
int main()
{
HWND hwnd = createWindow(winWidth, winHeight);
HDC hdc = GetDC(hwnd);
EGLDisplay eglDisplay = eglGetDisplay(hdc);
if (eglDisplay == EGL_NO_DISPLAY) {
cout << "Could not get egl display!" << endl;
return 1;
}
EGLint eglVersionMajor, eglVersionMinor;
eglInitialize(eglDisplay, &eglVersionMajor, &eglVersionMinor);
eglBindAPI(EGL_OPENGL_ES_API);
EGLint configAttributes[] =
{
EGL_BUFFER_SIZE, 0,
EGL_RED_SIZE, 5,
EGL_GREEN_SIZE, 6,
EGL_BLUE_SIZE, 5,
EGL_ALPHA_SIZE, 0,
EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
EGL_CONFIG_CAVEAT, EGL_DONT_CARE,
EGL_CONFIG_ID, EGL_DONT_CARE,
EGL_DEPTH_SIZE, 24,
EGL_LEVEL, 0,
EGL_MAX_SWAP_INTERVAL, EGL_DONT_CARE,
EGL_MIN_SWAP_INTERVAL, EGL_DONT_CARE,
EGL_NATIVE_RENDERABLE, EGL_DONT_CARE,
EGL_NATIVE_VISUAL_TYPE, EGL_DONT_CARE,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_SAMPLE_BUFFERS, 0,
EGL_SAMPLES, 0,
EGL_STENCIL_SIZE, 0,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_TRANSPARENT_TYPE, EGL_NONE,
EGL_TRANSPARENT_RED_VALUE, EGL_DONT_CARE,
EGL_TRANSPARENT_GREEN_VALUE, EGL_DONT_CARE,
EGL_TRANSPARENT_BLUE_VALUE, EGL_DONT_CARE,
EGL_NONE
};
EGLint surfaceAttributes[] = { EGL_NONE };
EGLint contextAttributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
EGLint nrOfConfigs;
EGLConfig windowConfig;
eglChooseConfig(eglDisplay, configAttributes, &windowConfig, 1, &nrOfConfigs);
EGLSurface eglSurface = eglCreateWindowSurface(eglDisplay, windowConfig, hwnd, surfaceAttributes);
if (eglSurface == EGL_NO_SURFACE) {
cerr << "Could not create EGL surface : " << eglGetError() << endl;
return 1;
}
EGLContext eglContext = eglCreateContext(eglDisplay, windowConfig, NULL, contextAttributes);
if (eglContext == EGL_NO_CONTEXT) {
cout << "Could not create egl context : " << eglGetError() << endl;
return 1;
}
cout << "EGL Version = " << eglQueryString(eglDisplay, EGL_VERSION) << "\n";
cout << "EGL Vendor = " << eglQueryString(eglDisplay, EGL_VENDOR) << "\n";
cout << "EGL Client APIs : \n" << eglQueryString(eglDisplay, EGL_CLIENT_APIS) << "\n";
//cout << "EGL Extensions : \n" << eglQueryString(eglDisplay, EGL_EXTENSIONS) << "\n";
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
outputGLESInfo();
//init scene
float points[] = {
0.0f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f
};
GLuint vbo = 0;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), points, GL_STATIC_DRAW);
GLuint vao = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
const char* vertex_shader =
"#version 100\n"
"attribute vec3 vp;"
"void main() {"
" gl_Position = vec4(vp, 1.0);"
"}";
const char* fragment_shader =
"#version 100\n"
"void main() {"
" gl_FragColor = vec4(0.5, 0.0, 0.5, 1.0);"
"}";
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, &vertex_shader, NULL);
glCompileShader(vs);
GLint vertex_compiled;
glGetShaderiv(vs, GL_COMPILE_STATUS, &vertex_compiled);
if (vertex_compiled != GL_TRUE)
{
GLsizei log_length = 0;
GLchar message[1024];
glGetShaderInfoLog(vs, 1024, &log_length, message);
// Write the error to a log
cout << "vertex_compiled: " << message << endl;
}
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, &fragment_shader, NULL);
glCompileShader(fs);
GLint fragment_compiled;
glGetShaderiv(fs, GL_COMPILE_STATUS, &fragment_compiled);
if (fragment_compiled != GL_TRUE)
{
GLsizei log_length = 0;
GLchar message[1024];
glGetShaderInfoLog(fs, 1024, &log_length, message);
// Write the error to a log
cout << "fragment_compiled: " << message << endl;
}
GLuint shader_programme = glCreateProgram();
glAttachShader(shader_programme, fs);
glAttachShader(shader_programme, vs);
glLinkProgram(shader_programme);
// Render loop
MSG uMsg;
PeekMessage(&uMsg, NULL, 0, 0, PM_REMOVE);
while (!quit) {
//render
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glUseProgram(shader_programme);
glBindVertexArray(vao);
// draw points 0-3 from the currently bound VAO with current in-use shader
glDrawArrays(GL_TRIANGLES, 0, 3);
while (PeekMessage(&uMsg, NULL, 0, 0, PM_REMOVE) > 0) {
TranslateMessage(&uMsg);
DispatchMessage(&uMsg);
}
eglSwapBuffers(eglDisplay, eglSurface);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment