CS116b/CS216
Chris Pollett
Feb 24, 2014
#ifndef _MYSDLAPPLICATION_H_ #define _MYSDLAPPLICATION_H_ #include <iostream> #include <SDL2/SDL.h> #ifdef __WIN32__ #undef main #include <SDL2/SDL_image.h> #else #include <SDL2_image/SDL_image.h> #endif class MySdlApplication { private: bool running; SDL_Window* display; void keyboard(const char * key); void mouse(SDL_MouseButtonEvent button); void motion(const int x, const int y); public: MySdlApplication(); int onExecute(); bool onInit(); void onEvent(SDL_Event* Event); void onLoop(); void onRender(); void onCleanup(); }; #endif
BASE = MySdlApplication all: $(BASE) OS := $(shell uname -s) ifeq ($(OS), Linux) # Science Center Linux Boxes CPPFLAGS = -I/home/l/i/lib175/usr/glew/include LDFLAGS += -L/home/l/i/lib175/usr/glew/lib -L/usr/X11R6/lib LIBS += -lGL -lGLU -lSDL2 -lSDL2_image endif ifeq ($(OS), Darwin) # Assume OS X CPPFLAGS += -D__MAC__ -I/usr/local/Cellar/glew/1.10.0/include/ --stdlib=libstdc++ -Wno-deprecated LDFLAGS += -framework SDL2 -framework SDL2_image -framework OpenGL -L/usr/local/Cellar/glew/1.10.0/lib/ endif ifdef OPT #turn on optimization CXXFLAGS += -O2 else #turn on debugging CXXFLAGS += -g endif CXX = g++ OBJ = $(BASE).o ppm.o glsupport.o $(BASE): $(OBJ) $(LINK.cpp) -o $@ $^ $(LIBS) -lGLEW clean: rm -f $(OBJ) $(BASE)
int MySdlApplication::onExecute() { if(onInit() == false) { return -1; } SDL_Event Event; while(running) { while(SDL_PollEvent(&Event)) { onEvent(&Event); } onLoop(); onRender(); } onCleanup(); return 0; } int main(int argc, const char * argv[]) { MySdlApplication application; return application.onExecute(); }
bool MySdlApplication::onInit() { if(SDL_Init(SDL_INIT_EVERYTHING) < 0) { return false; } SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); /* Turn on double buffering with a 24bit Z buffer. * You may need to change this to 16 or 32 for your system */ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); if((display = SDL_CreateWindow("My SDL Application", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_OPENGL)) == NULL) { return false; } /* Create our opengl context and attach it to our window */ SDL_GLContext maincontext = SDL_GL_CreateContext(display); /* This makes our buffer swap syncronized with the monitor's vertical refresh */ SDL_GL_SetSwapInterval(1); glewInit(); cout << (g_Gl2Compatible ? "Will use OpenGL 2.x / GLSL 1.0" : "Will use OpenGL 3.x / GLSL 1.3") << endl; if ((!g_Gl2Compatible) && !GLEW_VERSION_3_0) throw runtime_error( "Error: does not support OpenGL Shading Language v1.3"); else if (g_Gl2Compatible && !GLEW_VERSION_2_0) throw runtime_error( "Error: does not support OpenGL Shading Language v1.0"); initGLState(); initShaders(); initGeometry(); initTextures(); return true; }
static void loadTexture(GLuint type, GLuint texHandle, const char *ppmFilename) { int texWidth, texHeight; // vector<PackedPixel> pixData; // ppmRead(ppmFilename, texWidth, texHeight, pixData); SDL_Surface* newSurface = IMG_Load(ppmFilename); // read in image SDL_Surface* returnSurface; if(newSurface == NULL) { cout << ":_( Surface null" <<endl; return; } returnSurface = SDL_ConvertSurfaceFormat(newSurface, SDL_PIXELFORMAT_RGB24, 0); // need to convert to RGB from RGBA texWidth = returnSurface->w; texHeight = returnSurface->h; glActiveTexture(type); glBindTexture(GL_TEXTURE_2D, texHandle); // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texWidth, // texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixData[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texWidth, texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, returnSurface->pixels); SDL_FreeSurface(newSurface); SDL_FreeSurface(returnSurface); checkGlErrors(); }
void MySdlApplication::onEvent(SDL_Event* event) { switch(event->type) { case SDL_QUIT: running = false; break; case SDL_KEYUP: keyboard(SDL_GetKeyName(event->key.keysym.sym)); break; case SDL_MOUSEBUTTONDOWN: mouse(event->button); break; case SDL_MOUSEBUTTONUP: mouse(event->button); break; case SDL_MOUSEMOTION: motion(event->motion.x, event->motion.y); break; } } void MySdlApplication::keyboard(const char* key) { switch (key[0]) { case 27: //ESC exit(0); case 'H': cout << " ============== H E L P ==============\n\n" << "h\t\thelp menu\n" << "s\t\tsave screenshot\n" << "t\t\ttoggle between shaders\n" << "drag left mouse to rotate\n" << endl; break; case 'S': glFlush(); writePpmScreenshot(g_windowWidth, g_windowHeight, "out.ppm"); break; case 'T': g_activeShader++; if(g_activeShader >= g_numShaders) { g_activeShader = 0; } break; } } void MySdlApplication::mouse(SDL_MouseButtonEvent button) { g_mouseClickX = button.x; g_mouseClickY = g_windowHeight - button.y - 1; g_mouseLClickButton |= (button.button == SDL_BUTTON_LEFT && button.state == SDL_PRESSED); g_mouseRClickButton |= (button.button == SDL_BUTTON_RIGHT && button.state == SDL_PRESSED); g_mouseMClickButton |= (button.button == SDL_BUTTON_MIDDLE && button.state == SDL_PRESSED); g_mouseLClickButton &= !(button.button == SDL_BUTTON_LEFT && button.state == SDL_RELEASED); g_mouseRClickButton &= !(button.button == SDL_BUTTON_RIGHT && button.state == SDL_RELEASED); g_mouseMClickButton &= !(button.button == SDL_BUTTON_MIDDLE && button.state == SDL_RELEASED); g_mouseClickDown = g_mouseLClickButton || g_mouseRClickButton || g_mouseMClickButton; } void MySdlApplication::motion(const int x, const int y) { const double dx = x - g_mouseClickX; const double dy = g_windowHeight - y - 1 - g_mouseClickY; Matrix4 m; if (g_mouseLClickButton && !g_mouseRClickButton) { // left button down? m = Matrix4::makeXRotation(-dy) * Matrix4::makeYRotation(dx); } else if (g_mouseRClickButton && !g_mouseLClickButton) { // right button down? m = Matrix4::makeTranslation(Cvec3(dx, dy, 0) * 0.01); } else if (g_mouseMClickButton || (g_mouseLClickButton && g_mouseRClickButton)) { // middle or (left and right) button down? m = Matrix4::makeTranslation(Cvec3(0, 0, -dy) * 0.01); } if (g_mouseClickDown) { g_objectRbt[0] *= m; // Simply right-multiply is WRONG } g_mouseClickX = x; g_mouseClickY = g_windowHeight - y - 1; }
void MySdlApplication::onRender() { glUseProgram(g_shaderStates[g_activeShader]->program); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear framebuffer color&depth drawStuff(); SDL_GL_SwapWindow(display); checkGlErrors(); }
Which of the following statements is true?