gpt4 book ai didi

c++ - OpenGL 4 核心配置文件、着色器和 MFC

转载 作者:搜寻专家 更新时间:2023-10-31 00:34:06 25 4
gpt4 key购买 nike

我正在尝试让着色器在具有 OpenGL 4 核心配置文件的 MFC 应用程序中工作。

我在 Win32 应用程序中执行此操作以确保其正常工作(确实如此,在窗口的下部绘制了一个三角形):

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;

hInst = hInstance; // Store instance handle in our global variable

hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

if (!hWnd)
{
return FALSE;
}

m_hDC = ::GetDC(hWnd);

PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 32;
pfd.iLayerType = PFD_MAIN_PLANE;

int nPixelFormat = ChoosePixelFormat(m_hDC, &pfd);

if (nPixelFormat == 0) return false;

BOOL bResult = SetPixelFormat(m_hDC, nPixelFormat, &pfd);

if (!bResult) return false;

HGLRC tempContext = wglCreateContext(m_hDC);
wglMakeCurrent(m_hDC, tempContext);

GLenum err = glewInit();
if (GLEW_OK != err)
{
MessageBox(hWnd, (LPCWSTR)L"Glew not initialized", (LPCWSTR)L"Error", MB_ICONEXCLAMATION);
}

//Get a GL 4,2 context
int attribs[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
WGL_CONTEXT_MINOR_VERSION_ARB, 2,
WGL_CONTEXT_FLAGS_ARB, 0,
0
};

if (wglewIsSupported("WGL_ARB_create_context") == 1)
{
m_hRC = wglCreateContextAttribsARB(m_hDC, 0, attribs);
wglMakeCurrent(NULL, NULL);
wglDeleteContext(tempContext);
wglMakeCurrent(m_hDC, m_hRC);
}
else
{ //It's not possible to make a GL 4.x context. Use the old style context (GL 2.1 and before)
m_hRC = tempContext;
}


if (!m_hRC) return false;

static const char * vs_source[] =
{
"#version 420 core \n"
" \n"
"void main(void) \n"
"{ \n"
" const vec4 vertices[] = vec4[](vec4( 2.25, -2.25, 0.5, 1.0), \n"
" vec4(-2.25, -2.25, 0.5, 1.0), \n"
" vec4( 2.25, 2.25, 0.5, 1.0)); \n"
" \n"
" gl_Position = vertices[gl_VertexID]; \n"
"} \n"
};

static const char * fs_source[] =
{
"#version 420 core \n"
" \n"
"out vec4 color; \n"
" \n"
"void main(void) \n"
"{ \n"
" color = vec4(1.0, 0.8, 1.0, 1.0); \n"
"} \n"
};

program = glCreateProgram();
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, fs_source, NULL);
glCompileShader(fs);

GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, vs_source, NULL);
glCompileShader(vs);

glAttachShader(program, vs);
glAttachShader(program, fs);

glLinkProgram(program);

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

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

return TRUE;
}


const GLfloat green[] = { 0.0f, 0.25f, 0.0f, 1.0f };
//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;

switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
//hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...

glClearBufferfv(GL_COLOR, 0, green);

glUseProgram(program);
glDrawArrays(GL_TRIANGLES, 0, 3);

SwapBuffers(m_hDC);

//EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

然后我在 MFC MDI 程序中做了同样的事情,虽然背景被清除为与 Win32 应用程序相同的颜色,但着色器没有绘制任何东西。

为了完成,这是我的 MFC MDI View 类中的相关代码(它与 Win32 应用程序中的代码不同,因为我一直试图找出问题所在,但它曾经与 Win32 应用程序代码相同并且它没有用):

int CMFCApplication2View::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;

// TODO: Add your specialized creation code here
m_hDC = ::GetDC(m_hWnd);

PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 24;
pfd.iLayerType = PFD_MAIN_PLANE;

int nPixelFormat = ChoosePixelFormat(m_hDC, &pfd);

if (nPixelFormat == 0) return false;

BOOL bResult = SetPixelFormat(m_hDC, nPixelFormat, &pfd);

if (!bResult) return false;

HGLRC tempContext = wglCreateContext(m_hDC);
wglMakeCurrent(m_hDC, tempContext);


