⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sscroll.c

📁 一段linux下用OpenGL实现的小程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------	Smooth Scrolling------------------------------------------------------------ * Using OpenGL and sub-pixel accurate rendering. * Map editor included. :-) * * Copyright (c) David Olofson <david@olofson.net>, 2002 * * This software is released under the terms of the GPL. */#include <stdlib.h>#include <string.h>#include <math.h>#include "SDL.h"#if HAS_SDL_OPENGL_H#include "SDL_opengl.h"#else#ifdef WIN32#include <windows.h>#endif#if defined(__APPLE__) && defined(__MACH__)#include <OpenGL/gl.h>#include <OpenGL/glu.h>#else#include <GL/gl.h>#include <GL/glu.h>#endif#endif/* Screen size (unscaled) */#define	SCREEN_W	320#define	SCREEN_H	240/* Tile size */#define	TILE_W		32#define	TILE_H		32/* Tile palette size (pixels) */#define	PALETTE_W	256#define	PALETTE_H	256/* Tile palette size (tiles) */#define	PALETTE_TW	(PALETTE_W / TILE_W)#define	PALETTE_TH	(PALETTE_H / TILE_H)/* Map size (tiles) */#define	MAP_W		32#define	MAP_H		16/*------------------------------------------------	Common stuff------------------------------------------------*/void (*video_draw_tile)(float x, float y, int tile);Uint32 (*video_map_rgb)(Uint8 r, Uint8 g, Uint8 b);void (*video_fillrect)(SDL_Rect *r, Uint32 color);void (*video_flip)(void);void (*video_close)(void);unsigned char	*map = NULL;int		flags = 0;		/* SDL video flags */int		bpp = 0;		/* Preferred screen bpp */int		scale = -1;		/* Screen scale factor */int		mscale;			/* Mouse scale factor */int		screen_w, screen_h;	/* Actual screen size */int		vscreen_w, vscreen_h;	/* Virtual screen size *//*------------------------------------------------	SDL mode------------------------------------------------*/SDL_Surface *screen = NULL;SDL_Surface *tiles = NULL;void draw_tile_sdl(float x, float y, int tile){	SDL_Rect source_rect, dest_rect;	source_rect.x = tile % PALETTE_TW * TILE_W;	source_rect.y = tile / PALETTE_TW * TILE_H;	source_rect.w = TILE_W;	source_rect.h = TILE_H;	dest_rect.x = (int)floor(x);	dest_rect.y = (int)floor(y);	SDL_BlitSurface(tiles, &source_rect, screen, &dest_rect);}Uint32 map_rgb_sdl(Uint8 r, Uint8 g, Uint8 b){	return SDL_MapRGB(screen->format, r, g, b);}void fillrect_sdl(SDL_Rect *r, Uint32 color){	SDL_FillRect(screen, r, color);}void flip_sdl(void){	SDL_Flip(screen);}void close_sdl(void){	SDL_FreeSurface(tiles);	SDL_Quit();}int init_sdl(void){	SDL_Surface *tmp = NULL;	video_draw_tile = draw_tile_sdl;	video_map_rgb = map_rgb_sdl;	video_fillrect = fillrect_sdl;	video_flip = flip_sdl;	video_close = close_sdl;	screen = SDL_SetVideoMode(screen_w, screen_h, bpp, flags);	if(!screen)	{		fprintf(stderr, "Failed to open screen!\n");		exit(-1);	}	tmp = SDL_LoadBMP("tiles.bmp");	if(!tmp)	{		fprintf(stderr, "Could not load graphics!\n");		return -1;	}	tiles = SDL_DisplayFormat(tmp);	if(!tiles)	{		fprintf(stderr, "Could not convert graphics!\n");		return -1;	}	SDL_FreeSurface(tmp);	return 0;}/*------------------------------------------------	OpenGL mode------------------------------------------------*/GLint gl_tiles;/* OpenGL "state optimizer" hack from glSDL */static struct{	int	do_blend;	int	do_texture;	GLint	texture;	GLenum	sfactor, dfactor;} glstate;static void gl_reset(void){	glstate.do_blend = -1;	glstate.do_blend = -1;	glstate.texture = -1;	glstate.sfactor = 0xffffffff;	glstate.dfactor = 0xffffffff;}static __inline__ void gl_do_blend(int on){	if(glstate.do_blend == on)		return;	if(on)		glEnable(GL_BLEND);	else		glDisable(GL_BLEND);	glstate.do_blend = on;}static __inline__ void gl_do_texture(int on){	if(glstate.do_texture == on)		return;	if(on)		glEnable(GL_TEXTURE_2D);	else		glDisable(GL_TEXTURE_2D);	glstate.do_texture = on;}static __inline__ void gl_blendfunc(GLenum sfactor, GLenum dfactor){	if((sfactor == glstate.sfactor) && (dfactor == glstate.dfactor))		return;	glBlendFunc(sfactor, dfactor);	glstate.sfactor = sfactor;	glstate.dfactor = dfactor;}static __inline__ void gl_texture(GLuint tx){	if(tx == glstate.texture)		return;	glBindTexture(GL_TEXTURE_2D, tx);	glstate.texture = tx;}void draw_tile_gl(float x, float y, int tile){	float tx1 = (float)(tile % PALETTE_TW) / PALETTE_TW;	float ty1 = (float)(tile / PALETTE_TH) / PALETTE_TH;	float tx2 = tx1 + ((float)TILE_W / PALETTE_W);	float ty2 = ty1 + ((float)TILE_H / PALETTE_H);	float x1 = x;	float y1 = y;	float x2 = x + TILE_W;	float y2 = y + TILE_H;	gl_do_texture(1);	gl_do_blend(0);	gl_texture(gl_tiles);	glBegin(GL_QUADS);	glColor4ub(255, 255, 255, 255);	glTexCoord2f(tx1, ty1);	glVertex2f(x1, y1);	glTexCoord2f(tx2, ty1);	glVertex2f(x2, y1);	glTexCoord2f(tx2, ty2);	glVertex2f(x2, y2);	glTexCoord2f(tx1, ty2);	glVertex2f(x1, y2);	glEnd();}Uint32 map_rgb_gl(Uint8 r, Uint8 g, Uint8 b){	return r<<16 | g<<8 | b;}void fillrect_gl(SDL_Rect *r, Uint32 color){	int dx1, dy1, dx2, dy2;	gl_do_texture(0);	gl_do_blend(0);	if(!r)		r = &screen->clip_rect;	dx1 = r->x;	dy1 = r->y;	dx2 = dx1 + r->w;	dy2 = dy1 + r->h;	glBegin(GL_QUADS);	glColor3ub((color>>16) & 255, (color>>8) & 255, color & 255);	glVertex2i(dx1, dy1);	glVertex2i(dx2, dy1);	glVertex2i(dx2, dy2);	glVertex2i(dx1, dy2);	glEnd();}void flip_gl(void){	SDL_GL_SwapBuffers();}void close_gl(void){	glDeleteTextures(1, &gl_tiles);	SDL_Quit();}int init_gl(void){	SDL_Surface *tmp, *tmp2;	GLint gl_doublebuf;	GLint maxtexsize;	video_draw_tile = draw_tile_gl;	video_map_rgb = map_rgb_gl;	video_fillrect = fillrect_gl;	video_flip = flip_gl;	video_close = close_gl;	flags |= SDL_OPENGL;	gl_doublebuf = flags & SDL_DOUBLEBUF;	if(bpp == 15)	{		SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);		SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);		SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);	}	if(bpp == 16)	{		SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);		SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);		SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);	}	else if(bpp >= 24)	{		SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);		SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);		SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);	}	if(bpp)		SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, bpp);	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, gl_doublebuf);	screen = SDL_SetVideoMode(screen_w, screen_h, bpp, flags);	if(!screen)	{		fprintf(stderr, "Failed to open screen!\n");		return -1;	}	/*	 * Just because my driver f*cks up if there's console	 * output when it's messing with textures... :-(	 */	SDL_Delay(1000);	glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxtexsize);	if(maxtexsize < 256)	{		fprintf(stderr, "Need at least 256x256 textures!\n");		SDL_Quit();		return -1;	}	tmp = SDL_LoadBMP("tiles.bmp");	if(!tmp)	{		fprintf(stderr, "Could not load graphics!\n");		SDL_Quit();		return -1;	}	tmp2 = SDL_CreateRGBSurface(SDL_SWSURFACE, 256, 256, 24,#if SDL_BYTEORDER == SDL_BIG_ENDIAN			0x00ff0000, 0x0000ff00, 0x000000ff, 0);#else			0x000000ff, 0x0000ff00, 0x00ff0000, 0);#endif	if(!tmp2)	{		fprintf(stderr, "Failed to make texture from graphics!\n");		SDL_FreeSurface(tmp);		SDL_Quit();		return -1;	}	SDL_BlitSurface(tmp, NULL, tmp2, NULL);	SDL_FreeSurface(tmp);	glGenTextures(1, &gl_tiles);	glBindTexture(GL_TEXTURE_2D, gl_tiles);	glPixelStorei(GL_UNPACK_ROW_LENGTH, tmp2->pitch /			tmp2->format->BytesPerPixel);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, tmp2->w, tmp2->h, 0, GL_RGB,			GL_UNSIGNED_BYTE, tmp2->pixels);	glFlush();	SDL_FreeSurface(tmp2);	/*	 * Set up OpenGL for 2D rendering.	 */	glDisable(GL_DEPTH_TEST);	glDisable(GL_CULL_FACE);	glViewport(0, 0, screen->w, screen->h);	glMatrixMode(GL_PROJECTION);	glLoadIdentity();	glOrtho(0, vscreen_w, vscreen_h, 0, -1.0, 1.0);	glMatrixMode(GL_MODELVIEW);	glLoadIdentity();	glTranslatef(0.0f, 0.0f, 0.0f);	return 0;}/*------------------------------------------------	Common functions------------------------------------------------*/int	maxx, maxy;float	xpos = 0.0;float	ypos = 0.0;float	sx = 30.0;float	sy = 30.0;void video_bounce(float dt){	int maxx = MAP_W * TILE_W - vscreen_w;	int maxy = MAP_H * TILE_H - vscreen_h;	if(xpos >= maxx)	{		sx = -sx;		xpos = maxx * 2 - xpos;	}	else if(xpos <= 0)	{		sx = -sx;		xpos = -xpos;	}	if(ypos >= maxy)	{		sy = -sy;		ypos = maxy * 2 - ypos;	}	else if(ypos <= 0)	{		sy = -sy;		ypos = -ypos;	}}void video_limit(float dt){	if(xpos >= maxx)		xpos = maxx;	else if(xpos < 0)		xpos = 0;	if(ypos >= maxy)		ypos = maxy;	else if(ypos < 0)		ypos = 0;}void video_render(void){	int map_x, map_y, map_x_loop;	float fine_x, fine_y;	float x, y;	map_x = (int)xpos / TILE_W;	map_y = (int)ypos / TILE_H;	fine_x = (xpos / TILE_W - floor(xpos / TILE_W)) * TILE_W;	fine_y = (ypos / TILE_H - floor(ypos / TILE_H)) * TILE_H;	for (y = -fine_y; y < vscreen_h; y += TILE_H)	{		map_x_loop = map_x;		for (x = -fine_x; x < vscreen_w; x += TILE_W)		{			if((map_y < MAP_H) && (map_x_loop < MAP_W))				video_draw_tile(x, y, map[						map_y * MAP_W + map_x_loop++]);			else				video_draw_tile(x, y, 0);		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -