2012-07-16 158 views
-1

我的程序將視頻幀顯示爲OpenGL紋理。錯誤的OpenGL初始化

我有OpenGL初始化的問題。要看視頻,我需要開始渲染線程,停止它並重新開始。我想我在CRenderThread :: InitOpenGL()函數中缺少一些東西。我應該如何做正確的OpenGL初始化?

我的環境:

的Windows 7 64位系統

微軟的Visual Studio 2008 x64的

下面是代碼:

#include "RenderThread.h" 
#include <QtDebug> 
#include <vm_time.h> 

static Ipp32u UMCToInternalFormat(UMC::ColorFormat format) 
{ 
switch(format) 
{ 
case UMC::BGR24: return GL_BGR; 
case UMC::BGR32: return GL_BGRA; 
case UMC::RGB24: return GL_RGB; 
case UMC::RGB32: return GL_RGBA; 
} 
return 0; 
} 

CRenderThread::CRenderThread(const WId& rnWindowHandle) 
: m_bInitialized(false) 
, m_WindowHandle(rnWindowHandle) 
, m_Texture(0) 
, m_fTextureWidth(0.0f) 
, m_fTextureHeight(0.0f) 
, m_nFrameWidth(0) 
, m_nFrameHeight(0) 
, m_nWindowWidth(0) 
, m_nWindowHeight(0) 
{ 
} 

void CRenderThread::PrepareWork() 
{ 
// Wait until first frame comes 
if(!m_bAbort) 
    Suspend(); 
} 

void CRenderThread::DoOnStop() 
{ 
if(m_WindowGLResourceContext) 
{ 
    wglDeleteContext(m_WindowGLResourceContext); 
    m_WindowGLResourceContext = 0; 
} 
    ReleaseDC(m_WindowHandle, m_WindowDC); 

if(m_Texture) 
{ 
    glDeleteTextures(1, &m_Texture); 
    m_Texture = 0; 
} 
} 

void CRenderThread::InitOpenGL() 
{ 
PIXELFORMATDESCRIPTOR pfd = { 
    sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 
    PFD_TYPE_RGBA, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 
}; 

m_WindowDC = GetDC(m_WindowHandle); 
if(!m_WindowDC) 
    return; 

if(!SetPixelFormat(m_WindowDC, ChoosePixelFormat(m_WindowDC, &pfd), &pfd)) 
    return; 

m_WindowGLResourceContext = wglCreateContext(m_WindowDC); // create rendering context 
if(!m_WindowGLResourceContext) 
    return; 

if(!wglMakeCurrent(m_WindowDC, m_WindowGLResourceContext)) // set it as current 
    return; 

// OpenGL context already tied to output window 
// to disable all slow GL components 
// it is not mandatory to disable all if we have accelerated card 
glClearColor(0.0f, 170.0f, 255.0f, 1.0f); 
glClearDepth(1.0); 
glDepthFunc(GL_NEVER); 

// disable slow GL extensions 
glDisable(GL_DEPTH_TEST); glDisable(GL_ALPHA_TEST); glDisable(GL_BLEND); 
glDisable(GL_DITHER);  glDisable(GL_FOG);   glDisable(GL_STENCIL_TEST); 
glDisable(GL_LIGHTING); glDisable(GL_LOGIC_OP);  glDisable(GL_TEXTURE_1D); 
glDisable(GL_TEXTURE_2D); 

glPixelTransferi(GL_MAP_COLOR, GL_FALSE); 
glPixelTransferi(GL_RED_SCALE, 1); glPixelTransferi(GL_RED_BIAS, 0); 
glPixelTransferi(GL_GREEN_SCALE, 1); glPixelTransferi(GL_GREEN_BIAS, 0); 
glPixelTransferi(GL_BLUE_SCALE, 1); glPixelTransferi(GL_BLUE_BIAS, 0); 
glPixelTransferi(GL_ALPHA_SCALE, 1); glPixelTransferi(GL_ALPHA_BIAS, 0); 

glEnable(GL_TEXTURE_2D); 
glGenTextures(1, &m_Texture); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 

glViewport(0, 0, m_nWindowWidth, m_nWindowHeight); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
glRasterPos2i(-1, 1);  // move to the upper left corner 
glPixelZoom(1.0, -1.0);  // top to bottom 

SwapBuffers(m_WindowDC); 

m_bInitialized = true; 
} 

void CRenderThread::SetRenderFrame(PVideoData pFrame) 
{ 
Q_ASSERT(pFrame.get()); 
{ 
    //boost::mutex::scoped_lock Lock(m_FrameMutex); 
    m_pFrameToRender = pFrame; 
} 

// Resume thread to render current frame 
Resume(); 
} 

void CRenderThread::DoWork() 
{ 
IppiSize CurWinSize; 
UMC::Status nStatus = UMC::UMC_OK; 

::RECT rect; 
GetClientRect(m_WindowHandle, &rect); 
CurWinSize.height = rect.bottom; 
CurWinSize.width = rect.right; 

if(!m_bInitialized) 
    InitOpenGL(); 

if(CurWinSize.width > IPP_MAX_16S || CurWinSize.height > IPP_MAX_16S) // window seems to be destroyed 
    return; 

// reinit buffers if window size has been changed 
if(CurWinSize.height != m_nWindowHeight || CurWinSize.width != m_nWindowWidth) 
{ 
    m_nWindowWidth = CurWinSize.width; 
    m_nWindowHeight = CurWinSize.height; 

    glViewport(0, 0, m_nWindowWidth, m_nWindowHeight); 
} 

// Render frame 
{ 
    //boost::mutex::scoped_lock Lock(m_FrameMutex); 
    if(m_pFrameToRender.get()) 
    { 
     if(m_nWindowWidth && m_nWindowHeight) 
     { 
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

      m_nFrameWidth = m_pFrameToRender->GetWidth(); 
      m_nFrameHeight = m_pFrameToRender->GetHeight(); 
      m_nRenderFormat = UMCToInternalFormat(m_pFrameToRender->GetColorFormat()); 

      glTexImage2D(GL_TEXTURE_2D, 0, 3, m_nFrameWidth, m_nFrameHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, m_pFrameToRender->GetBufferPointer()); 
      //glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_nFrameWidth, m_nFrameHeight, m_nRenderFormat, GL_UNSIGNED_BYTE, m_pFrameToRender->GetBufferPointer()); 

      glBegin(GL_POLYGON); 
      glTexCoord2i(0, 0); glVertex2f(-1.0, 1.0); 
      glTexCoord2i(1, 0); glVertex2f(1.0, 1.0); 
      glTexCoord2i(1, 1); glVertex2f(1.0, -1.0); 
      glTexCoord2i(0, 1); glVertex2f(-1.0, -1.0); 
      glEnd(); 

      glFlush(); 

      SwapBuffers(m_WindowDC); // to draw on physical screen 
     } 
    } 
} 

// Wait for next frame to render 
if(!m_bAbort) 
    Suspend(); 
} 
+1

它看起來好像你試圖從多個線程訪問單個GL上下文。是這樣嗎? – genpfault 2012-07-16 16:15:10

+0

不,從函數體中調用創建OpenGL上下文的函數CRenderThread :: InitOpenGL()。 – Thomas13 2012-07-17 04:36:21

回答

2

夫婦的想法,不一定都是相關的到您的問題:

glClearColor(0.0f, 170.0f, 255.0f, 1.0f);

清除顏色被鉗位到的[0,1]的範圍內,不[0,255]。


// disable slow GL extensions 
glDisable(GL_DEPTH_TEST); glDisable(GL_ALPHA_TEST); glDisable(GL_BLEND); 
glDisable(GL_DITHER);  glDisable(GL_FOG);   glDisable(GL_STENCIL_TEST); 
glDisable(GL_LIGHTING); glDisable(GL_LOGIC_OP);  glDisable(GL_TEXTURE_1D); 
glDisable(GL_TEXTURE_2D); 

這些(和最重要OpenGL設置)默認情況下禁用。這些都無所作爲。雖然沒有傷害任何東西。


glPixelTransferi(GL_MAP_COLOR, GL_FALSE); 
glPixelTransferi(GL_RED_SCALE, 1); glPixelTransferi(GL_RED_BIAS, 0); 
glPixelTransferi(GL_GREEN_SCALE, 1); glPixelTransferi(GL_GREEN_BIAS, 0); 
glPixelTransferi(GL_BLUE_SCALE, 1); glPixelTransferi(GL_BLUE_BIAS, 0); 
glPixelTransferi(GL_ALPHA_SCALE, 1); glPixelTransferi(GL_ALPHA_BIAS, 0); 

再次,這些所有的默認值。


glEnable(GL_TEXTURE_2D); 
glGenTextures(1, &m_Texture); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 

這實際上可能是一個真正的問題。 glTexParameter只會影響當前綁定的紋理,但您在此處調用它們時不會綁定紋理。所以這些什麼都不做。當你實際上稍後使用紋理時,它將在最小過濾器上設置mipmapping,這可能會導致它不顯示。將您的glTexParameter調用移到您希望它們生效的紋理上之後。

+0

蒂姆,不幸的是這並沒有幫助。我在CRenderThread :: DoWork()中的glTexImage2D之前移動了紋理gereration和綁定,但行爲保持不變 - 我需要重新啓動線程才能看到視頻。 – Thomas13 2012-07-17 04:39:49