2013-09-23 4 views
2

У меня есть небольшая структура, которая отображает текстуру в окне без полей, но когда я ее запускаю, приложение показывает значок занятой мыши, когда я активирую окно OpenGL, и я не могу понять, где это исходит из.Окно OpenGL всегда занято

Следующий код является полным решением (Visual Studio 2010) и должен компилироваться как есть. К сожалению, я даже не знаю, с чего начать, поэтому я скопировал полный код здесь. BasicProject создает случайную текстуру и передает ее в окно OpenGL.

Может ли кто-нибудь понять, почему код застрял в загруженном окне? Обратные вызовы OpenGL никогда не достигаются, но я не понимаю, почему нет.

BasicProject.cpp (точка входа):

/** Sample Project for OpenGL-Display functionality 
* 
* Anton Roth, 2013 
*/ 

#include "stdafx.h" 
#include <conio.h> 
#include <process.h> 
#include <vector> 
#include <Windows.h> 
#include <cstdlib> 
#include <ctime> 
#include "OpenGL-Display.h" 

void RunOpenGL(void* pParams); 
bool applicationRunning = true; 
HANDLE threadOGL; 

int _tmain(int argc, _TCHAR* argv[]) { 
    OGD::OpenGLDisplay_Init(640, 480, 200, 200, 0, "First Display"); 
    threadOGL = (HANDLE)_beginthread(RunOpenGL, 0, NULL); 

    while(!_kbhit()) { 
     Sleep(500); 
    } 

    applicationRunning = false; 
    WaitForSingleObject(threadOGL, 500); 

    return 0; 
} 

void RunOpenGL(void* pParams) { 
    std::vector<char> texture; 
    texture.resize(640 * 480 * 3); 
    std::srand(time(0)); 

    while(applicationRunning) { 
     for(int i = 0; i < 640 * 480 * 3; ++i) { 
      texture.at(i) = std::rand() % 255; 
     } 

     OGD::OpenGLDisplay_Wrapper(&texture.at(0), 640, 480, false, 24, 0); 
     int x, y; 
     OGD::OpenGLDisplay_MousePos(x, y, 0); 
     Sleep(300); 
    } 
} 

OpenGL-Display.h:

#ifndef __OPENGLDISPLAY 
#define __OPENGLDISPLAY 
#include <windows.h>  // Header File For Windows 
#include <stdio.h>   // Header File For Standard Input/Output 
#include <gl\gl.h>   // Header File For The OpenGL32 Library 
#include <gl\glu.h>   // Header File For The GLu32 Library 
#include <vector> 

namespace OGD 
{ 
    class OpenGL_Display 
    { 
     public: 
      OpenGL_Display(int newId); 
      ~OpenGL_Display(); 
      void Init_Display(int width, int height, int posX, int posY, LPCSTR className); 
      void DrawNewImage(int width, int height, char* imageData, bool flip, int bpp); 
      void GetMouseCords(int& x, int& y); 
      int ID; 
     protected: 
      bool CreateGLWindow(char* title, int bits, int posX, int posY, LPCSTR className); 
      GLvoid ReSizeGLScene(GLsizei width, GLsizei height); 
      int LoadGLTextures(); 
      int InitGL(GLvoid); 
      void UpdateGLBuffers(int width, int height, char* imageData, int bpp); 
      int DrawGLScene(bool flip); 
      GLvoid KillGLWindow(GLvoid); 
      HDC   hDC;  // Private GDI Device Context 
      static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc 

      HGLRC  hRC;  // Permanent Rendering Context 
      HWND  hWnd;  // Holds Our Window Handle 
      HINSTANCE hInstance;  // Holds The Instance Of The Application 

      bool keys[256];   // Array Used For The Keyboard Routine 
      bool active;  // Window Active Flag Set To TRUE By Default 
      bool fullscreen; // Fullscreen Flag Set To Fullscreen Mode By Default 
      bool g_bExitThread; // end thread 
      GLuint texture;   // Bitmap image buffer 
      int  g_iCounter;  // Current buffer being grabbed to 
      bool g_GLdone; // Counter to make sure no unnecessary updates are made which cause CPU load 
      int xPos; 
      int yPos; 
      int xPos_right; 
      int yPos_right; 
      int width; 
      int height; 
    }; 

    static std::vector<OGD::OpenGL_Display*> oglDisp; 

    void OpenGLDisplay_Wrapper(char* image, int width, int height, bool flip, int bpp, int ID); 
    void OpenGLDisplay_Init(int width, int height, int posX, int posY, int ID, LPCSTR className); 
    void OpenGLDisplay_MousePos(int&x, int&y, int ID); 
}; 

