SDL游戏之路(八)--2D游戏添加3D元素

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<nRD; i++)
	{
		SDL_RendererInfo info;
		if(!SDL_GetRenderDriverInfo(i, &info))
		{
			if(!strcmp(info.name, "opengl"))
			{
				oglIdx = i;
			}
		}
	}
	m_screen_renderer = SDL_CreateRenderer(m_screen_window, oglIdx,
			SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC);

#else
	m_screen_renderer = SDL_CreateRenderer(m_screen_window, -1,
			SDL_RENDERER_ACCELERATED);
#endif
	if (m_screen_renderer == NULL) {
		return -4;
	}
	g_SP.setScreen(skypark_ScreenWidth, skypark_ScreenHeight);
#else
	m_screen_renderer = &g_SkRenderer;
#endif
	return 0;
}


第二步:

如何实现坐标的统一呢?

上一章我们已经实现了平台的坐标自适应。所有 我们当然希望在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的元素。

效果图如下:(蓝色部分为游戏全部场景)



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值