为什么我的OpenGL不能绘制任何东西?

问题描述:

我正在将我的开源粒子引擎测试从SDL移植到SDL + OpenGL。我设法编译并运行,但无论我做什么,屏幕都保持黑屏。 main.cpp中:为什么我的OpenGL不能绘制任何东西?

#include "glengine.h" 



int WINAPI WinMain(
    HINSTANCE hInstance, 
    HINSTANCE hPrevInstance, 
    LPSTR lpCmdLine, 
    int nCmdShow 
) 
{ 
//Create a glengine instance 
ultragl::glengine *gle = new ultragl::glengine(); 

if(gle->init()) 
    gle->run(); 

else 
    std::cout << "glengine initializiation failed!" << std::endl; 

//If we can't initialize, or the lesson has quit we delete the instance 
delete gle; 

return 0; 
}; 

glengine.h:

//we need to include window first because GLee needs to be included before GL.h 
#include "window.h" 
#include <math.h>   // Math Library Header File 
#include <vector> 
#include <stdio.h> 

using namespace std; 

namespace ultragl 
{ 
    class glengine 
    { 
     protected: 
       window m_Window; ///< The window for this lesson 
       unsigned int m_Keys[SDLK_LAST]; ///< Stores keys that are pressed 
       float piover180; 

       virtual void draw(); 
       virtual void resize(int x, int y); 
       virtual bool processEvents(); 
       void controls(); 

     private: 
      /* 
      * We need a structure to store our vertices in, otherwise we 
      * just had a huge bunch of floats in the end 
      */ 
      struct Vertex 
      { 
       float x, y, z; 

       Vertex(){} 

       Vertex(float x, float y, float z) 
       { 
        this->x = x; 
        this->y = y; 
        this->z = z; 
       } 
      }; 

      struct particle 
      { 
       public : 
       double angle; 
       double speed; 
       Vertex v; 
       int r; 
       int g; 
       int b; 
       int a; 

       particle(double angle, double speed, Vertex v, int r, int g, int b, int a) 
       { 
        this->angle = angle; 
        this->speed = speed; 
        this->v = v; 
        this->r = r; 
        this->g = g; 
        this->b = b; 
        this->a = a; 
       } 

       particle() 
       { 

       } 

      }; 

      particle p[500]; 
      float particlesize; 


     public: 
      glengine(); 
      ~glengine(); 

      virtual void run(); 
      virtual bool init(); 
      void glengine::test2(int num); 
      void glengine::update(); 
    }; 
}; 

window.h中:

#include <string> 
#include <iostream> 

#include "GLee/GLee.h" 

#include <SDL/SDL.h> 
#include <SDL/SDL_opengl.h> 
#include <GL/glu.h> 

using namespace std; 

namespace ultragl 
{ 
    class window 
    { 
     private: 
      int w_height; 
      int w_width; 
      int w_bpp; 
      bool w_fullscreen; 
      string w_title; 

     public: 
      window(); 
      ~window(); 

      bool createWindow(int width, int height, int bpp, bool fullscreen, const string& title); 
      void setSize(int width, int height); 
      int getHeight(); 
      int getWidth(); 
    }; 
}; 

glengine.cpp(主一个看):

#include "glengine.h" 

namespace ultragl{ 

    glengine::glengine() 
    { 
     piover180 = 0.0174532925f; 
    } 

    glengine::~glengine() 
    { 

    } 

    void glengine::resize(int x, int y) 
    { 
     std::cout << "Resizing Window to " << x << "x" << y << std::endl; 

     if (y <= 0) 
     { 
      y = 1; 
     } 

     glViewport(0,0,x,y); 

     glMatrixMode(GL_PROJECTION); 
     glLoadIdentity(); 
     gluPerspective(45.0f,(GLfloat)x/(GLfloat)y,1.0f,100.0f); 

     glMatrixMode(GL_MODELVIEW); 
     glLoadIdentity(); 
    } 

    bool glengine::processEvents() 
    { 
     SDL_Event event; 

     while (SDL_PollEvent(&event))//get all events 
     { 
      switch (event.type) 
      { 
       // Quit event 
       case SDL_QUIT: 
       { 
        // Return false because we are quitting. 
        return false; 
       } 

       case SDL_KEYDOWN: 
       { 
        SDLKey sym = event.key.keysym.sym; 

        if(sym == SDLK_ESCAPE) //Quit if escape was pressed 
        { 
         return false; 
        } 

        m_Keys[sym] = 1; 
        break; 
       } 

       case SDL_KEYUP: 
       { 
        SDLKey sym = event.key.keysym.sym; 
        m_Keys[sym] = 0; 
        break; 
       } 

       case SDL_VIDEORESIZE: 
       { 
        //the window has been resized so we need to set up our viewport and projection according to the new size 
        resize(event.resize.w, event.resize.h); 
        break; 
       } 
       // Default case 
       default: 
       { 
        break; 
       } 
      } 
     } 

     return true; 
    } 


