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