Skip to content

Instantly share code, notes, and snippets.

@bitdewy
Created April 7, 2013 10:39
Show Gist options
  • Save bitdewy/5329958 to your computer and use it in GitHub Desktop.
Save bitdewy/5329958 to your computer and use it in GitHub Desktop.
openGL practice
#include <iostream>
#include <map>
#include <vector>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/noncopyable.hpp>
#include <gl/glut.h>
#include <gl/SOIL.h>
class KeyboardManger : boost::noncopyable
{
public:
typedef boost::function<void ()> KeyPressAction;
typedef std::map<int, KeyPressAction> KeyActionsMap;
KeyboardManger() {}
~KeyboardManger() {}
void setKeyPressAction(int key, const KeyPressAction& func) {
actions_map_.insert(std::pair<int, KeyPressAction>(key, func));
}
void processKey(int key)
{
auto it = actions_map_.find(key);
if (it != actions_map_.end())
it->second();
else
[](int key){ std::cout << "can't process key " << key << std::endl; };
}
private:
KeyActionsMap actions_map_;
};
static KeyboardManger normalKeyManager;
static KeyboardManger specialKeyManager;
struct MovementManager : boost::noncopyable
{
MovementManager()
: xrotate_(.0f), yrotate_(.0f),
xspeed_(.0f), yspeed_(.0f), z_(-7.f)
{}
~MovementManager() {}
void xSpeedup() {
if (xspeed_ > -15.f) xspeed_ -= .1f;
}
void xSpeeddown() {
if (xspeed_ < 15.f) xspeed_ += .1f;
}
void ySpeedup() {
if (yspeed_ > -15.f) yspeed_ -= .1f;
}
void ySpeeddown() {
if (yspeed_ < 15.f) yspeed_ += .1f;
}
void xrotateContinue() { xrotate_ += xspeed_; }
void yrotateContinue() { yrotate_ += yspeed_; }
void approach() {
if (z_ < -4.f) z_ += .1f;
}
void depart() {
if (z_ > -50.f) z_ -= .1f;
}
GLfloat xrotate_;
GLfloat yrotate_;
GLfloat xspeed_;
GLfloat yspeed_;
GLfloat z_;
};
static MovementManager movemment;
template <typename T, size_t N>
struct dimensional
{
T data_[N];
};
template <typename T>
class _4D : dimensional<T, 4>
{
public:
_4D(T arg0, T arg1, T arg2, T arg3) {
data_[0] = arg0;
data_[1] = arg1;
data_[2] = arg2;
data_[3] = arg3;
}
const T* data() { return data_; }
};
class lightManager : boost::noncopyable
{
public:
lightManager()
: lightOn_(false),
ambient_(_4D<GLfloat>(.5f, .5f, .5f, 1.f)),
diffuse_(_4D<GLfloat>(1.f, 1.f, 1.f, 1.f)),
position_(_4D<GLfloat>(.0f, .0f, 2.f, 1.f))
{}
void init() {
glLightfv(GL_LIGHT1, GL_AMBIENT, ambient_.data());
glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse_.data());
glLightfv(GL_LIGHT1, GL_POSITION, position_.data());
glEnable(GL_LIGHT1);
}
~lightManager() {}
void switchLight() {
lightOn_ = !lightOn_;
if (lightOn_)
glEnable(GL_LIGHTING);
else
glDisable(GL_LIGHTING);
}
private:
bool lightOn_;
_4D<GLfloat> ambient_;
_4D<GLfloat> diffuse_;
_4D<GLfloat> position_;
};
static lightManager light;
class TexturesMangager : boost::noncopyable
{
public:
TexturesMangager()
: transparent_(false),
texture_index_(0)
{}
bool addTexture(const char* bitmapFile,
GLint minFilter, GLint magFilter, GLuint flags) {
auto texture = SOIL_load_OGL_texture(bitmapFile,
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
flags);
if(texture == 0)
return false;
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
textures_.push_back(texture);
return true;
}
void selectNextTexture() {
texture_index_ += 1;
if (texture_index_ >= textures_.size())
texture_index_ = 0;
glBindTexture(GL_TEXTURE_2D, textures_.at(texture_index_));
}
void transparent() {
transparent_ = !transparent_;
if (transparent_) {
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
} else {
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
}
}
private:
bool transparent_;
size_t texture_index_;
std::vector<GLuint> textures_;
};
static TexturesMangager textures;
GLvoid setKeyActions()
{
specialKeyManager.setKeyPressAction(GLUT_KEY_UP,
boost::bind(&MovementManager::xSpeedup, &movemment));
specialKeyManager.setKeyPressAction(GLUT_KEY_DOWN,
boost::bind(&MovementManager::xSpeeddown, &movemment));
specialKeyManager.setKeyPressAction(GLUT_KEY_LEFT,
boost::bind(&MovementManager::ySpeedup, &movemment));
specialKeyManager.setKeyPressAction(GLUT_KEY_RIGHT,
boost::bind(&MovementManager::ySpeeddown, &movemment));
specialKeyManager.setKeyPressAction(GLUT_KEY_PAGE_UP,
boost::bind(&MovementManager::depart, &movemment));
specialKeyManager.setKeyPressAction(GLUT_KEY_PAGE_DOWN,
boost::bind(&MovementManager::approach, &movemment));
normalKeyManager.setKeyPressAction('l',
boost::bind(&lightManager::switchLight, &light));
normalKeyManager.setKeyPressAction('f',
boost::bind(&TexturesMangager::selectNextTexture, &textures));
normalKeyManager.setKeyPressAction('b',
boost::bind(&TexturesMangager::transparent, &textures));
normalKeyManager.setKeyPressAction(27, boost::bind(&exit, 0));
}
GLvoid display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(.0f, .0f, movemment.z_);
glRotatef(movemment.xrotate_, 1.f, .0f, .0f);
glRotatef(movemment.yrotate_, .0f, 1.f, .0f);
glBegin(GL_QUADS);
//front
glNormal3f(.0f, .0f, 1.f);
glTexCoord2f(1.f, 1.f); glVertex3f(1.f, 1.f, 1.f);
glTexCoord2f(.0f, 1.f); glVertex3f(-1.f, 1.f, 1.f);
glTexCoord2f(.0f, .0f); glVertex3f(-1.f, -1.f, 1.f);
glTexCoord2f(1.f, .0f); glVertex3f(1.f, -1.f, 1.f);
//right
glNormal3f(1.f, .0f, .0f);
glTexCoord2f(1.f, 1.f); glVertex3f(1.f, 1.f, -1.f);
glTexCoord2f(.0f, 1.f); glVertex3f(1.f, 1.f, 1.f);
glTexCoord2f(.0f, .0f); glVertex3f(1.f, -1.f, 1.f);
glTexCoord2f(1.f, .0f); glVertex3f(1.f, -1.f, -1.f);
//back
glNormal3f(.0f, .0f, -1.f);
glTexCoord2f(1.f, 1.f); glVertex3f(-1.f, 1.f, -1.f);
glTexCoord2f(.0f, 1.f); glVertex3f(1.f, 1.f, -1.f);
glTexCoord2f(.0f, .0f); glVertex3f(1.f, -1.f, -1.f);
glTexCoord2f(1.f, .0f); glVertex3f(-1.f, -1.f, -1.f);
//left
glNormal3f(-1.f, .0f, .0f);
glTexCoord2f(1.f, 1.f); glVertex3f(-1.f, 1.f, 1.f);
glTexCoord2f(.0f, 1.f); glVertex3f(-1.f, -1.f, 1.f);
glTexCoord2f(.0f, .0f); glVertex3f(-1.f, -1.f, -1.f);
glTexCoord2f(1.f, .0f); glVertex3f(-1.f, 1.f, -1.f);
//top
glNormal3f(.0f, 1.f, .0f);
glTexCoord2f(1.f, 1.f); glVertex3f(1.f, 1.f, -1.f);
glTexCoord2f(.0f, 1.f); glVertex3f(-1.f, 1.f, -1.f);
glTexCoord2f(.0f, .0f); glVertex3f(-1.f, 1.f, 1.f);
glTexCoord2f(1.f, .0f); glVertex3f(1.f, 1.f, 1.f);
//bottom
glNormal3f(.0f, -1.f, 0.f);
glTexCoord2f(1.f, 1.f); glVertex3f(1.f, -1.f, 1.f);
glTexCoord2f(.0f, 1.f); glVertex3f(-1.f, -1.f, 1.f);
glTexCoord2f(.0f, .0f); glVertex3f(-1.f, -1.f, -1.f);
glTexCoord2f(1.f, .0f); glVertex3f(1.f, -1.f, -1.f);
glEnd();
movemment.xrotateContinue();
movemment.yrotateContinue();
glFlush();
}
GLvoid refresh(GLint)
{
glutPostRedisplay();
glutTimerFunc(50, refresh, 0);
}
GLvoid reshape(GLsizei width, GLsizei height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45., static_cast<GLdouble>(width)/height, .1, 100.);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
inline GLvoid processNormalKeyPress(unsigned char key, int x, int y)
{
normalKeyManager.processKey(static_cast<int>(key));
}
inline GLvoid processSpecialKeyPress(int key, int x, int y)
{
specialKeyManager.processKey(key);
}
GLvoid initGL(GLvoid)
{
textures.addTexture("Data/alalei.bmp",
GL_NEAREST, GL_NEAREST, SOIL_FLAG_INVERT_Y);
textures.addTexture("Data/alalei.bmp",
GL_LINEAR, GL_LINEAR, SOIL_FLAG_INVERT_Y);
textures.addTexture("Data/alalei.bmp",
GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR,
SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y);
textures.selectNextTexture();
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glClearDepth(1.);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glColor4f(1.f, 1.f, 1.f, .5f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
setKeyActions();
light.init();
light.switchLight();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
glutInitWindowSize(500, 500);
glutInitWindowPosition(150, 150);
glutCreateWindow("bitdewy openGL practice");
glutReshapeFunc(reshape);
glutKeyboardFunc(processNormalKeyPress);
glutSpecialFunc(processSpecialKeyPress);
initGL();
glutDisplayFunc(display);
glutTimerFunc(50, refresh, 0);
glutMainLoop();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment