Blame projects/asteroid/main.cpp

Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
#include <ctime>
Ivan Mahonin 223ac6
#include <cstdlib>
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
#include <string>
Ivan Mahonin 223ac6
#include <iostream>
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
#include <GL/gl.h>
Ivan Mahonin 223ac6
#include <SDL2/SDL.h>
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
#include "geometry.h"
Ivan Mahonin 223ac6
#include "scene.h"
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
class Main {
Ivan Mahonin 223ac6
public:
Ivan Mahonin 223ac6
    bool sdl_initialized;
Ivan Mahonin 223ac6
    SDL_Window *mainWindow;
Ivan Mahonin 223ac6
    SDL_GLContext mainContext;
Ivan Mahonin 223ac6
    Scene *scene;
Ivan Mahonin 223ac6
    
Ivan Mahonin 223ac6
    Main():
Ivan Mahonin 223ac6
        sdl_initialized(),
Ivan Mahonin 223ac6
        mainWindow(),
Ivan Mahonin 223ac6
        mainContext(),
Ivan Mahonin 223ac6
        scene()
Ivan Mahonin 223ac6
    { }
Ivan Mahonin 223ac6
    
Ivan Mahonin 223ac6
    ~Main() { deinit(); }
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
    bool init() {
Ivan Mahonin 223ac6
        srand(time(NULL));
Ivan Mahonin 223ac6
        
Ivan Mahonin 223ac6
        if (SDL_Init(SDL_INIT_VIDEO) < 0) {
Ivan Mahonin 223ac6
            std::cerr << "SDL_Init failed" << std::endl;
Ivan Mahonin 223ac6
            deinit();
Ivan Mahonin 223ac6
            return false;
Ivan Mahonin 223ac6
        }
Ivan Mahonin 223ac6
        sdl_initialized = true;
Ivan Mahonin 223ac6
        
Ivan Mahonin 223ac6
        mainWindow = SDL_CreateWindow(
Ivan Mahonin 223ac6
            "simu",
Ivan Mahonin 223ac6
            SDL_WINDOWPOS_CENTERED,
Ivan Mahonin 223ac6
            SDL_WINDOWPOS_CENTERED,
Ivan Mahonin 223ac6
            512,
Ivan Mahonin 223ac6
            512,
Ivan Mahonin 223ac6
            SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE );
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
        if (!mainWindow)
Ivan Mahonin 223ac6
        {
Ivan Mahonin 223ac6
            std::cerr << "cannot create window" << std::endl;
Ivan Mahonin 223ac6
            std::cerr << SDL_GetError() << std::endl;
Ivan Mahonin 223ac6
            SDL_ClearError();
Ivan Mahonin 223ac6
            deinit();
Ivan Mahonin 223ac6
            return false;
Ivan Mahonin 223ac6
        }
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
        mainContext = SDL_GL_CreateContext(mainWindow);
Ivan Mahonin 223ac6
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
Ivan Mahonin 223ac6
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
Ivan Mahonin 223ac6
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
Ivan Mahonin 223ac6
        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
        // vsync
Ivan Mahonin 223ac6
        SDL_GL_SetSwapInterval(1);
Ivan Mahonin 223ac6
        
Ivan Mahonin 223ac6
        scene = new Scene();
Ivan Mahonin 223ac6
        
Ivan Mahonin 223ac6
        glClearColor(0.0, 0.0, 0.0, 0.0);
Ivan Mahonin 223ac6
        glEnable(GL_LINE_SMOOTH);
Ivan Mahonin 223ac6
        glEnable(GL_POINT_SMOOTH);
Ivan Mahonin 223ac6
        glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
Ivan Mahonin 223ac6
        glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
        glEnable(GL_NORMALIZE);
Ivan Mahonin 223ac6
        glDisable(GL_DEPTH_TEST);
Ivan Mahonin 223ac6
        
Ivan Mahonin 223ac6
        glEnable(GL_LIGHT0);
Ivan Mahonin 223ac6
        float light0[] = {1, 1, 1, 0};
Ivan Mahonin 223ac6
        glLightfv(GL_LIGHT0, GL_POSITION, light0);
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
        glEnable(GL_LIGHT1);
Ivan Mahonin 223ac6
        float light1[] = {-1, -1, -1, 0};
Ivan Mahonin 223ac6
        float color[] = {0.5, 0.5, 0.5, 1};
Ivan Mahonin 223ac6
        glLightfv(GL_LIGHT1, GL_POSITION, light1);
Ivan Mahonin 223ac6
        glLightfv(GL_LIGHT1, GL_DIFFUSE, color);
Ivan Mahonin 223ac6
        //glLightfv(GL_LIGHT1, GL_SPECULAR, color);
Ivan Mahonin 223ac6
        
Ivan Mahonin 223ac6
        glEnable(GL_COLOR_MATERIAL);
Ivan Mahonin 223ac6
        
Ivan Mahonin 223ac6
        resize(512, 512);
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
        return true;
Ivan Mahonin 223ac6
    }
Ivan Mahonin 223ac6
    
Ivan Mahonin 223ac6
    void deinit() {
Ivan Mahonin 223ac6
        if (scene) { delete scene; scene = 0; }
Ivan Mahonin 223ac6
        if (mainContext) { SDL_GL_DeleteContext(mainContext); mainContext = 0; }
Ivan Mahonin 223ac6
        if (mainWindow) { SDL_DestroyWindow(mainWindow); mainWindow = 0; }
Ivan Mahonin 223ac6
        if (sdl_initialized) { SDL_Quit(); sdl_initialized = false; }
Ivan Mahonin 223ac6
    }
Ivan Mahonin 223ac6
    
Ivan Mahonin 223ac6
    void resize(int width, int height) {
Ivan Mahonin 223ac6
        glViewport(0, 0, width, height);
Ivan Mahonin 223ac6
        glMatrixMode(GL_PROJECTION);
Ivan Mahonin 223ac6
        glLoadMatrixd( Matrix4::perspective(90.0, (Real)width/height, 0.1, 100).a );
Ivan Mahonin 223ac6
        glMatrixMode(GL_MODELVIEW);
Ivan Mahonin 223ac6
    }
Ivan Mahonin 223ac6
    
Ivan Mahonin 223ac6
    void loop() {
Ivan Mahonin 223ac6
        bool quit = false;
Ivan Mahonin 223ac6
        Uint32 prev_time = SDL_GetTicks();
Ivan Mahonin 223ac6
        while(!quit) {
Ivan Mahonin 223ac6
            SDL_Event event;
Ivan Mahonin 223ac6
            while (SDL_PollEvent(&event)) {
Ivan Mahonin 223ac6
                if (event.type == SDL_QUIT)
Ivan Mahonin 223ac6
                    quit = true;
Ivan Mahonin 223ac6
                if (event.type == SDL_WINDOWEVENT) {
Ivan Mahonin 223ac6
                    if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
Ivan Mahonin 223ac6
                        resize(event.window.data1, event.window.data2);
Ivan Mahonin 223ac6
                    }
Ivan Mahonin 223ac6
                }
Ivan Mahonin 223ac6
                if (event.type == SDL_KEYDOWN) {
Ivan Mahonin 223ac6
                    switch (event.key.keysym.sym) {
Ivan Mahonin 223ac6
                    case SDLK_ESCAPE:
Ivan Mahonin 223ac6
                        quit = true;
Ivan Mahonin 223ac6
                        break;
Ivan Mahonin 223ac6
                    case SDLK_w:
Ivan Mahonin 223ac6
                        scene->wireframe = !scene->wireframe;
Ivan Mahonin 223ac6
                        break;
Ivan Mahonin 223ac6
                    case SDLK_r:
Ivan Mahonin 223ac6
                        scene->generate();
Ivan Mahonin 223ac6
                        break;
Ivan Mahonin 223ac6
                    default:
Ivan Mahonin 223ac6
                        break;
Ivan Mahonin 223ac6
                    }
Ivan Mahonin 223ac6
                }
Ivan Mahonin 223ac6
                if (event.type == SDL_MOUSEMOTION) {
Ivan Mahonin 223ac6
                    if (event.motion.state & SDL_BUTTON_LMASK) {
Ivan Mahonin 223ac6
                        scene->angles.z += event.motion.xrel;
Ivan Mahonin 223ac6
                        scene->angles.x += event.motion.yrel;
Ivan Mahonin 223ac6
                    }
Ivan Mahonin 223ac6
                    if (event.motion.state & SDL_BUTTON_RMASK) {
Ivan Mahonin 223ac6
                        scene->offset.z *= pow(2, event.motion.yrel/100.0);
Ivan Mahonin 223ac6
                    }
Ivan Mahonin 223ac6
                    if (event.motion.state & SDL_BUTTON_MMASK) {
Ivan Mahonin 223ac6
                        scene->offset.x += 0.1*event.motion.xrel;
Ivan Mahonin 223ac6
                        scene->offset.y -= 0.1*event.motion.yrel;
Ivan Mahonin 223ac6
                    }
Ivan Mahonin 223ac6
                }
Ivan Mahonin 223ac6
            }
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
            Uint32 curr_time = SDL_GetTicks();
Ivan Mahonin 223ac6
            double dt = (curr_time - prev_time)/1000.0;
Ivan Mahonin 223ac6
            prev_time = curr_time;
Ivan Mahonin 223ac6
            
Ivan Mahonin 223ac6
            scene->update(dt);
Ivan Mahonin 223ac6
            
Ivan Mahonin 223ac6
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Ivan Mahonin 223ac6
            scene->draw();
Ivan Mahonin 223ac6
            SDL_GL_SwapWindow(mainWindow);
Ivan Mahonin 223ac6
        }
Ivan Mahonin 223ac6
    }
Ivan Mahonin 223ac6
};
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
int main(int argc, char **argv)
Ivan Mahonin 223ac6
{
Ivan Mahonin 223ac6
    Main app;
Ivan Mahonin 223ac6
    if (!app.init()) return -1;
Ivan Mahonin 223ac6
    app.loop();
Ivan Mahonin 223ac6
    return 0;
Ivan Mahonin 223ac6
}