#endif 

OpenGL-Display.cpp:

/** Based on code by NeHe tutorials 
    Adapted to display live camera display with OpenGL 
*/ 

#include "OpenGL-Display.h" 

using namespace OGD; 

OpenGL_Display::OpenGL_Display(int newId) 
{ 
    xPos = -1; 
    yPos = -1; 
    ID = newId; 
    width = 1; 
    height = 1; 
} 

OpenGL_Display::~OpenGL_Display() 
{ 
    KillGLWindow(); 
} 

void OpenGL_Display::Init_Display(int newWidth, int newHeight, int posX, int posY, LPCSTR inputName) 
{ 
    width = newWidth; 
    height = newHeight; 
    className = inputName; 

    if (!CreateGLWindow((char*)className, 24, posX, posY, className)) 
    { 
     throw; 
    } 
} 

LRESULT CALLBACK OpenGL_Display::WndProc( HWND hWnd,   // Handle For This Window 
          UINT uMsg,   // Message For This Window 
          WPARAM wParam,   // Additional Message Information 
          LPARAM lParam)   // Additional Message Information 
{ 
    switch (uMsg)         // Check For Windows Messages 
    { 
     case WM_SYSCOMMAND:       // Intercept System Commands 
     { 
      switch (wParam)       // Check System Calls 
      { 
       case SC_SCREENSAVE:     // Screensaver Trying To Start? 
       case SC_MONITORPOWER:    // Monitor Trying To Enter Powersave? 
       return 0;       // Prevent From Happening 
      } 
      break;         // Exit 
     } 

     case WM_CLOSE:        // Did We Receive A Close Message? 
     { 
      PostQuitMessage(0);      // Send A Quit Message 
      return 0;        // Jump Back 
     } 

     case WM_SIZE:        // Resize The OpenGL Window 
     { 
      oglDisp.at(0)->ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord=Width, HiWord=Height 
      return 0;        // Jump Back 
     } 
    } 

    // Pass All Unhandled Messages To DefWindowProc 
    return DefWindowProc(hWnd,uMsg,wParam,lParam); 
} 


bool OpenGL_Display::CreateGLWindow(char* title, int bits, int posX, int posY, LPCSTR className) 
{ 
    GLuint  PixelFormat;   // Holds The Results After Searching For A Match 
    WNDCLASS wc;      // Windows Class Structure 
    DWORD  dwExStyle;    // Window Extended Style 
    DWORD  dwStyle;    // Window Style 
    RECT  WindowRect;    // Grabs Rectangle Upper Left/Lower Right Values 
    WindowRect.left=(long)0;   // Set Left Value To 0 
    WindowRect.right=(long)width;  // Set Right Value To Requested Width 
    WindowRect.top=(long)0;    // Set Top Value To 0 
    WindowRect.bottom=(long)height;  // Set Bottom Value To Requested Height 

    hInstance   = GetModuleHandle(NULL);    // Grab An Instance For Our Window 
    wc.style   = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Size, And Own DC For Window. 
    wc.lpfnWndProc  = WndProc;        // WndProc Handles Messages 
    wc.cbClsExtra  = 0;         // No Extra Window Data 
    wc.cbWndExtra  = 0;         // No Extra Window Data 
    wc.hInstance  = hInstance;       // Set The Instance 
    wc.hIcon   = LoadIcon(NULL, IDI_WINLOGO);   // Load The Default Icon 
    wc.hCursor   = LoadCursor(NULL, IDC_ARROW);   // Load The Arrow Pointer 
    wc.hbrBackground = NULL;         // No Background Required For GL 
    wc.lpszMenuName  = NULL;         // We Don't Want A Menu 
    wc.lpszClassName = className;        // Set The Class Name 

    RegisterClass(&wc);           // Return FALSE 

    dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;   // Window Extended Style 
    dwStyle=WS_VISIBLE | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;;       // Windows Style 

    AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);  // Adjust Window To True Requested Size 
    //HWND hwndC = GetConsoleWindow(); 
    // Create The Window 
    hWnd=CreateWindowEx( dwExStyle,       // Extended Style For The Window 
           className,       // Class Name 
           title,        // Window Title 
           //WS_OVERLAPPEDWINDOW, 
           dwStyle |       // Defined Window Style 
           WS_CLIPSIBLINGS |     // Required Window Style 
           WS_CLIPCHILDREN,     // Required Window Style 
           posX, posY,       // Window Position 
           WindowRect.right-WindowRect.left, // Calculate Window Width 
           WindowRect.bottom-WindowRect.top, // Calculate Window Height 
           NULL,        // No Parent Window 
           NULL,        // No Menu 
           hInstance,       // Instance 
           NULL); 

    static PIXELFORMATDESCRIPTOR pfd=    // pfd Tells Windows How We Want Things To Be 
    { 
     sizeof(PIXELFORMATDESCRIPTOR),    // Size Of This Pixel Format Descriptor 
     1,           // Version Number 
     PFD_DRAW_TO_WINDOW |      // Format Must Support Window 
     PFD_SUPPORT_OPENGL |      // Format Must Support OpenGL 
     PFD_DOUBLEBUFFER,       // Must Support Double Buffering 
     PFD_TYPE_RGBA,        // Request An RGBA Format 
     bits,          // Select Our Color Depth 
     0, 0, 0, 0, 0, 0,       // Color Bits Ignored 
     0,           // No Alpha Buffer 
     0,           // Shift Bit Ignored 
     0,           // No Accumulation Buffer 
     0, 0, 0, 0,         // Accumulation Bits Ignored 
     16,           // 16Bit Z-Buffer (Depth Buffer) 
     0,           // No Stencil Buffer 
     0,           // No Auxiliary Buffer 
     PFD_MAIN_PLANE,        // Main Drawing Layer 
     0,           // Reserved 
     0, 0, 0          // Layer Masks Ignored 
    }; 

    hDC=GetDC(hWnd); 

    PixelFormat=ChoosePixelFormat(hDC,&pfd); 

    SetPixelFormat(hDC,PixelFormat,&pfd); 

    hRC=wglCreateContext(hDC); 

    wglMakeCurrent(hDC,hRC); 

    ShowWindow(hWnd,SW_SHOW);      // Show The Window 
    SetForegroundWindow(hWnd);      // Slightly Higher Priority 
    SetFocus(hWnd);         // Sets Keyboard Focus To The Window 
    ReSizeGLScene(width, height);     // Set Up Our Perspective GL Screen 

    InitGL(); 

    return TRUE;         // Success 
} 


