[英]OpenGL drawing to an existing HDC using Texture2D
我正在嘗試使用OpenGL渲染到已使用Windows API創建的窗口的現有渲染區域。 我得到了HDC,並使用wglCreateContext和wglMakeCurrent創建了一個opengl上下文。 然后創建紋理並綁定它。 盡管我可以將緩沖區清除為選擇的任何顏色,但無法對其進行渲染。 以下代碼示例應明確我的問題所在。
void draw(HDC dhdc){
static unsigned char render_on_device_image_once, odd;
static GLuint texture_id;
size_t sz;
odd = (odd + 1) % 2;
if(!render_on_device_image_once){
// DO ONCE
render_on_device_image_once = 1;
GLubyte pixels[] =
{
0, 0, 0, 255, 255, 255,
255, 255, 255, 0, 0, 0,
};
glGenTextures(1, &texture_id);
glBindTexture(GL_TEXTURE_2D, texture_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if(odd)
glClearColor(0.0, 0.0, 0.5, 1.0);
else
glClearColor(0.5, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glTranslatef(0, 0, -5);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture_id);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glTexCoord2f(1.0, 0.0);
glVertex3f(1.0, 0.0, 0.0);
glTexCoord2f(1.0, 1.0);
glVertex3f(1.0, 1.0, 0.0);
glTexCoord2f(0.0, 1.0);
glVertex3f(0.0, 1.0, 0.0);
glEnd();
glDisable(GL_TEXTURE_2D);
SwapBuffers(dhdc);}
上面的代碼是我從此答案中提取的(並稍作修改),使窗口區域在紅色和藍色之間切換,但不渲染四邊形。 有沒有人遇到過類似的問題,或者可以發現我的錯誤?
謝謝。
編輯:
為了添加更多信息,我將HDC的像素格式設置為此:
static PIXELFORMATDESCRIPTOR window_pixel_format_desc =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, //Flags
PFD_TYPE_RGBA, //The kind of framebuffer. RGBA or palette.
8, //Colordepth of the framebuffer.
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
32, //Number of bits for the depthbuffer
0, //Number of bits for the stencilbuffer
0, //Number of Aux buffers in the framebuffer.
PFD_MAIN_PLANE,
0,
0, 0, 0
};
兩件事情。
首先,您永遠不會調用glViewport
。 您需要執行此操作以設置渲染表面的大小。 視口應設置為使用整個窗口,因此您需要使用Win32函數來查詢窗口的客戶端大小。
其次是:
glTranslatef(0, 0, -5);
為什么在那里? 這沒有用,它會使三角形的Z分量變為-5。 在OpenGL的默認狀態下,該范圍不在[-1,1] Z范圍內。
首先,最重要的是,如果您的目標是“將像素從OpenGL轉換為DC”,那么通過Window DC進行處理將非常有問題。 對於一個,您完全依賴於窗口像素管理。 像素所有權,窗口可見性,窗口裁剪等都可能對渲染結果產生負面影響。
要考慮的另一重要事項是,您只能設置一個窗口的像素格式一次 ! 對於屏幕外渲染,您有2個選項(或3個選項,具體取決於主機系統是否支持EGL,而EGL環境為您提供屏幕外渲染):
創建一個隱藏/不可見的幫助程序窗口,以為OpenGL提供DC服務並渲染為幀緩沖區對象 。 到目前為止,這是當前數據(2016年)的首選解決方案
創建一個PBuffer為OpenGL提供DC服務並渲染到該DC
創建屏幕外的EGL上下文。 屏幕外EGL可以支持直接屏幕外表面,因此不需要幀緩沖區對象。 或者沒有主表面的屏幕外上下文,因此嚴格要求幀緩沖對象。
在上述選項中, 只有 PBuffer方法為您提供了在DC之間可靠地使用BitBlt的方法。 但是,創建PBuffers就像創建不可見窗口一樣容易/困難,而framebuffer對象則為您提供了更多的控制權。 另外,與PBuffers不同的是,禁止幀緩沖區對象目標的內容(紋理或渲染緩沖區)突然“消失”(PBuffers隨時可能變為無效)。
將圖像從OpenGL中提取出來並用於DC操作的最可靠方法是創建DIBSECTION( CreateDIBSection )並使用glReadPixels將圖像數據讀入其中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.