Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //// GLCanvas.h /////////////////////////////////////////////////////////////////////////
- //
- //
- /////////////////////////////////////////////////////////////////////////////////////////
- #pragma once
- #ifndef GLCANVAS_H
- #define GLCANVAS_H
- #include <gl/glew.h> //must come first before other gl type headers
- #include "wx/glcanvas.h"
- #ifdef __WXMAC__
- #include "OpenGL/glu.h"
- #include "OpenGL/gl.h"
- #else
- #include <windows.h>
- #include <GL/glu.h>
- #include <GL/gl.h>
- #include "GL/glut.h"
- #endif
- #include "Object.h"
- //////////////////////////////////
- class GLCanvas: public wxGLCanvas
- {
- public:
- GLCanvas(MainPanel *parent, wxWindowID id, wxSize size, int* attribList);
- ~GLCanvas();
- //EVENTS
- void OnPaint(wxPaintEvent& event);
- void OnSize(wxSizeEvent& event);
- void OnEraseBackground(wxEraseEvent& event){}; //Do nothing, to avoid flashing.
- void IdleLoop(wxIdleEvent& event);
- void Render();
- //PROCESSING
- void InitGL(GLfloat Width, GLfloat Height);
- void ReSizeGLScene(GLint Width, GLint Height);
- MainPanel *mainPanel;
- Object *object;
- DECLARE_EVENT_TABLE()
- };
- #endif //GLCANVAS_H
- //// GLCanvas.cpp////////////////////////////////////////////////////////////////////////
- //
- //
- /////////////////////////////////////////////////////////////////////////////////////////
- #include "stdwx.h"
- #include "GLCanvas.h"
- ///////////////////////////////////////
- BEGIN_EVENT_TABLE(GLCanvas, wxGLCanvas)
- EVT_SIZE(GLCanvas::OnSize)
- EVT_PAINT(GLCanvas::OnPaint)
- EVT_ERASE_BACKGROUND(GLCanvas::OnEraseBackground)
- EVT_IDLE (GLCanvas::IdleLoop)
- END_EVENT_TABLE()
- GLCanvas::GLCanvas(MainPanel *parent, wxWindowID id, wxSize size, int* attributeList)
- : wxGLCanvas(parent, id, wxPoint(0,0), size, wxFULL_REPAINT_ON_RESIZE, wxT(""), attributeList, wxNullPalette)
- {
- SetExtraStyle(wxWS_EX_PROCESS_IDLE); //animate in the idle event
- SetCurrent();
- mainPanel = parent;
- glewInit();
- /////////////////////////////////////////////////
- object = new Object("model.3ds");
- //////////////////////////////////////////////////
- InitGL(1,1);
- }
- GLCanvas::~GLCanvas()
- {
- delete object;
- }
- void GLCanvas::OnPaint(wxPaintEvent &event)
- {
- Render();
- }
- void GLCanvas::OnSize(wxSizeEvent& event)
- {
- // this is also necessary to update the context on some platforms
- wxGLCanvas::OnSize(event);
- wxSize temp = event.GetSize();
- ReSizeGLScene(temp.GetWidth(), temp.GetHeight());
- this->SetSize(temp);
- }
- void GLCanvas::IdleLoop(wxIdleEvent &event)
- {
- event.Skip(true); //do not propagate this event
- Refresh();
- }
- void GLCanvas::Render()
- {
- if(!IsShown()) return;
- SetCurrent();
- wxPaintDC(this);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- object->Draw();
- glFlush();
- SwapBuffers();
- }
- void GLCanvas::InitGL(GLfloat Width, GLfloat Height)
- {
- glClearColor(0.0, 0.0, 0.0, 0.0);
- glShadeModel(GL_SMOOTH);
- // Enable lighting and set the position of the light
- glEnable(GL_LIGHT0);
- glEnable(GL_LIGHTING);
- GLfloat pos[] = { 0.0, 4.0, 4.0 };
- glLightfv(GL_LIGHT0, GL_POSITION, pos);
- // Generate Vertex Buffer Objects
- object->CreateVBO();
- }
- void GLCanvas::ReSizeGLScene(GLint Width, GLint Height)
- {
- // Reset the viewport
- glViewport(0, 0, Width, Height);
- // Reset the projection and modelview matrix
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- // 10 x 10 x 10 viewing volume
- glOrtho(-5.0, 5.0, -5.0, 5.0, -5.0, 5.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- }
- //// Object.h /////////////////////////////////////////////////////////////////////////
- //
- //
- ///////////////////////////////////////////////////////////////////////////////////////
- #pragma once
- #ifndef OBJECT_H
- #define OBJECT_H
- #include "lib3ds/file.h"
- #include "lib3ds/mesh.h"
- class Object
- {
- public:
- Object(std:: string filename);
- virtual ~Object();
- virtual void Draw() const;
- virtual void CreateVBO();
- protected:
- void GetFaces();
- unsigned int m_TotalFaces;
- Lib3dsFile * m_model;
- GLuint m_VertexVBO, m_NormalVBO, m_TexCoordVBO;
- };
- #endif //OBJECT_H
- //// Object.cpp////////////////////////////////////////////////////////////////////////
- //
- //
- ///////////////////////////////////////////////////////////////////////////////////////
- #include "stdwx.h"
- #include "Object.h"
- Object::Object(std:: string filename)
- {
- m_TotalFaces = 0;
- m_model = lib3ds_file_load(filename.c_str());
- // If loading the model failed, we throw an exception
- if(!m_model)
- {
- throw strcat("Unable to load ", filename.c_str());
- }
- }
- Object::~Object()
- {
- }
- void Object::GetFaces()
- {
- m_TotalFaces = 0;
- Lib3dsMesh * mesh;
- // Loop through every mesh.
- for(mesh = m_model->meshes;mesh != NULL;mesh = mesh->next)
- {
- // Add the number of faces this mesh has to the total number of faces.
- m_TotalFaces += mesh->faces;
- }
- }
- void Object::CreateVBO()
- {
- // Calculate the number of faces we have in total.
- GetFaces();
- // Allocate memory for our vertices, normals and texture-coordinates.
- Lib3dsVector * vertices = new Lib3dsVector[m_TotalFaces * 3];
- Lib3dsVector * normals = new Lib3dsVector[m_TotalFaces * 3];
- Lib3dsVector * texCoords = new Lib3dsVector[m_TotalFaces * 2];
- Lib3dsMesh * mesh;
- unsigned int FinishedFaces = 0;
- // Loop through all the meshes.
- for(mesh = m_model->meshes;mesh != NULL;mesh = mesh->next)
- {
- lib3ds_mesh_calculate_normals(mesh, &normals[FinishedFaces*3]);
- // Loop through every face.
- for(unsigned int cur_face = 0; cur_face < mesh->faces;cur_face++)
- {
- Lib3dsFace * face = &mesh->faceL[cur_face];
- for(unsigned int i = 0;i < 3;i++)
- {
- // If there are texture-coordinates.
- if(mesh->texels)
- {
- memcpy(&texCoords[FinishedFaces*2 + i], mesh->texelL[face->points[ i ]], sizeof(Lib3dsTexel));
- }
- memcpy(&vertices[FinishedFaces*3 + i], mesh->pointL[face->points[ i ]].pos, sizeof(Lib3dsVector));
- }
- FinishedFaces++;
- }
- }
- // Generate a VBO and store it with our vertices.
- glGenBuffers(1, &m_VertexVBO);
- glBindBuffer(GL_ARRAY_BUFFER, m_VertexVBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(Lib3dsVector) * 3 * m_TotalFaces, vertices, GL_STATIC_DRAW);
- // Generate another VBO and store the normals in it.
- glGenBuffers(1, &m_NormalVBO);
- glBindBuffer(GL_ARRAY_BUFFER, m_NormalVBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(Lib3dsVector) * 3 * m_TotalFaces, normals, GL_STATIC_DRAW);
- // Generate a third VBO and store the texture coordinates in it.
- glGenBuffers(1, &m_TexCoordVBO);
- glBindBuffer(GL_ARRAY_BUFFER, m_TexCoordVBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(Lib3dsTexel) * 3 * m_TotalFaces, texCoords, GL_STATIC_DRAW);
- // Clean up our allocated memory because the data is now stored in the GPU.
- delete vertices;
- delete normals;
- delete texCoords;
- // We no longer need lib3ds.
- lib3ds_file_free(m_model);
- m_model = NULL;
- }
- void Object:: Draw() const
- {
- // Enable vertex, normal and texture-coordinate arrays.
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_NORMAL_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- // Bind the VBO with the normals.
- glBindBuffer(GL_ARRAY_BUFFER, m_NormalVBO);
- // The pointer for the normals is NULL which means that OpenGL will use the currently bound VBO.
- glNormalPointer(GL_FLOAT, 0, NULL);
- glBindBuffer(GL_ARRAY_BUFFER, m_TexCoordVBO);
- glTexCoordPointer(2, GL_FLOAT, 0, NULL);
- glBindBuffer(GL_ARRAY_BUFFER, m_VertexVBO);
- glVertexPointer(3, GL_FLOAT, 0, NULL);
- // Render the triangles.
- glDrawArrays(GL_TRIANGLES, 0, m_TotalFaces * 3);
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement