Help us understand the problem. What is going on with this article?

SDL2とopenglの連携例

More than 3 years have passed since last update.

環境はwindows xp 32
以下のサイトを参考にしました
http://tacoika.blog87.fc2.com/blog-entry-322.html
http://d.hatena.ne.jp/yano-htn/20120226/1330263041
CMakeを使わず用意されているslnでコンパイルすることをお勧めします。CMakeは素人が触ればリンクエラーの宝庫です

基本

main.cpp
/* -*- coding:utf-8 -*- */

/**
 * sdl_with_opengl.cpp
 */
#pragma comment(lib, "SDL2.lib")
#pragma comment(lib, "SDL2main.lib")
#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"glu32.lib")

#include <SDL.h>
#include <SDL_opengl.h>
#include <GL/glu.h>

#include <iostream>
#include <string>

#include <cmath>

static const std::string WINDOW_CAPTION = "SDL with OpenGL";
static const Uint32 WINDOW_WIDTH = 640;
static const Uint32 WINDOW_HEIGHT = 480;
static const Uint32 WINDOW_BPP = 32;

static const Uint32 FPS = 60;

static SDL_Window* window;
static SDL_GLContext context;

bool init();
bool finalize();

void update();
void draw();
bool pollingEvent();

int main(int argc, char *argv[]) {
    // initialize
    if (!init()) {
        std::cerr << "ERROR: failed to initialize SDL" << std::endl;
        exit(1);
    }

    // mainloop
    static const Uint32 interval = 1000 / FPS;
    static Uint32 nextTime = SDL_GetTicks() + interval;
    bool skipDraw = false;
    while (true) {
        // check event
        if (!pollingEvent()) break;

        // update and draw
        update();
        if (!skipDraw) {
            draw();
            SDL_GL_SwapWindow(window);
        }

        int delayTime = (int)(nextTime - SDL_GetTicks());
        if (delayTime > 0) {
            SDL_Delay((Uint32)delayTime);
            skipDraw = false;
        } else {
            // skip next draw step because of no time
            skipDraw = true;
        }

        nextTime += interval;
    }

    // finalize
    finalize();

    return 0;
}

bool init() {
    // initialize SDL
    if( SDL_Init(SDL_INIT_VIDEO) < 0 ) return false;

    // enable double buffering
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

    // create indow
    // set SDL_WINDOW_OPENGL to use opengl for drawing
    window = SDL_CreateWindow(WINDOW_CAPTION.c_str(),
                              SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
                              WINDOW_WIDTH, WINDOW_HEIGHT,
                              SDL_WINDOW_OPENGL);
    if (!window) return false;

    // create OpenGL context
    context = SDL_GL_CreateContext(window);
    if (!context) return false;

    // setup viewport
    glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glEnable(GL_DEPTH_TEST);

    // setup projection matrix
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0, (GLdouble) WINDOW_WIDTH / (GLdouble) WINDOW_HEIGHT, 2.0, 200.0);

    // setup light
    static GLfloat position[] = {-10.0f, 10.0f, 10.0f, 1.0f};
    static GLfloat ambient [] = { 1.0f, 1.0f, 1.0f, 1.0f};
    static GLfloat diffuse [] = { 1.0f, 1.0f, 1.0f, 1.0f};
    static GLfloat specular[] = { 0.0f, 0.0f, 0.0f, 0.0f};
    glLightfv(GL_LIGHT0, GL_POSITION, position);
    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
    glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
    glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

    return true;
}

bool finalize() {
  // finalize SDL
  SDL_Quit();

  return true;
}

void update() {
}

void draw() {
    // clear
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // setup view
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt( 0.0f,  0.0f,-30.0f,
               0.0f,  0.0f, 0.0f,
               0.0f, -1.0f, 0.0f);

    // setup material
    GLfloat ambient  [] = { 0.1f, 0.1f, 0.1f, 1.0f};
    GLfloat diffuse  [] = { 1.0f, 0.0f, 0.0f, 1.0f};
    GLfloat specular [] = { 1.0f, 1.0f, 1.0f, 1.0f};
    GLfloat shininess[] = { 0.0f};
    glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
    glMaterialfv(GL_FRONT, GL_SHININESS, shininess);

    // draw sphere
    GLUquadric* quadric = gluNewQuadric();
    gluSphere(quadric, 10.0, 30, 30);
    gluDeleteQuadric(quadric);
}

// polling event and execute actions
bool pollingEvent()
{
    SDL_Event ev;
    SDL_Keycode key;
    while ( SDL_PollEvent(&ev) )
    {
        switch(ev.type){
        case SDL_QUIT:
            // raise when exit event is occur
            return false;
            break;
        case SDL_KEYDOWN:
        // raise when key down
        {
            key = ev.key.keysym.sym;
            // ESC
            if(key == SDLK_ESCAPE){
                return false;
            }
        }
        break;
        }
    }
    return true;
}

分離(やってることは基本と同じ)

冗長だからSDLとopenglの結合部分をクラスにして隠蔽した。
このsdlglを継承してdrawの中身だけを書けばいい。

sdlgl.h
#pragma once
#pragma comment(lib,"SDL2.lib")
#pragma comment(lib,"SDL2main.lib")
#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"glu32.lib")
#include <SDL.h>
#include <SDL_opengl.h>
#include <GL/glu.h>

class   SDLGL{
    void    setview(int w,int h){
        // setup viewport&projection
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        glEnable(GL_DEPTH_TEST);
        glViewport(0, 0, w, h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        perspective(w,h);
        //glOrtho(0 , w , h , 0 , 2 , 200);
    }
    bool finalize() {
      // finalize SDL
      SDL_Quit();
      return true;
    }
    // polling event and execute actions
    bool pollingEvent(){
        SDL_Event ev;
        SDL_Keycode key;
        while ( SDL_PollEvent(&ev) )
        {
            switch(ev.type){
                case    SDL_WINDOWEVENT:
                    if(ev.window.event==SDL_WINDOWEVENT_RESIZED)setview(ev.window.data1,ev.window.data2);
                    break;
                case    SDL_QUIT:
                    // raise when exit event is occur
                    return false;
                    break;
                case SDL_KEYDOWN:
                // raise when key down
                {
                    key = ev.key.keysym.sym;
                    // ESC
                    if(key == SDLK_ESCAPE){
                        return false;
                    }
                }
                break;
            }
        }
        return true;
    }
public:
    signed  start(char*title,int w=600,int h=400){
        SDL_Window* window;
        SDL_GLContext context;
        // initialize SDL
        if( SDL_Init(SDL_INIT_VIDEO) < 0 ) return false;

        // enable double buffering
        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

        // create indow
        // set SDL_WINDOW_OPENGL to use opengl for drawing
        window = SDL_CreateWindow(title,
                                  SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
                                  w, h,
                                  SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
        if (!window)return 1;

        // create OpenGL context
        context = SDL_GL_CreateContext(window);
        if (!context)return 1;

        // setup viewport&projection
        setview(w, h);

        // setup light
        static GLfloat position[] = {-10.0f, 10.0f, 10.0f, 1.0f};
        static GLfloat ambient [] = { 1.0f, 1.0f, 1.0f, 1.0f};
        static GLfloat diffuse [] = { 1.0f, 1.0f, 1.0f, 1.0f};
        static GLfloat specular[] = { 0.0f, 0.0f, 0.0f, 0.0f};
        glLightfv(GL_LIGHT0, GL_POSITION, position);
        glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
        glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
        glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
        glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
        glEnable(GL_LIGHTING);
        glEnable(GL_LIGHT0);

        // mainloop
        while (true) {
            // check event
            if (!pollingEvent()) break;
            //draw
            glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
            draw();
            SDL_GL_SwapWindow(window);
        }

        // finalize
        finalize();
        return  0;
    }
    virtual void    draw(){
        // setup view
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        gluLookAt( 0.0f,  0.0f,-30.0f,
                   0.0f,  0.0f, 0.0f,
                   0.0f, -1.0f, 0.0f);

        // setup material
        GLfloat ambient  [] = { 0.1f, 0.1f, 0.1f, 1.0f};
        GLfloat diffuse  [] = { 1.0f, 0.0f, 0.0f, 1.0f};
        GLfloat specular [] = { 1.0f, 1.0f, 1.0f, 1.0f};
        GLfloat shininess[] = { 0.0f};
        glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
        glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
        glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
        glMaterialfv(GL_FRONT, GL_SHININESS, shininess);

        // draw sphere
        GLUquadric* quadric = gluNewQuadric();
        gluSphere(quadric, 10.0, 30, 30);
        gluDeleteQuadric(quadric);
    }
    virtual void    perspective(int w,int h){
        gluPerspective(45.0, (GLdouble) w / (GLdouble) h, 2.0, 200.0);
    }
};
main.cpp
#include"sdlgl.h"

struct  MYSDLGL:public  SDLGL{
    virtual void    perspective(int w,int h){
        gluPerspective(45.0, (GLdouble) w / (GLdouble) h, 2.0, 200.0);
    }
    virtual void    draw(){
        // setup view
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        gluLookAt( 0.0f,  0.0f,-30.0f,
                   0.0f,  0.0f, 0.0f,
                   0.0f, -1.0f, 0.0f);

        // setup material
        GLfloat ambient  [] = { 0.1f, 0.1f, 0.1f, 1.0f};
        GLfloat diffuse  [] = { 1.0f, 0.0f, 0.0f, 1.0f};
        GLfloat specular [] = { 1.0f, 1.0f, 1.0f, 1.0f};
        GLfloat shininess[] = { 0.0f};
        glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
        glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
        glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
        glMaterialfv(GL_FRONT, GL_SHININESS, shininess);

        // draw sphere
        GLUquadric* quadric = gluNewQuadric();
        gluSphere(quadric, 10.0, 30, 30);
        gluDeleteQuadric(quadric);
    }
};
int main(int argc, char *argv[]){
    MYSDLGL gl;
    gl.start("nemui");
    return  0;
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした