簡體   English   中英

OpenGL使用Texture2D繪制到現有的HDC

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM