Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

lib3ds to opengl with wxWidgets (black window)

By: a guest on Jan 8th, 2011  |  syntax: C++  |  size: 8.74 KB  |  views: 628  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. //// GLCanvas.h /////////////////////////////////////////////////////////////////////////
  2. //
  3. //
  4. /////////////////////////////////////////////////////////////////////////////////////////
  5.  
  6. #pragma once
  7. #ifndef GLCANVAS_H
  8. #define GLCANVAS_H
  9.  
  10. #include <gl/glew.h>  //must come first before other gl type headers
  11. #include "wx/glcanvas.h"
  12.  
  13. #ifdef __WXMAC__
  14. #include "OpenGL/glu.h"
  15. #include "OpenGL/gl.h"
  16. #else
  17. #include <windows.h>
  18. #include <GL/glu.h>
  19. #include <GL/gl.h>
  20. #include "GL/glut.h"
  21. #endif
  22.  
  23. #include "Object.h"
  24.  
  25. //////////////////////////////////
  26. class GLCanvas: public wxGLCanvas
  27. {
  28. public:
  29.     GLCanvas(MainPanel *parent, wxWindowID id, wxSize size, int* attribList);
  30.         ~GLCanvas();
  31.  
  32.         //EVENTS
  33.     void OnPaint(wxPaintEvent& event);
  34.     void OnSize(wxSizeEvent& event);
  35.         void OnEraseBackground(wxEraseEvent& event){}; //Do nothing, to avoid flashing.
  36.         void IdleLoop(wxIdleEvent& event);
  37.  
  38.         void Render();
  39.        
  40.         //PROCESSING
  41.         void InitGL(GLfloat Width, GLfloat Height);
  42.         void ReSizeGLScene(GLint Width, GLint Height);
  43.  
  44.         MainPanel *mainPanel;
  45.  
  46.         Object *object;
  47.  
  48.         DECLARE_EVENT_TABLE()
  49. };
  50.  
  51. #endif //GLCANVAS_H
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61. //// GLCanvas.cpp////////////////////////////////////////////////////////////////////////
  62. //
  63. //
  64. /////////////////////////////////////////////////////////////////////////////////////////
  65.  
  66. #include "stdwx.h"
  67. #include "GLCanvas.h"
  68.  
  69. ///////////////////////////////////////
  70. BEGIN_EVENT_TABLE(GLCanvas, wxGLCanvas)
  71.     EVT_SIZE(GLCanvas::OnSize)
  72.     EVT_PAINT(GLCanvas::OnPaint)
  73.     EVT_ERASE_BACKGROUND(GLCanvas::OnEraseBackground)
  74.         EVT_IDLE     (GLCanvas::IdleLoop)
  75. END_EVENT_TABLE()
  76.  
  77. GLCanvas::GLCanvas(MainPanel *parent, wxWindowID id, wxSize size, int* attributeList)
  78.     : wxGLCanvas(parent, id, wxPoint(0,0), size, wxFULL_REPAINT_ON_RESIZE, wxT(""), attributeList, wxNullPalette)
  79.        
  80. {
  81.         SetExtraStyle(wxWS_EX_PROCESS_IDLE); //animate in the idle event
  82.         SetCurrent();
  83.  
  84.         mainPanel = parent;
  85.         glewInit();
  86.  
  87.         /////////////////////////////////////////////////
  88.         object = new Object("model.3ds");
  89.         //////////////////////////////////////////////////
  90.  
  91.         InitGL(1,1);
  92. }
  93.  
  94. GLCanvas::~GLCanvas()
  95. {
  96.         delete object;
  97. }
  98.  
  99. void GLCanvas::OnPaint(wxPaintEvent &event)
  100. {
  101.         Render();
  102. }
  103.  
  104. void GLCanvas::OnSize(wxSizeEvent& event)
  105. {
  106.     // this is also necessary to update the context on some platforms
  107.     wxGLCanvas::OnSize(event);
  108.         wxSize temp = event.GetSize();
  109.         ReSizeGLScene(temp.GetWidth(), temp.GetHeight());
  110.         this->SetSize(temp);
  111. }
  112.  
  113. void GLCanvas::IdleLoop(wxIdleEvent &event)
  114. {
  115.         event.Skip(true); //do not propagate this event
  116.         Refresh();
  117. }
  118.  
  119. void GLCanvas::Render()
  120. {
  121.         if(!IsShown()) return;
  122.  
  123.     SetCurrent();
  124.  
  125.         wxPaintDC(this);
  126.         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    
  127.  
  128.         object->Draw();
  129.        
  130.         glFlush();
  131.         SwapBuffers();
  132. }
  133.  
  134. void GLCanvas::InitGL(GLfloat Width, GLfloat Height)   
  135. {
  136.       glClearColor(0.0, 0.0, 0.0, 0.0);
  137.         glShadeModel(GL_SMOOTH);
  138.        
  139.         // Enable lighting and set the position of the light
  140.         glEnable(GL_LIGHT0);
  141.         glEnable(GL_LIGHTING);
  142.         GLfloat pos[] = { 0.0, 4.0, 4.0 };
  143.         glLightfv(GL_LIGHT0, GL_POSITION, pos);
  144.        
  145.         // Generate Vertex Buffer Objects
  146.         object->CreateVBO();
  147.            
  148. }
  149.  
  150. void GLCanvas::ReSizeGLScene(GLint Width, GLint Height)
  151. {
  152.         // Reset the viewport
  153.         glViewport(0, 0, Width, Height);
  154.         // Reset the projection and modelview matrix
  155.         glMatrixMode(GL_PROJECTION);
  156.         glLoadIdentity();
  157.         // 10 x 10 x 10 viewing volume
  158.         glOrtho(-5.0, 5.0, -5.0, 5.0, -5.0, 5.0);
  159.         glMatrixMode(GL_MODELVIEW);
  160.         glLoadIdentity();
  161.    
  162. }
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171.  
  172. //// Object.h /////////////////////////////////////////////////////////////////////////
  173. //
  174. //
  175. ///////////////////////////////////////////////////////////////////////////////////////
  176.  
  177. #pragma once
  178. #ifndef OBJECT_H
  179. #define OBJECT_H
  180.  
  181. #include "lib3ds/file.h"
  182. #include "lib3ds/mesh.h"
  183.  
  184. class Object
  185. {
  186.         public:
  187.                 Object(std:: string filename);
  188.                                 virtual ~Object();
  189.                 virtual void Draw() const;
  190.                 virtual void CreateVBO();
  191.                
  192.         protected:
  193.                 void GetFaces();
  194.                 unsigned int m_TotalFaces;
  195.                 Lib3dsFile * m_model;
  196.                 GLuint m_VertexVBO, m_NormalVBO, m_TexCoordVBO;
  197. };
  198.  
  199. #endif //OBJECT_H
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207.  
  208.  
  209. //// Object.cpp////////////////////////////////////////////////////////////////////////
  210. //
  211. //
  212. ///////////////////////////////////////////////////////////////////////////////////////
  213.  
  214. #include "stdwx.h"
  215. #include "Object.h"
  216.  
  217. Object::Object(std:: string filename)
  218. {
  219.         m_TotalFaces = 0;
  220.        
  221.         m_model = lib3ds_file_load(filename.c_str());
  222.         // If loading the model failed, we throw an exception
  223.         if(!m_model)
  224.         {
  225.                 throw strcat("Unable to load ", filename.c_str());
  226.         }
  227. }
  228.  
  229. Object::~Object()
  230. {
  231.  
  232. }
  233.  
  234. void Object::GetFaces()
  235. {
  236.       m_TotalFaces = 0;
  237.      Lib3dsMesh * mesh;
  238.      
  239.      // Loop through every mesh.
  240.      
  241.      for(mesh = m_model->meshes;mesh != NULL;mesh = mesh->next)
  242.      {
  243.           // Add the number of faces this mesh has to the total number of faces.
  244.          
  245.           m_TotalFaces += mesh->faces;
  246.      }    
  247.  
  248. }
  249.  
  250. void Object::CreateVBO()
  251. {
  252.         // Calculate the number of faces we have in total.
  253.        
  254.      GetFaces();
  255.      
  256.      // Allocate memory for our vertices, normals and texture-coordinates.
  257.      
  258.      Lib3dsVector * vertices = new Lib3dsVector[m_TotalFaces * 3];
  259.      Lib3dsVector * normals = new Lib3dsVector[m_TotalFaces * 3];
  260.      Lib3dsVector * texCoords = new Lib3dsVector[m_TotalFaces * 2];
  261.      
  262.      Lib3dsMesh * mesh;
  263.      unsigned int FinishedFaces = 0;  
  264.        
  265.      // Loop through all the meshes.
  266.      
  267.      for(mesh = m_model->meshes;mesh != NULL;mesh = mesh->next)
  268.      {
  269.           lib3ds_mesh_calculate_normals(mesh, &normals[FinishedFaces*3]);
  270.          
  271.           // Loop through every face.
  272.          
  273.                   for(unsigned int cur_face = 0; cur_face < mesh->faces;cur_face++)
  274.           {            
  275.                           Lib3dsFace * face = &mesh->faceL[cur_face];
  276.                for(unsigned int i = 0;i < 3;i++)
  277.  
  278.                {                        
  279.                     // If there are texture-coordinates.
  280.                    
  281.                     if(mesh->texels)
  282.                                 {
  283.                          memcpy(&texCoords[FinishedFaces*2 + i], mesh->texelL[face->points[ i ]], sizeof(Lib3dsTexel));
  284.  
  285.                     }    
  286.                     memcpy(&vertices[FinishedFaces*3 + i], mesh->pointL[face->points[ i ]].pos, sizeof(Lib3dsVector));
  287.                }
  288.                FinishedFaces++;
  289.           }
  290.      }
  291.      
  292.      // Generate a VBO and store it with our vertices.
  293.      
  294.      glGenBuffers(1, &m_VertexVBO);
  295.      glBindBuffer(GL_ARRAY_BUFFER, m_VertexVBO);
  296.      glBufferData(GL_ARRAY_BUFFER, sizeof(Lib3dsVector) * 3 * m_TotalFaces, vertices, GL_STATIC_DRAW);
  297.      
  298.      // Generate another VBO and store the normals in it.
  299.      
  300.      glGenBuffers(1, &m_NormalVBO);
  301.      glBindBuffer(GL_ARRAY_BUFFER, m_NormalVBO);
  302.      glBufferData(GL_ARRAY_BUFFER, sizeof(Lib3dsVector) * 3 * m_TotalFaces, normals, GL_STATIC_DRAW);
  303.      
  304.      // Generate a third VBO and store the texture coordinates in it.
  305.      
  306.      glGenBuffers(1, &m_TexCoordVBO);
  307.      glBindBuffer(GL_ARRAY_BUFFER, m_TexCoordVBO);
  308.      glBufferData(GL_ARRAY_BUFFER, sizeof(Lib3dsTexel) * 3 * m_TotalFaces, texCoords, GL_STATIC_DRAW);
  309.      
  310.      // Clean up our allocated memory because the data is now stored in the GPU.
  311.      
  312.      delete vertices;
  313.      delete normals;
  314.      delete texCoords;
  315.      
  316.      // We no longer need lib3ds.
  317.      
  318.      lib3ds_file_free(m_model);
  319.      m_model = NULL;
  320. }
  321.  
  322. void Object:: Draw() const
  323. {
  324.       // Enable vertex, normal and texture-coordinate arrays.
  325.      
  326.      glEnableClientState(GL_VERTEX_ARRAY);
  327.      glEnableClientState(GL_NORMAL_ARRAY);
  328.      glEnableClientState(GL_TEXTURE_COORD_ARRAY);  
  329.      
  330.      // Bind the VBO with the normals.
  331.      
  332.      glBindBuffer(GL_ARRAY_BUFFER, m_NormalVBO);
  333.      
  334.      // The pointer for the normals is NULL which means that OpenGL will use the currently bound VBO.
  335.      
  336.      glNormalPointer(GL_FLOAT, 0, NULL);
  337.      
  338.      glBindBuffer(GL_ARRAY_BUFFER, m_TexCoordVBO);    
  339.      glTexCoordPointer(2, GL_FLOAT, 0, NULL);    
  340.      
  341.      glBindBuffer(GL_ARRAY_BUFFER, m_VertexVBO);
  342.      glVertexPointer(3, GL_FLOAT, 0, NULL);
  343.      
  344.      // Render the triangles.
  345.      
  346.      glDrawArrays(GL_TRIANGLES, 0, m_TotalFaces * 3);
  347.      
  348.      glDisableClientState(GL_VERTEX_ARRAY);
  349.      glDisableClientState(GL_NORMAL_ARRAY);    
  350.      glDisableClientState(GL_TEXTURE_COORD_ARRAY);  
  351. }