int OpenGL_Display::LoadGLTextures()         // Load Bitmaps And Convert To Textures 
{ 
    // Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit 

    glGenTextures(1, &texture);     // Create The Texture 
    // Typical Texture Generation Using Data From The Bitmap 
    glBindTexture(GL_TEXTURE_2D, texture); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); // Minimizing filter, in case display is smaller image size 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); // Magnifying filter, in case display is smaller image size 

    return 1;          // Return The Status 
} 

GLvoid OpenGL_Display::ReSizeGLScene(GLsizei newWidth, GLsizei newHeight)  // Resize And Initialize The GL Window 
{ 
    width = newWidth; 
    height = newHeight; 
} 

int OpenGL_Display::InitGL(GLvoid)          // All Setup For OpenGL Goes Here 
{ 
    if (!LoadGLTextures())        // Jump To Texture Loading Routine 
    { 
     return FALSE;         // If Texture Didn't Load Return FALSE 
    } 

    return TRUE;          // Initialization Went OK 
} 

void OpenGL_Display::GetMouseCords(int& x, int& y)  // All Setup For OpenGL Goes Here 
{ 
    x = xPos; 
    y = yPos; 
} 

void OpenGL_Display::UpdateGLBuffers(int width, int height, char* imageData, int bpp) { 
    glBindTexture(GL_TEXTURE_2D, texture); 
    switch(bpp) { 
    case 8: glTexImage2D(GL_TEXTURE_2D, 0, GL_INTENSITY, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, imageData); break; 
    case 16: glTexImage2D(GL_TEXTURE_2D, 0, GL_INTENSITY, width, height, 0, GL_RED, GL_UNSIGNED_SHORT, imageData); break; 
    case 24: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, imageData); break; 
    default: return; 
    } 

    GLenum mError = glGetError(); 

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); 
} 

