"Hello, World" in SDL/OpenGL
Here's a small "hello, world" demo program written in C++ using SDL and OpenGL. It was successfully compiled with Visual Studio 8 along with SDL and SDL_ttf libraries. You can get SDL and SDL_ttf from sourceforge.net.
The program is based on the code provided by Ernest Pazera, the author of "Focus on SDL", the Premier Press Game Development Series.
Since I don't like to use VS IDE, I opted to use nmake instead. It makes programming much easier for me.
=====================================================================================
The program is based on the code provided by Ernest Pazera, the author of "Focus on SDL", the Premier Press Game Development Series.
Since I don't like to use VS IDE, I opted to use nmake instead. It makes programming much easier for me.
=====================================================================================
// ===========================================================================
// HelloWorld.h
//
// CJKim, Octo Simple LLC, 01-May-07
//
// include SDL stuff
#include "SDL.h"
#include "SDL_ttf.h"
class CHelloWorld
{
private:
SDL_Surface* m_pDisplaySurface;
SDL_Surface* m_pTextSurf0;
SDL_Surface* m_pTextSurf1;
SDL_Surface* m_pTextSurf2;
SDL_Surface* m_pTextSurf3;
TTF_Font* m_pLargeFont;
TTF_Font* m_pSmallFont;
int m_skipLarge;
int m_skipSmall;
static int m_ScreenWidth;
static int m_ScreenHeight;
void CalcLoc(SDL_Surface* sfc, SDL_Rect& src, SDL_Rect& dst);
public:
CHelloWorld(char *fontName);
virtual ~CHelloWorld();
void Render();
void Italicize();
};
// -- end of HelloWorld.h --
// ===========================================================================
// HelloWorld.cpp -- "Hello, World" in SDL
//
// CJKim, Octo Simple LLC, 01-May-07
// based on ernest pazera's work 10JUN2002
//
// requires static linkage to:
// SDL.lib, SDLmain.lib, SDL_ttf.lib
// for Windows, requires dynamic linkage to:
// sdl.dll, sdl_ttf.dll
#include <iostream>
#include <stdlib.h>
#include "HelloWorld.h"
// screen dimensions
int CHelloWorld::m_ScreenWidth = 640;
int CHelloWorld::m_ScreenHeight = 480;
#undef main
void CHelloWorld::CalcLoc(SDL_Surface *s, SDL_Rect &src, SDL_Rect &dst)
{
// source rectangle
src.x = src.y = 0;
src.w = s->w;
src.h = s->h;
// destination rectangle
dst = src;
dst.x = (m_ScreenWidth - dst.w) / 2;
dst.y = (m_ScreenHeight - dst.h) / 2;
}
CHelloWorld::CHelloWorld(char *fontName = "arial.ttf") :
m_pDisplaySurface(NULL),
m_pLargeFont(NULL),
m_pSmallFont(NULL),
m_skipLarge(58),
m_skipSmall(14)
{
// initialize SDL
if (SDL_Init(SDL_INIT_VIDEO)==-1) {
std::cerr << "Could not initialize SDL!" << std::endl;
exit(1);
}
std::cerr << "SDL Initialization Completed." << std::endl;
// set up to uninitialize SDL at exit
atexit(SDL_Quit);
SDL_WM_SetCaption("Hello, world!", "Hello, world!");
// create windowed environment
m_pDisplaySurface = SDL_SetVideoMode(m_ScreenWidth, m_ScreenHeight, 0, SDL_ANYFORMAT);
if (m_pDisplaySurface == NULL) {
std::cerr << "Could not set up display surface!" << std::endl;
exit(1);
}
//initialize SDL_ttf
if (TTF_Init() < 0) {
std::cerr << "Unable to initialize TTF: " << TTF_GetError() << std::endl;
exit(1);
}
// open fonts
m_pLargeFont = TTF_OpenFont(fontName, 50);
m_pSmallFont = TTF_OpenFont(fontName, 12);
if (NULL == m_pLargeFont || NULL == m_pSmallFont) {
std::cerr << "Cannot load " << fontName << ": " << TTF_GetError() << std::endl;
exit(1);
}
std::cout << "Using " << fontName << ", Size 50 and 12" << std::endl;
// see how many pixels need to be skipped to print the next line
m_skipLarge = TTF_FontLineSkip(m_pLargeFont);
m_skipSmall = TTF_FontLineSkip(m_pSmallFont);
std::cout << "Large Font Skip = " << int(m_skipLarge) << " Pixels" << std::endl;
std::cout << "Small Font Skip = " << int(m_skipSmall) << " Pixels" << std::endl;
}
CHelloWorld::~CHelloWorld()
{
// destroy text surface
SDL_FreeSurface(m_pTextSurf0);
SDL_FreeSurface(m_pTextSurf3);
SDL_FreeSurface(m_pTextSurf2);
SDL_FreeSurface(m_pTextSurf1);
// close the font
TTF_CloseFont(m_pSmallFont);
TTF_CloseFont(m_pLargeFont);
// quit SDL_ttf
TTF_Quit();
}
void CHelloWorld::Render()
{
// set up colors
SDL_Color fgcolor, bgcolor, instcolor;
fgcolor.r = 255; // black
fgcolor.g = 255;
fgcolor.b = 255;
bgcolor.r = 128; // gray
bgcolor.g = 128;
bgcolor.b = 128;
instcolor.r = 0;
instcolor.g = 128;
instcolor.b = 128;
// render text
m_pTextSurf1 = TTF_RenderText_Solid( m_pLargeFont, "Solid: Hello, world!", fgcolor);
m_pTextSurf2 = TTF_RenderText_Shaded( m_pLargeFont, "Shaded: Hello, world!", fgcolor, bgcolor);
m_pTextSurf3 = TTF_RenderText_Blended(m_pLargeFont, "Blended: Hello, world!", fgcolor);
m_pTextSurf0 = TTF_RenderText_Solid( m_pSmallFont, "Hit Escape to Quit", instcolor);
//rectangles
SDL_Rect rcSrc;
SDL_Rect rcDst;
// blit the surface
CalcLoc(m_pTextSurf1, rcSrc, rcDst); rcDst.y -= m_skipLarge * 1;
SDL_BlitSurface(m_pTextSurf1, &rcSrc, m_pDisplaySurface, &rcDst);
CalcLoc(m_pTextSurf2, rcSrc, rcDst); rcDst.y += m_skipLarge * 0 + (-3 + rand() % 6);
SDL_BlitSurface(m_pTextSurf2, &rcSrc, m_pDisplaySurface, &rcDst);
CalcLoc(m_pTextSurf3, rcSrc, rcDst); rcDst.y += m_skipLarge * 1;
SDL_BlitSurface(m_pTextSurf3, &rcSrc, m_pDisplaySurface, &rcDst);
// instruction text at the bottom of the screen
rcSrc.x = rcSrc.y = 0;
rcSrc.w = m_pTextSurf0->w; rcSrc.h = m_pTextSurf0->h;
rcDst = rcSrc;
rcDst.x = (m_ScreenWidth - rcDst.w) / 2;
rcDst.y = (m_ScreenHeight - m_skipSmall - 5);
SDL_BlitSurface(m_pTextSurf0, &rcSrc, m_pDisplaySurface, &rcDst);
SDL_UpdateRect(m_pDisplaySurface, 0, 0, 0, 0);
}
void CHelloWorld::Italicize()
{
TTF_SetFontStyle(m_pLargeFont, TTF_STYLE_ITALIC);
}
void mainloop(CHelloWorld* hw)
{
// repeat until quitting
for (bool done = false; !done; ) {
//event structure
SDL_Event event;
// wait for an event
if (SDL_PollEvent(&event) == 0) {
hw->Render(); // update the screen
SDL_Delay(100);
continue;
}
//event occurred, check for quit
if (event.type == SDL_QUIT) {
done = true;
break;
}
if (event.type == SDL_KEYDOWN) {
switch (event.key.keysym.sym) {
case SDLK_ESCAPE:
done = true;
break;
default:
break;
}
}
}
}
// main function
int main(int argc, char* argv[])
{
CHelloWorld* pHW = new CHelloWorld();
pHW->Italicize(); // show it in italic
pHW->Render(); // paint the canvas, van gogh
mainloop(pHW); // loop until the user quits
delete pHW; // get rid of it
std::cout << "SDL Demo Program Exits Normally." << std::endl;
return (0);
}
// -- end of ttf.cpp --
#==================================================================================
#
# nmake makefile for HelloWorld.cpp
#
CFLAGS= \
/I "\work\games\SDL-1.2.11-dev\include" \
/I "\work\games\SDL_ttf-2.0.8\include" \
/EHsc
LDFLAGS= \
/LIBPATH:"\work\games\SDL-1.2.11-dev\lib" \
/LIBPATH:"\work\games\SDL_ttf-2.0.8\lib" \
SDL_ttf.lib \
SDL.lib \
glu32.lib \
opengl32.lib \
kernel32.lib \
user32.lib \
gdi32.lib \
advapi32.lib \
shell32.lib
PROGRAMS=HelloWorld.exe
# image_viewer.exe: image_viewer.cpp
# cl image_viewer.cpp $(CFLAGS) /link $(LDFLAGS)
all: $(PROGRAMS)
HelloWorld.obj: HelloWorld.cpp
$(CC) /nologo /c $(CFLAGS) HelloWorld.cpp
HelloWorld.exe: HelloWorld.obj
link /NOLOGO /OUT:HelloWorld.exe $(LDFLAGS) HelloWorld.obj
clean:
del $(PROGRAMS) *.obj
new: clean all
