Created
April 7, 2013 10:39
-
-
Save bitdewy/5329958 to your computer and use it in GitHub Desktop.
openGL practice
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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