1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SDL2とopenglの連携例

Last updated at Posted at 2016-04-10

環境は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;
}
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?