繁体   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