int OpenGL_Display::DrawGLScene(bool flip)         // Here's Where We Do All The Drawing 
{ 
    if (height==0)          // Prevent A Divide By Zero 
    { 
     height=1;          // Making Height Equal One 
    } 

    glViewport(0,0,width,height);      // Reset The Current Viewport 

    glMatrixMode(GL_PROJECTION);      // Select The Projection Matrix 
    glLoadIdentity();         // Reset The Projection Matrix 

    // Calculate The Aspect Ratio Of The Window 
    gluPerspective(25.0f,1.0f,0.1f,100.0f); 

    glMatrixMode(GL_MODELVIEW);       // Select The Modelview Matrix 
    glLoadIdentity();         // Reset The Modelview Matrix 

    glEnable(GL_TEXTURE_2D);       // Enable Texture Mapping 
    glShadeModel(GL_SMOOTH);       // Enable Smooth Shading 
    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);    // Black Background 
    glClearDepth(1.0f);         // Depth Buffer Setup 
    glDisable(GL_DEPTH_TEST);       // Enables Depth Testing 
    glDepthFunc(GL_LEQUAL);        // The Type Of Depth Testing To Do 
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations 

    GLenum mError = glGetError(); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer 
    glLoadIdentity();         // Reset The View 
    glTranslatef(0.0f,0.0f,-5.0f); 
    mError = glGetError(); 
    glBindTexture(GL_TEXTURE_2D, texture); 
    mError = glGetError(); 
    glColor4f(1.0, 1.0, 1.0, 1.0); 
    mError = glGetError(); 

    if(flip) 
    { 
     glBegin(GL_QUADS); 
      // Front Face 
      glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.5f); 
      glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, -1.0f, 0.5f); 
      glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, 0.5f); 
      glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.5f); 
     glEnd(); 
     mError = glGetError(); 
    } 
    else 
    { 
     glBegin(GL_QUADS); 
      // Front Face 
      glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 0.5f); 
      glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, -1.0f, 0.5f); 
      glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, 1.0f, 0.5f); 
      glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 0.5f); 
     glEnd(); 
     mError = glGetError(); 
    } 
    mError = glGetError(); 
    return TRUE;          // Keep Going 
} 

GLvoid OpenGL_Display::KillGLWindow(GLvoid)        // Properly Kill The Window 
{ 
    if (fullscreen)          // Are We In Fullscreen Mode? 
    { 
     ChangeDisplaySettings(NULL,0);     // If So Switch Back To The Desktop 
     ShowCursor(TRUE);        // Show Mouse Pointer 
    } 

    if (hRC)           // Do We Have A Rendering Context? 
    { 
     wglMakeCurrent(NULL,NULL); 
     wglDeleteContext(hRC); 
     hRC=NULL;          // Set RC To NULL 
    } 

    ReleaseDC(hWnd,hDC); 

    DestroyWindow(hWnd); 

    UnregisterClass("OpenGL_Display",hInstance); 
} 

void OpenGL_Display::DrawNewImage(int width, int height, char* imageData, bool flip, int bpp) 
{ 
    BOOL returnVal = wglMakeCurrent(hDC, hRC); 

    UpdateGLBuffers(width, height, imageData, bpp); 
    DrawGLScene(flip); 
    SwapBuffers(hDC); 
    wglMakeCurrent(NULL, NULL); 
} 

void OGD::OpenGLDisplay_Init(int width, int height, int posX, int posY, int ID, LPCSTR className) 
{ 
    for(unsigned int i = 0; i < oglDisp.size(); ++i) { 
     if(oglDisp.at(i)->ID == ID) { 
      return; 
     } 
    } 

    oglDisp.push_back(new OGD::OpenGL_Display(ID)); 
    oglDisp.at(oglDisp.size()-1)->Init_Display(width, height, posX, posY, className); //by default this ID is latest 
    wglMakeCurrent(NULL, NULL); 
    GLenum mError = glGetError(); 
} 

void OGD::OpenGLDisplay_Wrapper(char* image, int width, int height, bool flip, int bpp, int ID) 
{ 
    for(unsigned int i = 0; i < oglDisp.size(); ++i) { 
     if(oglDisp.at(i)->ID == ID) { 
      oglDisp.at(i)->DrawNewImage(width, height, image, flip, bpp); 
      return; 
     } 
    } 
} 
+2

Вы когда-нибудь слышали о SSCCE? – dhein

+0

Да, у меня есть, но большая часть кода инициализируется, а BasicProject - только для SSCCE. – SinisterMJ

+2

Священная стена текста, можете ли вы свести к минимуму пример проблемы? Вы можете просто найти причину своей проблемы ... – wich

ответ

1

Даже если ваше окно OpenGL-based, вы должны создать цикл сообщений и повторно вызвать GetMessage, TranslateMessage и DispatchMessage. Обращайтесь с WM_PAINT, хотя ничего не нужно рисовать. Если вы этого не сделаете, Windows подумает, что ваше приложение не отвечает, и показывает курсор занят (или, что еще хуже, показывает диалог «Не реагировать на приложение»).

+0

Кроме того, курсором по умолчанию для нового окна является загруженный курсор - до тех пор, пока приложение не получит вокруг, чтобы изменить его. –

Смежные вопросы