    bool glengine::init() 
    { 
     srand(time(NULL)); 

     for(int i = 0; i < 500; i++) 
      p[i] = particle(0, 0, Vertex(0.0f, 0.0f, 0.0f), 0, 0, 0, 0); 


     if (!m_Window.createWindow(640, 480, 32, false, "Paricle Test GL")) 
     { 
      return false; 
     } 

     particlesize = 0.01; 
     glShadeModel(GL_SMOOTH);    // Enable Smooth Shading 
     glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background 
     glClearDepth(1.0f);      // Depth Buffer Setup 
     glEnable(GL_DEPTH_TEST);    // Enables Depth Testing 
     glDepthFunc(GL_LEQUAL);     // The Type Of Depth Testing To Do 
     glEnable(GL_BLEND); 
     glBlendFunc(GL_ONE , GL_ONE_MINUS_SRC_ALPHA); 

     return true; 
    } 

    void glengine::test2(int num) 
    { 
     glPushMatrix(); 
      glTranslatef(p[num].v.x, p[num].v.y, p[num].v.z); 
      glBegin(GL_QUADS); 
       glColor4i(p[num].r, p[num].g, p[num].b, p[num].a);    // Green for x axis 
        glVertex3f(-particlesize, -particlesize, particlesize); 
        glVertex3f(particlesize, -particlesize, particlesize); 
        glVertex3f(particlesize, particlesize, particlesize); 
        glVertex3f(-particlesize, particlesize, particlesize); 
      glEnd(); 

     glPopMatrix(); 
    } 

    void glengine::draw() 
    { 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer 
     glLoadIdentity();     // Reset The Current Modelview Matrix 

     gluLookAt(0, 5, 20, 0, 0, 0, 0, 0, 0); 
     for(int i = 0; i < 500; i++) 
      test2(i); 
    } 

    void glengine::update() 
    { 
     for(int i = 0; i < 500; i++) 
     { 
      if(p[i].a <= 0) 
       p[i] = particle(5 + rand() % 360, (rand() % 10) * 0.1, Vertex(0.0f, 0.0f, 0.0f), 0, 255, 255, 255); 

      else 
       p[i].a -= 1; 

      p[i].v.x += (sin(p[i].angle * (3.14159265/180)) * p[i].speed); 
      p[i].v.y -= (cos(p[i].angle * (3.14159265/180)) * p[i].speed); 
     } 
    } 

    void glengine::run() 
    { 
     while(processEvents()) 
     { 
      update(); 
      draw(); 
      SDL_GL_SwapBuffers(); 
     } 
    } 
}; 

最后window.cpp:

#include "window.h" 

namespace ultragl 
{ 
    window::window(): w_width(0), w_height(0), w_bpp(0), w_fullscreen(false) 
    { 

    } 

    window::~window() 
    { 
     SDL_Quit(); 
    } 

    bool window::createWindow(int width, int height, int bpp, bool fullscreen, const string& title) 
    { 
     if(SDL_Init(SDL_INIT_VIDEO) != 0) 
      return false; 

     w_height = height; 
     w_width = width; 
     w_title = title; 
     w_fullscreen = fullscreen; 
     w_bpp = bpp; 

     //Set lowest possiable values. 
     SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); 
     SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); 
     SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); 
     SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 5); 
     SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); 
     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 

     //Set title. 
     SDL_WM_SetCaption(title.c_str(), title.c_str()); 

     // Flags tell SDL about the type of window we are creating. 
     int flags = SDL_OPENGL; 

     if(fullscreen == true) 
      flags |= SDL_FULLSCREEN; 

     // Create window 
     SDL_Surface * screen = SDL_SetVideoMode(width, height, bpp, flags); 

     if(screen == 0) 
      return false; 

     //SDL doesn't trigger off a ResizeEvent at startup, but as we need this for OpenGL, we do this ourself 
     SDL_Event resizeEvent; 
     resizeEvent.type = SDL_VIDEORESIZE; 
     resizeEvent.resize.w = width; 
     resizeEvent.resize.h = height; 

     SDL_PushEvent(&resizeEvent); 

     return true; 
    } 

    void window::setSize(int width, int height) 
    { 
     w_height = height; 
     w_width = width; 
    } 

    int window::getHeight() 
    { 
     return w_height; 
    } 

    int window::getWidth() 
    { 
     return w_width; 
    } 
}; 

无论如何,我真的需要完成这个,但我已经尝试了所有我能想到的。我测试了许多不同方式的glengine文件,看起来像这样在一个点上:

#include "glengine.h" 
#include "SOIL/SOIL.h" 
#include "SOIL/stb_image_aug.h" 
#include "SOIL/image_helper.h" 
#include "SOIL/image_DXT.h" 

namespace ultragl{ 

    glengine::glengine() 
    { 
     piover180 = 0.0174532925f; 
    } 

    glengine::~glengine() 
    { 

    } 

    void glengine::resize(int x, int y) 
    { 
     std::cout << "Resizing Window to " << x << "x" << y << std::endl; 

     if (y <= 0) 
     { 
      y = 1; 
     } 

     glViewport(0,0,x,y); 

     glMatrixMode(GL_PROJECTION); 
     glLoadIdentity(); 
     gluPerspective(45.0f,(GLfloat)x/(GLfloat)y,1.0f,1000.0f); 

     glMatrixMode(GL_MODELVIEW); 
     glLoadIdentity(); 
    } 

    bool glengine::processEvents() 
    { 
     SDL_Event event; 

     while (SDL_PollEvent(&event))//get all events 
     { 
      switch (event.type) 
      { 
       // Quit event 
       case SDL_QUIT: 
       { 
        // Return false because we are quitting. 
        return false; 
       } 

       case SDL_KEYDOWN: 
       { 
        SDLKey sym = event.key.keysym.sym; 

        if(sym == SDLK_ESCAPE) //Quit if escape was pressed 
        { 
         return false; 
        } 

        m_Keys[sym] = 1; 
        break; 
       } 

       case SDL_KEYUP: 
       { 
        SDLKey sym = event.key.keysym.sym; 
        m_Keys[sym] = 0; 
        break; 
       } 

       case SDL_VIDEORESIZE: 
       { 
        //the window has been resized so we need to set up our viewport and projection according to the new size 
        resize(event.resize.w, event.resize.h); 
        break; 
       } 
       // Default case 
       default: 
       { 
        break; 
       } 
      } 
     } 

     return true; 
    } 


    bool glengine::init() 
    { 
     srand(time(NULL)); 

     for(int i = 0; i < 500; i++) 
      p[i] = particle(0, 0, Vertex(0.0f, 0.0f, 0.0f), 0, 0, 0, 0); 


     if (!m_Window.createWindow(640, 480, 32, false, "Paricle Test GL")) 
     { 
      return false; 
     } 

     particlesize = 10.01; 
     glShadeModel(GL_SMOOTH);    // Enable Smooth Shading 
     glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background 
     glClearDepth(1.0f);      // Depth Buffer Setup 
     glEnable(GL_DEPTH_TEST);    // Enables Depth Testing 
     glDepthFunc(GL_LEQUAL);     // The Type Of Depth Testing To Do 
     glEnable(GL_BLEND); 
     glBlendFunc(GL_ONE , GL_ONE_MINUS_SRC_ALPHA); 

     return true; 
    } 

    void glengine::test2(int num) 
    { 
     //glPushMatrix(); 
      //glTranslatef(p[num].v.x, p[num].v.y, p[num].v.z); 
       glColor4i(255, 255, 255, 255); 

     glBegin(GL_QUADS); 
      glNormal3f(0.0f, 0.0f, 1.0f); 
      glVertex3f(-particlesize, -particlesize, particlesize); 
      glVertex3f(particlesize, -particlesize, particlesize); 
      glVertex3f(particlesize, particlesize, particlesize); 
      glVertex3f(-particlesize, particlesize, particlesize); 
     glEnd(); 

     // Back Face 
     glBegin(GL_QUADS); 
      glNormal3f(0.0f, 0.0f,-1.0f); 
      glVertex3f(-particlesize, -particlesize, -particlesize); 
      glVertex3f(-particlesize, particlesize, -particlesize); 
      glVertex3f(particlesize, particlesize, -particlesize); 
      glVertex3f(particlesize, -particlesize, -particlesize); 
     glEnd(); 

     // Top Face 
     glBegin(GL_QUADS); 
      glNormal3f(0.0f, 1.0f, 0.0f); 
      glVertex3f(-particlesize, particlesize, -particlesize); 
      glVertex3f(-particlesize, particlesize, particlesize); 
      glVertex3f(particlesize, particlesize, particlesize); 
      glVertex3f(particlesize, particlesize, -particlesize); 
     glEnd(); 

     // Bottom Face 
     glBegin(GL_QUADS); 
      glNormal3f(0.0f,-1.0f, 0.0f); 
      glVertex3f(-particlesize, -particlesize, -particlesize); 
      glVertex3f(particlesize, -particlesize, -particlesize); 
      glVertex3f(particlesize, -particlesize, particlesize); 
      glVertex3f(-particlesize, -particlesize, particlesize); 
     glEnd(); 

      // Right face 
     glBegin(GL_QUADS); 
      glNormal3f(1.0f, 0.0f, 0.0f); 
      glVertex3f(particlesize, -particlesize, -particlesize); 
      glVertex3f(particlesize, particlesize, -particlesize); 
      glVertex3f(particlesize, particlesize, particlesize); 
      glVertex3f(particlesize, -particlesize, particlesize); 
     glEnd(); 

      // Left Face 
     glBegin(GL_QUADS); 
      glNormal3f(-1.0f, 0.0f, 0.0f); 
      glVertex3f(-particlesize, -particlesize, -particlesize); 
      glVertex3f(-particlesize, -particlesize, particlesize); 
      glVertex3f(-particlesize, particlesize, particlesize); 
      glVertex3f(-particlesize, particlesize, -particlesize); 
     glEnd(); 


     //glPopMatrix(); 
    } 

