3D游戏如何制作呢?
2D游戏场景中加入3D元素怎么实现呢?
我的问题是,一个SDL写的2D游戏,如何在适当的地方添加3D元素?
经过不断的尝试和google,这个问题也解决了。
第一步:创建的SDL2的 窗口,视图需要和OpenGL的结合起来。
代码例子如下:
int SkComm::init() {
#ifndef __WP8__
#ifdef __SKYPARK_IPHONE__
int iRet = SDL_Init(SDL_INIT_VIDEO);
#else
#ifdef __SKYPARK_LINUX__
int iRet = SDL_Init(SDL_INIT_VIDEO);
#else
int iRet = SDL_Init(SDL_INIT_EVERYTHING);
#endif
#endif
if (iRet < 0) {
return -1;
}
iRet = TTF_Init();
if (iRet < 0) {
return -2;
}
int iPos = 0;
#ifdef __SKYPARK_WIN__
iPos = 40;
int skypark_ScreenWidth = 800;
int skypark_ScreenHeight = 600;
#endif
#ifdef __ANDROID__
int skypark_ScreenWidth = Android_ScreenWidth;
int skypark_ScreenHeight = Android_ScreenHeight;
#endif
#ifdef __SKYPARK_MAC__
iPos = 40;
int skypark_ScreenWidth = 800;
int skypark_ScreenHeight = 600;
#endif
#ifdef __SKYPARK_IPHONE__
int skypark_ScreenWidth = 480;
int skypark_ScreenHeight = 320;
#endif
#ifdef __SKYPARK_LINUX__
iPos = 40;
int skypark_ScreenWidth = 800;
int skypark_ScreenHeight = 600;
#endif
#ifdef HAVE_OPENGL
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); //设置GL版本的
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);//设置多缓存的个数
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);//设置深度缓存大小的,另外如果讲24改成32你会发现性能会下降很多很多很多很多的。
m_screen_window = SDL_CreateWindow("skypark", iPos, iPos,
skypark_ScreenWidth, skypark_ScreenHeight, SDL_WINDOW_OPENGL);
#else
m_screen_window = SDL_CreateWindow("skypark", iPos, iPos,
skypark_ScreenWidth, skypark_ScreenHeight, SDL_WINDOW_SHOWN);
#endif
if (m_screen_window == NULL) {
return -3;
}
#ifdef HAVE_OPENGL
m_glcontext = SDL_GL_CreateContext(m_screen_window);
int oglIdx = -1;
int nRD = SDL_GetNumRenderDrivers();
for(int i=0; i
第二步:
如何实现坐标的统一呢?
上一章我们已经实现了平台的坐标自适应。所有 我们当然希望在3D场景中,坐标也是自适应的。
如何做到呢?我们创建3D游戏场景的坐标顶点,取窗口的一半,就可以了。代码如下:
{
//g_SkComm.log("[%s][%d]context=%d", __FILE__, __LINE__, context);
glMatrixMode(GL_PROJECTION | GL_MODELVIEW);
glLoadIdentity();
//坐标统一,设置大小为窗口一半
glOrtho(-g_iScreenWidthHalf, g_iScreenWidthHalf, g_iScreenHeightHalf,
-g_iScreenHeightHalf, -1000, 1000);
sk_gl_setOrtho(-g_iScreenWidthHalf, g_iScreenWidthHalf,
g_iScreenHeightHalf, -g_iScreenHeightHalf, 0, 1);
}
第三步:
在游戏绘图线程中,绘制2D和绘制3D相互结合:
主循环:
while (true) {
SkEvent event;
while (g_SkComm.poll_event(&event)) {
g_SkGame.doEvent(&event);
}
Sint64 iCurTime = g_SkGameTimer.getGameMTime();
while (g_SkGameTimer.m_siGameLastTime + g_SkGameTimer.siGameLoopMsec
< iCurTime) {
g_SkGameTimer.m_siGameLastTime += g_SkGameTimer.siGameLoopMsec;
g_SkGameThread.run(g_SkGameTimer.m_siGameLastTime);
}
bool bShow = true;
while (siShowBegin + g_SkGameTimer.siShowLoopMsec < iCurTime) {
siShowBegin += g_SkGameTimer.siShowLoopMsec;
if (bShow) {
//g_SkGame.show(&g_SkShow);
{
Render();
}
g_SkShow.flush();
bShow = false;
}
}
//g_SkComm.log("[%s][%d]\n", __FILE__, __LINE__);
//g_SkComm.msleep(3000);
g_SkComm.msleep(SkGameTimer::siGameManLoopMsec);
}
游戏内容绘制:
static void Render() {
//绘制2D的游戏场景
glPushMatrix();
glLoadIdentity();
glOrtho(-g_iScreenWidthHalf, g_iScreenWidthHalf, g_iScreenHeightHalf,
-g_iScreenHeightHalf, -1000, 1000);
g_SkGame.show(&g_SkShow);
glPopMatrix();
glRotatef(5.0, 1.0, 1.0, 1.0);
//绘制3D的三角
{
float x = 30.0, y = 30.0;
glBegin (GL_TRIANGLES);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(x, y + 90.0);
glColor3f(0.0, 1.0, 0.0);
glVertex2f(x + 90.0, y - 90.0);
glColor3f(0.0, 0.0, 1.0);
glVertex2f(x - 90.0, y - 90.0);
glEnd();
}
//绘制3D的立方体
draw3D();
}
static void draw3D() {
static float color[8][3] = { { 1.0, 1.0, 0.0 }, { 1.0, 0.0, 0.0 }, { 0.0,
0.0, 0.0 }, { 0.0, 1.0, 0.0 }, { 0.0, 1.0, 1.0 }, { 1.0, 1.0, 1.0 },
{ 1.0, 0.0, 1.0 }, { 0.0, 0.0, 1.0 } };
static float cube[8][3] = { { 50, 50, -50 }, { 50, -50, -50 }, { -50, -50,
-50 }, { -50, 50, -50 }, { -50, 50, 50 }, { 50, 50, 50 }, { 50, -50,
50 }, { -50, -50, 50 } };
/* Do our drawing, too. */
//glClearColor(0.0, 0.0, 0.0, 1.0);
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin (GL_QUADS);
glColor3f(1.0, 0.0, 0.0);
glVertex3fv(cube[0]);
glVertex3fv(cube[1]);
glVertex3fv(cube[2]);
glVertex3fv(cube[3]);
glColor3f(0.0, 1.0, 0.0);
glVertex3fv(cube[3]);
glVertex3fv(cube[4]);
glVertex3fv(cube[7]);
glVertex3fv(cube[2]);
glColor3f(0.0, 0.0, 1.0);
glVertex3fv(cube[0]);
glVertex3fv(cube[5]);
glVertex3fv(cube[6]);
glVertex3fv(cube[1]);
glColor3f(0.0, 1.0, 1.0);
glVertex3fv(cube[5]);
glVertex3fv(cube[4]);
glVertex3fv(cube[7]);
glVertex3fv(cube[6]);
glColor3f(1.0, 1.0, 0.0);
glVertex3fv(cube[5]);
glVertex3fv(cube[0]);
glVertex3fv(cube[3]);
glVertex3fv(cube[4]);
glColor3f(1.0, 0.0, 1.0);
glVertex3fv(cube[6]);
glVertex3fv(cube[1]);
glVertex3fv(cube[2]);
glVertex3fv(cube[7]);
glEnd();
//glMatrixMode (GL_MODELVIEW);
//glRotatef(5.0, 1.0, 1.0, 1.0);
}
好了,到这里,我们就实现了,在2D的游戏场景里面添加了2个3D的元素。
效果图如下:(蓝色部分为游戏全部场景)