Last active
July 11, 2022 09:26
-
-
Save lag945/e78b3ef9c22f2e80285e9c23eba94848 to your computer and use it in GitHub Desktop.
Desktop 3D with EGL+ANGLE+Windows
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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