gpt4 book ai didi

c# - C# 中的 OpenGL 包装器

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:08:53 26 4
gpt4 key购买 nike

我编写了一个简单的类来创建一个窗口并将 OpenGL 初始化为该窗口。它在 native c++ 和 CLI 中也能正常工作。但是,一旦我将 CLI 类作为 DLL 导入到我的 C# 项目中,渲染就会失败。出现一个空白窗口,但渲染不起作用。 SwapBuffers 和 GL 渲染被调用但没有任何反应。你知道什么是错的吗?(对不起,我不是母语人士)

OpenGLClass.cpp

#include "OpenGLClass.h"
#include <iostream>

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

OpenGLClass::OpenGLClass()
{
}


OpenGLClass::~OpenGLClass()
{
}

bool OpenGLClass::Initialize()
{
if (InitWindow())
return InitOGL();
else
return false;
}

void OpenGLClass::Run()
{
MSG msg = { 0 };
while (true)
{
if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break;

TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
Render();
SwapBuffers(m_hDevContext);
}
}
}

void OpenGLClass::Render()
{
glViewport(0, 0, 800, 600);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (float)800 / (float)600, 1, 1000);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

gluLookAt(0, 0, 10,
0, 0, 0,
0, 1, 0);

glClearColor(0.2, 0.5, 0.8, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

static float i = 0.01f;

i += 0.001f;

float c = cos(i);
float s = sin(i);

glBegin(GL_TRIANGLES);
glColor3f(c, 0, 0); // red
glVertex3f(1 + c, 0 + s, 0);

glColor3f(c, s, 0); // yellow
glVertex3f(0 + c, 1 + s, 0);

glColor3f(s, 0.1f, s); // magenta
glVertex3f(-1 + c, 0 + s, 0);
glEnd();
}

bool OpenGLClass::InitWindow()
{
WNDCLASSEX wc;

m_hInstance = GetModuleHandle(NULL);

wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = m_hInstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hIconSm = wc.hIcon;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "OpenGLWindow";
wc.cbSize = sizeof(WNDCLASSEX);

if (!RegisterClassEx(&wc))
{
MessageBox(NULL, "RegisterClassEx() failed", "Error", MB_OK);
return false;
}

int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int screenHeight = GetSystemMetrics(SM_CYSCREEN);

screenWidth = 800;
screenHeight = 600;
int nStyle = WS_POPUP;


m_hwnd = CreateWindowEx(WS_EX_APPWINDOW, "OpenGLWindow", "WindowTitle", nStyle, 0, 0, screenWidth, screenHeight, NULL, NULL, m_hInstance, NULL);


ShowWindow(m_hwnd, SW_SHOW);
return true;
}

bool OpenGLClass::InitOGL()
{
m_hDevContext = GetDC(m_hwnd);


PIXELFORMATDESCRIPTOR pfd = { 0 };
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 = 24;

int format = ChoosePixelFormat(m_hDevContext, &pfd);
if (format == 0)
return false;

std::cout << "Pixel Format: " << format << std::endl;

if (!SetPixelFormat(m_hDevContext, format, &pfd))
return false;


m_GLRenderContext = wglCreateContext(m_hDevContext);
if (!wglMakeCurrent(m_hDevContext, m_GLRenderContext))
return false;
GLint GlewInitResult = glewInit();
if (GLEW_OK != GlewInitResult)
{
return false;
}

glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);


return true;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;

switch (message)
{
case WM_KEYDOWN:
if (wParam == VK_ESCAPE)
{
PostQuitMessage(0);
DestroyWindow(hwnd);
}
break;
case WM_CLOSE:
PostQuitMessage(0);
DestroyWindow(hwnd);
break;

default:
return DefWindowProc(hwnd, message, wParam, lParam);
}

return 0;
}

WrapperClass.h

#pragma once
#include <OpenGLClass.h>

public ref class WrapperClass
{
public:
WrapperClass() : m_Impl(new OpenGLClass) {}

~WrapperClass() {
delete m_Impl;
}

protected:
!WrapperClass() {
delete m_Impl;
}

public:

inline bool Initialize()
{
return m_Impl->Initialize();
}


inline void Run()
{
m_Impl->Run();
}

private:
OpenGLClass* m_Impl;
};

C#代码

namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
BackgroundWorker bw = new BackgroundWorker();
WrapperClass wc;

public Form1()
{
InitializeComponent();
InitOGL();
}

private void InitOGL()
{
wc = new WrapperClass();
if(wc.Initialize())
{
bw.DoWork += Bw_DoWork;
bw.RunWorkerAsync();
}
}

private void Bw_DoWork(object sender, DoWorkEventArgs e)
{
wc.Run();
}
}
}

最佳答案

作为BDLstarmole指出,我在不同的线程上运行 InitOGL 和 Render。

关于c# - C# 中的 OpenGL 包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45097185/

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