Я пытаюсь создать контекст OpenGL с расширением ARB. Я прочитал множество документов, постов и вики-хроники об этом . Но я не могу сделать последний контекст текущим, как вы видите в коде, второй вызов wglMakeCurrent () закомментирован, что означает, что контекст, который фактически используется, является первым созданным без расширения. Если я раскомментирую это, окно не будет отображаться.
Я провел некоторое тестирование на ошибки с функциями ARB, похоже, проблема в списке атрибутов или в вызове wglChoosePixelFormatARB ().
Код:
#include <stdio.h>
#define UNICODE
#include <windows.h>
#include <dwmapi.h>
#define GLEW_STATIC
#include <glew.h>
#include <GL\wglext.h>
LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT uMsg, WPARAM wp, LPARAM lp);
unsigned int CreateShaderProgram(char* VertexSource, char* FragmentSource);
int main(void){
WNDCLASSEX wcx = {};
wcx.cbSize = sizeof(WNDCLASSEX);
wcx.style = CS_OWNDC;
wcx.lpfnWndProc = WindowProcedure;
wcx.lpszClassName = L"Win32Class";
RegisterClassEx(&wcx);
HWND hWnd = CreateWindowEx(WS_EX_APPWINDOW | WS_EX_LAYERED, wcx.lpszClassName, L"Title",
WS_POPUP, 400, 300, 800, 400, NULL, NULL, NULL, NULL);
DWM_BLURBEHIND blur = {};
blur.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
blur.fEnable = 1;
blur.hRgnBlur = CreateRectRgn(0, 0, -1, -1);
DwmEnableBlurBehindWindow(hWnd, &blur);
SetLayeredWindowAttributes(hWnd, RGB(0, 0, 0), 255, LWA_COLORKEY);
PIXELFORMATDESCRIPTOR pfd = {};
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 24;
pfd.cStencilBits = 8;
pfd.iLayerType = PFD_MAIN_PLANE;
HDC DeviceContext = GetDC(hWnd);
int PixelFormat = ChoosePixelFormat(DeviceContext, &pfd);
SetPixelFormat(DeviceContext, PixelFormat, &pfd);
HGLRC RenderingContext = wglCreateContext(DeviceContext);
wglMakeCurrent(DeviceContext, RenderingContext);
glewInit();
int Attributes[] = {
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
WGL_COLOR_BITS_ARB, 32,
WGL_DEPTH_BITS_ARB, 24,
WGL_STENCIL_BITS_ARB, 8,
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
WGL_CONTEXT_MINOR_VERSION_ARB, 4,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
0,
};
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB =
wglGetProcAddress("wglChoosePixelFormatARB");
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB =
(PFNWGLCREATECONTEXTATTRIBSARBPROC)
wglGetProcAddress("wglCreateContextAttribsARB");
wglChoosePixelFormatARB(DeviceContext, Attributes, NULL, 1, &PixelFormat,
NULL);
SetPixelFormat(DeviceContext, PixelFormat, &pfd);
RenderingContext = wglCreateContextAttribsARB(DeviceContext, NULL,
Attributes);
//wglMakeCurrent(DeviceContext, RenderingContext);
char VertexShaderSource[] =
"#version 440 core\n"
"\n"
"layout(location = 0) in vec4 position;\n"
"\n"
"void main(){\n"
" gl_Position = position;\n"
"}";
char FragmentShaderSource[] =
"#version 440 core\n"
"\n"
"layout(location = 0) out vec4 colour;\n"
"\n"
"void main(){\n"
" colour = vec4(0.5, 0.5, 0.5, 1.0);\n"
"}";
float Verticies[] = {
0.0f, 0.5f, // top : 0
0.5f, 0.0f, // right : 1
0.0f, -0.5f, // bottom : 2
-0.5f, 0.0f // left : 3
};
unsigned int Indices[] = {
3, 0, 1, // top
3, 2, 1 // bottom
};
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
unsigned int VertexArray;
glGenVertexArrays(1, &VertexArray);
glBindVertexArray(VertexArray);
unsigned int VertexBuffer;
glGenBuffers(1, &VertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, VertexBuffer);
glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(float), Verticies, GL_STATIC_DRAW);
unsigned int IndexBuffer;
glGenBuffers(1, &IndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned int), Indices,
GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);
unsigned int ShaderProgram = CreateShaderProgram(VertexShaderSource,
FragmentShaderSource);
glUseProgram(ShaderProgram);
glViewport(0, 0, 800, 400);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
ShowWindow(hWnd, 1);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0)){
DispatchMessage(&msg);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);
wglSwapLayerBuffers(DeviceContext, WGL_SWAP_MAIN_PLANE);
}
}
LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT uMsg, WPARAM wp, LPARAM lp){
switch(uMsg){
case WM_NCHITTEST: return HTCAPTION;
case WM_DESTROY: PostQuitMessage(0); return 0;
default: return DefWindowProc(hWnd, uMsg, wp, lp);
}
}
unsigned int CreateShader(char* Source, unsigned int Type);
unsigned int CreateShaderProgram(char* VertexSource,
char* FragmentSource){
unsigned int ShaderProgram = glCreateProgram(),
VertexShader = CreateShader(VertexSource, GL_VERTEX_SHADER),
FragmentShader = CreateShader(FragmentSource, GL_FRAGMENT_SHADER);
glAttachShader(ShaderProgram, VertexShader);
glAttachShader(ShaderProgram, FragmentShader);
glLinkProgram(ShaderProgram);
glValidateProgram(ShaderProgram);
return ShaderProgram;
}
unsigned int CreateShader(char* Source, unsigned int Type){
unsigned int Shader = glCreateShader(Type);
glShaderSource(Shader, 1, (const char* const*)&Source, NULL);
glCompileShader(Shader);
return Shader;
}
Примечание. Приведение результата второго вызова wglGetProcAdress () выдает предупреждение, если установлен флаг -Wextra (для компилятора g cc). Я не знаю, как это исправить.
Обновление: это все еще не работает: «Не удалось выбрать последний формат окна в пикселях». и «Не удалось создать окончательный контекст рендеринга». напечатаны (см. код) ниже. И окно не отображается.
Новый код: (большой комментарий - старый код):
#include <stdio.h>
#define UNICODE
#include <windows.h>
#include <dwmapi.h>
#define GLEW_STATIC
#include <glew.h>
#include <GL\wglext.h>
LRESULT CALLBACK FirstWindowProcedure(HWND hWnd, UINT uMsg, WPARAM wp,
LPARAM lp);
LRESULT CALLBACK FinalWindowProcedure(HWND hWnd, UINT uMsg, WPARAM wp,
LPARAM lp);
unsigned int CreateShaderProgram(char* VertexSource, char* FragmentSource);
int main(void){
WNDCLASSEX FirstWindowClass = {};
FirstWindowClass.cbSize = sizeof(WNDCLASSEX);
FirstWindowClass.style = CS_OWNDC;
FirstWindowClass.lpfnWndProc = FirstWindowProcedure;
FirstWindowClass.lpszClassName = L"FirstWindowClass";
if(!RegisterClassEx(&FirstWindowClass))
puts("Registration of the first window class failed.\n");
HWND FirstWindow = CreateWindowEx(WS_EX_APPWINDOW,
FirstWindowClass.lpszClassName, L"FirstWindow", WS_POPUP, 0, 0, 10, 10,
NULL, NULL, NULL, NULL);
if(FirstWindow == NULL)
puts("Creation of the first window failed.\n");
PIXELFORMATDESCRIPTOR FirstWindowPixelFormatDescriptor = {};
FirstWindowPixelFormatDescriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR);
FirstWindowPixelFormatDescriptor.nVersion = 1;
FirstWindowPixelFormatDescriptor.dwFlags = PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
FirstWindowPixelFormatDescriptor.iPixelType = PFD_TYPE_RGBA;
FirstWindowPixelFormatDescriptor.cColorBits = 32;
FirstWindowPixelFormatDescriptor.cDepthBits = 24;
FirstWindowPixelFormatDescriptor.cStencilBits = 8;
FirstWindowPixelFormatDescriptor.iLayerType = PFD_MAIN_PLANE;
HDC FirstWindowDeviceContext = GetDC(FirstWindow);
if(FirstWindowDeviceContext == NULL)
puts("First window device context retrieving failed.\n");
int FirstWindowPixelFormat = ChoosePixelFormat(FirstWindowDeviceContext,
&FirstWindowPixelFormatDescriptor);
if(FirstWindowPixelFormat == 0)
puts("Choosing the first pixel format failed.\n");
if(SetPixelFormat(FirstWindowDeviceContext, FirstWindowPixelFormat,
&FirstWindowPixelFormatDescriptor) == FALSE)
puts("Setting the first pixel format failed.\n");
HGLRC FirstWindowRenderingContext =
wglCreateContext(FirstWindowDeviceContext);
if(FirstWindowRenderingContext == NULL)
puts("Creating the first rendering context failed.\n");
if(wglMakeCurrent(FirstWindowDeviceContext, FirstWindowRenderingContext) ==
FALSE)
puts("Making the first context current failed.\n");
if(glewInit() != GLEW_OK)
puts("Initialisation of GLEW failed.\n");
WNDCLASSEX FinalWindowClass = {};
FinalWindowClass.cbSize = sizeof(WNDCLASSEX);
FinalWindowClass.style = CS_OWNDC;
FinalWindowClass.lpfnWndProc = FinalWindowProcedure;
FinalWindowClass.lpszClassName = L"FinalWindowClass";
if(!RegisterClassEx(&FinalWindowClass))
puts("Registration of the final window class failed\n");
HWND FinalWindow = CreateWindowEx(WS_EX_APPWINDOW,
FinalWindowClass.lpszClassName, L"FinalWindow", WS_POPUP, 0, 0, 10, 10,
NULL, NULL, NULL, NULL);
if(FinalWindow == NULL)
puts("Creation of the final window failed.\n");
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB =
wglGetProcAddress("wglChoosePixelFormatARB");
if(wglChoosePixelFormatARB == NULL)
puts("Getting the wglChoosePixelFormatARB function pointer failed.\n");
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB =
(PFNWGLCREATECONTEXTATTRIBSARBPROC)
wglGetProcAddress("wglCreateContextAttribsARB");
if(wglCreateContextAttribsARB == NULL)
puts("Getting the wglCreateContextAttribsARB function pointer"
"failed.\n");
int FinalWindowContextAttributes[] = {
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
WGL_COLOR_BITS_ARB, 32,
WGL_DEPTH_BITS_ARB, 24,
WGL_STENCIL_BITS_ARB, 8,
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
WGL_CONTEXT_MINOR_VERSION_ARB, 4,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
0,
};
HDC FinalWindowDeviceContext = GetDC(FinalWindow);
if(FinalWindowDeviceContext == NULL)
puts("Retrieving the final window device cotext failed.\n");
int FinalWindowPixelFormat;
if(FALSE == wglChoosePixelFormatARB(FinalWindowDeviceContext,
FinalWindowContextAttributes, NULL, 1, &FinalWindowPixelFormat, NULL))
puts("Choosing the final window pixel format failed.\n");
HGLRC FinalWindowRenderingContext =
wglCreateContextAttribsARB(FinalWindowDeviceContext, NULL,
FinalWindowContextAttributes);
if(FinalWindowRenderingContext == NULL)
puts("Creating the final rendering context failed.\n");
if(FALSE == wglMakeCurrent(FinalWindowDeviceContext,
FinalWindowRenderingContext))
puts("Making the final context current failed.\n");
DWM_BLURBEHIND blur = {};
blur.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
blur.fEnable = 1;
blur.hRgnBlur = CreateRectRgn(0, 0, -1, -1);
DwmEnableBlurBehindWindow(FinalWindow, &blur);
SetLayeredWindowAttributes(FinalWindow, RGB(0, 0, 0), 255, LWA_COLORKEY);
// ----- ----- ----- //
/*WNDCLASSEX wcx = {};
wcx.cbSize = sizeof(WNDCLASSEX);
wcx.style = CS_OWNDC;
wcx.lpfnWndProc = WindowProcedure;
wcx.lpszClassName = L"Win32Class";
RegisterClassEx(&wcx);
HWND hWnd = CreateWindowEx(WS_EX_APPWINDOW | WS_EX_LAYERED, wcx.lpszClassName, L"Title",
WS_POPUP, 400, 300, 800, 400, NULL, NULL, NULL, NULL);
DWM_BLURBEHIND blur = {};
blur.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
blur.fEnable = 1;
blur.hRgnBlur = CreateRectRgn(0, 0, -1, -1);
DwmEnableBlurBehindWindow(hWnd, &blur);
SetLayeredWindowAttributes(hWnd, RGB(0, 0, 0), 255, LWA_COLORKEY);
PIXELFORMATDESCRIPTOR pfd = {};
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 24;
pfd.cStencilBits = 8;
pfd.iLayerType = PFD_MAIN_PLANE;
HDC DeviceContext = GetDC(hWnd);
int PixelFormat = ChoosePixelFormat(DeviceContext, &pfd);
SetPixelFormat(DeviceContext, PixelFormat, &pfd);
HGLRC RenderingContext = wglCreateContext(DeviceContext);
wglMakeCurrent(DeviceContext, RenderingContext);
glewInit();
int Attributes[] = {
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
WGL_COLOR_BITS_ARB, 32,
WGL_DEPTH_BITS_ARB, 24,
WGL_STENCIL_BITS_ARB, 8,
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
WGL_CONTEXT_MINOR_VERSION_ARB, 4,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
0,
};
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB =
wglGetProcAddress("wglChoosePixelFormatARB");
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB =
(PFNWGLCREATECONTEXTATTRIBSARBPROC)
wglGetProcAddress("wglCreateContextAttribsARB");
wglChoosePixelFormatARB(DeviceContext, Attributes, NULL, 1, &PixelFormat,
NULL);
RenderingContext = wglCreateContextAttribsARB(DeviceContext, NULL,
Attributes);
wglMakeCurrent(DeviceContext, RenderingContext);*/
char VertexShaderSource[] =
"#version 440 core\n"
"\n"
"layout(location = 0) in vec4 position;\n"
"\n"
"void main(){\n"
" gl_Position = position;\n"
"}";
char FragmentShaderSource[] =
"#version 440 core\n"
"\n"
"layout(location = 0) out vec4 colour;\n"
"\n"
"void main(){\n"
" colour = vec4(0.5, 0.5, 0.5, 1.0);\n"
"}";
float Verticies[] = {
0.0f, 0.5f, // top : 0
0.5f, 0.0f, // right : 1
0.0f, -0.5f, // bottom : 2
-0.5f, 0.0f // left : 3
};
unsigned int Indices[] = {
3, 0, 1, // top
3, 2, 1 // bottom
};
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
unsigned int VertexArray;
glGenVertexArrays(1, &VertexArray);
glBindVertexArray(VertexArray);
unsigned int VertexBuffer;
glGenBuffers(1, &VertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, VertexBuffer);
glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(float), Verticies, GL_STATIC_DRAW);
unsigned int IndexBuffer;
glGenBuffers(1, &IndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned int), Indices,
GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);
unsigned int ShaderProgram = CreateShaderProgram(VertexShaderSource,
FragmentShaderSource);
glUseProgram(ShaderProgram);
glViewport(0, 0, 800, 400);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
ShowWindow(FinalWindow, 1);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0)){
DispatchMessage(&msg);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);
wglSwapLayerBuffers(FinalWindowDeviceContext, WGL_SWAP_MAIN_PLANE);
}
}
LRESULT CALLBACK FirstWindowProcedure(HWND hWnd, UINT uMsg, WPARAM wp, LPARAM lp){
return DefWindowProc(hWnd, uMsg, wp, lp);
}
LRESULT CALLBACK FinalWindowProcedure(HWND hWnd, UINT uMsg, WPARAM wp, LPARAM lp){
switch(uMsg){
case WM_NCHITTEST: return HTCAPTION;
case WM_DESTROY: PostQuitMessage(0); return 0;
default: return DefWindowProc(hWnd, uMsg, wp, lp);
}
}
unsigned int CreateShader(char* Source, unsigned int Type);
unsigned int CreateShaderProgram(char* VertexSource,
char* FragmentSource){
unsigned int ShaderProgram = glCreateProgram(),
VertexShader = CreateShader(VertexSource, GL_VERTEX_SHADER),
FragmentShader = CreateShader(FragmentSource, GL_FRAGMENT_SHADER);
glAttachShader(ShaderProgram, VertexShader);
glAttachShader(ShaderProgram, FragmentShader);
glLinkProgram(ShaderProgram);
glValidateProgram(ShaderProgram);
return ShaderProgram;
}
unsigned int CreateShader(char* Source, unsigned int Type){
unsigned int Shader = glCreateShader(Type);
glShaderSource(Shader, 1, (const char* const*)&Source, NULL);
glCompileShader(Shader);
return Shader;
}