 
   
   
   
   
   
   
   
   
   
   
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?