glewExperimental = GL_TRUE;
GLenum err = glewInit();
if (GLEW_OK != err)
{
AfxMessageBox(_T("GLEW is not initialized!"));
}

//This is a modern pixel format attribute list.
//It has an extensible structure. Just add in more argument pairs
//befroe the null to request more features.
const int attribList[] =
{
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
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,
0, 0 //End
};


unsigned int numFormats;
int pixelFormat;
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));

//Select a pixel format number
wglChoosePixelFormatARB(m_hDC, attribList, NULL, 1, &pixelFormat, &numFormats);

//Optional: Get the pixel format's description. We must provide a
//description to SetPixelFormat(), but its contents mean little.
//According to MSDN:
// The system's metafile component uses this structure to record the logical
// pixel format specification. The structure has no other effect upon the
// behavior of the SetPixelFormat function.
//DescribePixelFormat(m_pDC->GetSafeHdc(), pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);

//Set it as the current
if (FALSE == SetPixelFormat(m_hDC, pixelFormat, &pfd))
{

}



//Get a GL 4,4 context
int attribs[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 2,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
//WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
0, 0 //End
};

if (wglewIsSupported("WGL_ARB_create_context") == 1)
{
m_hRC = wglCreateContextAttribsARB(m_hDC, 0, attribs);
wglMakeCurrent(NULL, NULL);
wglDeleteContext(tempContext);
wglMakeCurrent(m_hDC, m_hRC);
}
else
{ //It's not possible to make a GL 4.x context. Use the old style context (GL 2.1 and before)
m_hRC = tempContext;
}


if (!m_hRC) return false;

static const char * vs_source[] =
{
"#version 150 core \n"
" \n"
"void main(void) \n"
"{ \n"
" const vec4 vertices[] = vec4[](vec4( 2.25, -2.25, 0.5, 1.0), \n"
" vec4(-2.25, -2.25, 0.5, 1.0), \n"
" vec4( 2.25, 2.25, 0.5, 1.0)); \n"
" \n"
" gl_Position = vertices[gl_VertexID]; \n"
"} \n"
};

static const char * fs_source[] =
{
"#version 150 core \n"
" \n"
"out vec4 color; \n"
" \n"
"void main(void) \n"
"{ \n"
" color = vec4(1.0, 0.8, 1.0, 1.0); \n"
"} \n"
};

program = glCreateProgram();
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, fs_source, NULL);
glCompileShader(fs);

GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, vs_source, NULL);
glCompileShader(vs);

glAttachShader(program, vs);
glAttachShader(program, fs);

glLinkProgram(program);

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

wglMakeCurrent(NULL, NULL);

return 0;
}



void CMFCApplication2View::OnDraw(CDC*/* pDC*/)
{
CMFCApplication2Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;

// TODO: add draw code for native data here
// Make the rendering context current
wglMakeCurrent(m_hDC, m_hRC);

// TODO: add draw code for native data here
static const GLfloat green[] = { 1.0f, 0.0f, 0.0f, 1.0f };
glClearBufferfv(GL_COLOR, 0, green);

glUseProgram(program);
glDrawArrays(GL_TRIANGLES, 0, 3);

SwapBuffers(m_hDC);

// Allow other rendering contexts to coexist
wglMakeCurrent(NULL, NULL);

}

我通过 AMD 的 GPU Perfstudio 运行了这两个可执行文件。 Win32 框架调试显示一切正常。 MFC 帧调试显示帧缓冲区大小为 0(win32 应用程序的帧缓冲区大小为窗口大小)。两个应用程序 API 跟踪是相同的。

知道会发生什么吗?

最佳答案

显然,MFC 中的 OpenGL 在使用核心配置文件时需要通过 glViewport 设置视口(viewport)。

处理 WM_SIZE 并执行 glViewport(0, 0, (GLsizei)cx, (GLsizei)cy) 解决了这个问题。

请注意,Andon 说我不应该指定像素格式两次是正确的。它没有给出任何错误,这很奇怪,但是当我删除它时,一切都继续工作。

关于c++ - OpenGL 4 核心配置文件、着色器和 MFC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26949823/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com