    void glengine::draw() 
    { 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer 
     glLoadIdentity();     // Reset The Current Modelview Matrix 

     gluLookAt(0, 5, 20, 0, 0, 0, 0, 1, 0); 
     for(int i = 0; i < 500; i++) 
      test2(i); 
    } 

    void glengine::update() 
    { 
     for(int i = 0; i < 500; i++) 
     { 
      if(p[i].a <= 0) 
       p[i] = particle(5 + rand() % 360, (rand() % 10) * 0.1, Vertex(0.0f, 0.0f, -5.0f), 0, 255, 255, 255); 

      else 
       p[i].a -= 1; 

      p[i].v.x += (sin(p[i].angle * (3.14159265/180)) * p[i].speed); 
      p[i].v.y -= (cos(p[i].angle * (3.14159265/180)) * p[i].speed); 
     } 
    } 

    void glengine::run() 
    { 
     while(processEvents()) 
     { 
      update(); 
      draw(); 
      SDL_GL_SwapBuffers(); 
     } 
    } 
}; 

它仍然没有工作。我真的以我的智慧结束了这一次。

+2

我发现你可以得到更好的回应,如果你可以减少你的源代码到绝对最小的例子,同时仍然有相同的问题。当你可以将问题简化为1页的简单示例时,人们不希望通过4页源代码来完成这项工作。 – mmcdole 2009-02-11 10:12:56

+0

将您的程序减少到尽可能简单的绘图程序。设置你的OpenGL窗口,视口等,并尝试画一条线。如果它没有显示在这里发布代码。然后,当人们看到问题时,您可以将修复应用于更大的问题。 – mmcdole 2009-02-11 10:14:01

好吧,我设法使用大量建议和其他一些源代码来解决它。结果发现问题来自3条不同的路线。

particlesize = 0.01;应该更大一些:particlesize = 1.01;

glColor4i(255, 255, 255, 255)将立方体变成与透明颜色相同的颜色,因为我错误地使用它。我无法弄清楚如何正确使用它,所以我使用glColor4f(0.0f,1.0f,1.0f,0.5f)来代替,而且工作正常。

gluLookAt(0, 5, 20, 0, 0, 0, 0, 1, 0)

所需的所有gluLookAt(0, 5, 20, 0, 0, 0, 0, 0, 0)最后感谢大家的帮助,和你的时间。

检查OpenGL的错误状态。使用glslDevil,glInterceptgDebugger。检查glGetError功能。您可以测试SDL是否实际获取了设备上下文? 窗口是否反映glClearColor调用中的更改?不要在glClearColor中使用0.5作为alpha值。 尝试这些建议,并按照Simucal建议的最小示例报告。

我没有检查过你的代码,但是我总是在调试这类问题时做的一件事就是将清晰的颜色设置为像(1,0,1)这样的丰富多彩的东西。

这将帮助您查看问题是您的绘制对象是完全黑色还是根本没有绘制。

编辑: 正如有人在评论中提到的那样:它还显示如果清除操作清除为正确的颜色或者如果它保持黑色,则是否具有正确的GL上下文。

+2

并查看您是否创建了至少glClear工作正确的上下文。 – aib 2009-02-11 12:04:17

您不检查SDL-GL-SetAttribute()调用的返回值。

和你的显卡支持5/5/5/5 20-bpp颜色吗?