SDL_Engine游戏引擎制作 5-Texture 2.x的新宠

SDL2系列教程6-纹理 创建纹理 如上一课所述,纹理是GPU渲染等效于表面。因此,纹理几乎总是使用函数SDL_CreateTextureFromSurface()从曲面创建。这个函数或多或少地做你期望的 - 参数是渲染上下文和从中创建纹理的表面。与其他创建函数一样,它将在失败时返回NULL。 以这种方式创建纹理时,数据将被复制到纹理,允许您释放用于加载图像的表面。 // create window, render... 阅读详情

SDL在2.x后,SDL_Texture成为了主力军,以实现各种绘制操作。简单介绍一些与之相关的函数:

1.SDL_QueryTexture。获取一个纹理(即SDL_Texture)的属性,如纹理的高和宽等。

Texture.h

#ifndef __SDL_Texture_H__
#define __SDL_Texture_H__
#include "SDL.h"
#include "Object.h"
NS_SDL_BEGIN
class Renderer;

class Texture : public Object
{
private:
	SDL_Texture* _texture;
public:
	Texture();
	virtual~Texture();

	static Texture* create(SDL_Texture* pTex);
	bool init(SDL_Texture* pTex);
	//获得贴图的属性
	void queryTexture(Uint32* format,int* access,int* w,int* h);
	//设置追加颜色 srcColor = srcColor*(color/255)	//获得追加颜色
	/*即 如果原来颜色为(255,255,255) 设置为(255,128,255)  结果为(255,128,255)*/
	int setTextureColorMod(Uint8 r,Uint8 g,Uint8 b)const;
	int getTextureColorMod(Uint8* r,Uint8* g,Uint8* b)const;
	//透明度
	int setTextureAlphaMod(Uint8 alpha)const;
	int getTextureAlphaMod(Uint8* alpha)const;
	//设置混合,主要用于SDL_RenderCopy
	/*SDL_BLENDMODE_NONE SDL_BLENDMODE_BLEND SDL_BLEND_ADD SDL_BLEND_ADD*/
	int setTextureBlendMode(SDL_BlendMode blendMode)const;
	int getTextureBlendMode(SDL_BlendMode* blendMode)const;
	//获取SDL_Texture
	SDL_Texture* getSDL_Texture()const;
	//Renderer的友元
	friend class Renderer;
};
NS_SDL_END
#endif

Texture.cpp

#include "Texture.h"
NS_SDL_BEGIN
Texture::Texture()
{
	_texture = NULL;
}

Texture::~Texture()
{
	if(_texture)
		SDL_DestroyTexture(_texture);
}

Texture* Texture::create(SDL_Texture* pTex)
{
	Texture* texture = new Texture();

	if(texture && texture->init(pTex))
		texture->autorelease();
	else
		SDL_SAFE_DELETE(texture);

	return texture;
}

bool Texture::init(SDL_Texture* pTex)
{
	if(pTex != nullptr)
	{
		_texture = pTex;
		return true;
	}
	return false;
}

void Texture::queryTexture(Uint32* format,int* access,int* w,int* h)
{
	if(_texture != nullptr)
		SDL_QueryTexture(_texture,format,access,w,h);
}

int Texture::setTextureColorMod(Uint8 r,Uint8 g,Uint8 b)const
{
	if(_texture)
		return SDL_SetTextureColorMod(_texture,r,g,b);
	else
		return -1;
}
int Texture::getTextureColorMod(Uint8* r,Uint8* g,Uint8* b)const
{
	if(_texture)
		return SDL_GetTextureColorMod(_texture,r,g,b);
	else
		return -1;
}

int Texture::setTextureAlphaMod(Uint8 alpha)const
{
	if(_texture != nullptr)
		return SDL_SetTextureAlphaMod(_texture,alpha);
	else
		return -1;
}

int Texture::getTextureAlphaMod(Uint8* alpha)const
{
	if(_texture)
		return SDL_GetTextureAlphaMod(_texture,alpha);
	else
		return -1;
}

int Texture::setTextureBlendMode(SDL_BlendMode blendMode)const
{
	if(_texture)
		return SDL_SetTextureBlendMode(_texture,blendMode);
	else
		return -1;
}

int Texture::getTextureBlendMode(SDL_BlendMode* blendMode)const
{
	if(_texture)
		return SDL_GetTextureBlendMode(_texture,blendMode);
	else
		return -1;
}

SDL_Texture* Texture::getSDL_Texture()const
{
	return _texture;
}
NS_SDL_END

在SDL中,纹理Texture是和Renderer渲染器紧密相关的(Surface则不是),所以Texture类中仅有一个为create(SDL_Texture*)的函数,其他的纹理生成函数则是在Renderer类之中。

SDL_Color为SDL提供的结构体,顾名思义,表示颜色。在SDL_Engine中,有Color3B和Color4B与之对应。3B 表示3个字节,RGB,即Red Green Blue 红绿蓝三原色。4B则是在3B的基础上,添加了一个alpha透明值。

Color.h

#ifndef __SDL_Color_H__
#define __SDL_Color_H__

#include<string>
#include "SDL.h"
#include "Object.h"

NS_SDL_BEGIN
//---------------------------Color4B------------------------------------
class Color4B : public Object
{
public:
	Uint8 r;
	Uint8 g;
	Uint8 b;
	Uint8 a;
public:
	Color4B(Uint8 r = 0,Uint8 g = 0,Uint8 b = 0,Uint8 a = 255)
		:r(r),g(g),b(b),a(a)
	{
	}
	Color4B(const SDL_Color& color)
	{
		r = color.r;
		g = color.g;
		b = color.b;
		a = color.a;
	}
	/*format 255,255,255,255*/
	Color4B(const std::string& str)
	{
		int rr = 0,gg = 0,bb = 0,aa = 0;
		SDL_sscanf(str.c_str(),"%d,%d,%d,%d",&rr,&gg,&bb,&aa);

		r = rr;
		g = gg;
		b = bb;
		a = aa;
	}

	bool equals(const Color4B& other)const
	{
		if(this == &other)
			return true;

		return r == other.r &&
			g == other.g &&
			b == other.b &&
			a == other.a;
	}
	//重载运算符
	Color4B operator*(Uint8 d)
	{
		return Color4B(r * d,g * d,b * d,a * d);
	}
	Color4B operator+(const Color4B& color)
	{
		return Color4B(r + color.r,g + color.g,b + color.b,a + color.a);
	}
	Color4B operator-(const Color4B& color)
	{
		return Color4B(r - color.r,g - color.g,b - color.b);
	}
	//重载== !=
	bool operator==(const Color4B& other)
	{
		if(this == &other)
			return true;

		return r == other.r &&
			g == other.g &&
			b == other.b &&
			a == other.a;
	}
	bool operator!=(const Color4B& other)
	{
		if(this == &other)
			return false;
		return r != other.r ||
			g != other.g ||
			b != other.b ||
			a != other.a;
	}
	//获取SDL_Color
	SDL_Color getSDL_Color()const
	{
		SDL_Color color = {r,g,b,a};
		return color;
	}
};
//----------------------------------------Color3B-------------------------------
class Color3B:public Object
{
public:
	Uint8 r;
	Uint8 g;
	Uint8 b;
public:
	Color3B(Uint8 r = 0,Uint8 g = 0,Uint8 b = 0)
		:r(r),g(g),b(b)
	{
	}
	Color3B(const SDL_Color& color)
	{
		r = color.r;
		g = color.g;
		b = color.b;
	}
	/*Format 255,255,255*/
	Color3B(const std::string& str)
	{
		int rr = 0,gg = 0,bb = 0;
		SDL_sscanf(str.c_str(),"%d,%d,%d",&rr,&gg,&bb);

		r = rr;
		g = gg;
		b = bb;
	}
	bool equals(const Color3B& other)const
	{
		if(this == &other)
			return true;
		return r == other.r &&
			g == other.g &&
			b == other.b;
	}
	//重载运算符
	Color3B operator*(Uint8 d)
	{
		return Color3B(r * d,g * d,b * d);
	}
	Color3B operator+(const Color3B& color)
	{
		return Color3B(r + color.r,g + color.g,b + color.b);
	}
	Color3B operator-(const Color3B& color)
	{
		return Color3B(r - color.r,g - color.g,b - color.b);
	}
	//重载== !=
	bool operator==(const Color3B& other)
	{
		if(this == &other)
			return true;
		return r == other.r &&
			g == other.g &&
			b == other.b;
	}
	bool operator!=(const Color3B& other)
	{
		if(this == &other)
			return false;
		return r != other.r ||
			g != other.g ||
			b != other.b;
	}
	//获取SDL_Color
	SDL_Color getSDL_Color(Uint8 alpha = 255)const
	{
		SDL_Color color = {r,g,b,alpha};
		return color;
	}
};
NS_SDL_END
#endif

SDL_Renderer在SDL2.x后一个窗口允许有多于一个的渲染器。不过,在SDL_Engine中,渲染器就使用了一个。

介绍一些SDL_Renderer相关的函数:

1.SDL_CreateRenderer。创建一个基于SDL_Window窗口的渲染器。

2.SDL_RenderClear。使用相应的颜色刷新当前的渲染目标。

3.SDL_RenderPresent。呈现到屏幕。

4.SDL_SetRenderDrawColor。设置渲染器刷新颜色。

5.SDL_CreateTexture。创建一个基于渲染器的纹理。

6.SDL_CreateTextureFromSurface。创建一个基于当前渲染器和当前表面来生成一个纹理。

7.SDL_RenderCopy。拷贝一个纹理到当前的渲染目标上。

8.SDL_RenderCopyEx。SDL_RenderCopy的扩展,额外添加了旋转角度angle,旋转中心,以及是否翻转。

9.IMG_LoadTexture。加载文件并生成纹理。

10.SDL_RenderDrawLine。绘制一条线。

11.SDL_RenderDrawRect。绘制一个矩形。

12.SDL_RenderFillRect。填充一个矩形。

13.SDL_RenderSetScale。设置渲染缩放,图片可能会稍微变形。

14.SDL_SetRenderTarget。设置渲染目标,当为nullptr是恢复默认渲染目标。

Renderer.h

#ifndef __Renderer_H__
#define __Renderer_H__

#include "SDL.h"
#include "SDL_image.h"

#include "Object.h"
#include "Rect.h"
#include "Color.h"

NS_SDL_BEGIN
class Window;
class Surface;
class Texture;

class Renderer : public Object
{
private:
	SDL_Renderer* _renderer;
public:
	Renderer();
	~Renderer();

	static Renderer* create(Window* window,int index,Uint32 flags);
	//初始化
	bool init(Window* window,int index,Uint32 flags);
	//清空渲染器
	int renderClear();
	//呈现
	void renderPresent();
	//设置刷新颜色
	void setRenderDrawColor(Uint8 r,Uint8 g,Uint8 b,Uint8 a);
	void setRenderDrawColor(const Color4B& color);
	//获取当前刷新颜色
	Color4B getRenderDrawColor()const;
	//创建Texture
	Texture* createTexture(Uint32 format,int access,int w,int h);
	Texture* createTextureFromSurface(Surface* surface);
	//绘制
	int renderCopy(Texture* texture,const SDL_Rect* srcRect,SDL_Rect* destRect);
	int renderCopyEx(Texture* texture,const SDL_Rect* srcRect,SDL_Rect* destRect,const double angle,const SDL_Point* center,SDL_RendererFlip flip);
	int renderCopyEx(Texture* texture,const Rect& srcRect,const Rect& destRect,const double angle,const Point& center,SDL_RendererFlip flip);
	//创建Texture
	Texture* imgLoadTexture(const char* filePath);
	//创建Texture 线程安全,即不参与内存管理
	Texture* imgLoadTextureThreadSafe(const char* filepath);
	Texture* createTextureFromSurfaceThreadSafe(Surface* surface);
	//一些画图函数
	int renderDrawLine(const Point& startPos,const Point& endPos);
	int renderDrawRect(const Rect& rect);

	int renderFillRect(const Rect& rect);
	//进行与渲染无关的分辨率
	int renderSetScale(float scaleX,float scaleY);
	Size renderGetScale()const;
	//进行逻辑缩放
	int renderSetLogicalSize(int w,int h);
	void renderGetLogicalSize(int& w,int& h);
	//设置填充模式
	int setRenderDrawBlendMode(SDL_BlendMode mode);
	int getRenderDrawBlendMode(SDL_BlendMode* mode);
	//渲染区域
	int renderSetViewport(const SDL_Rect* rect);
	//这里,SDL返回的是void,所以API做了相应改变
	Rect renderGetViewport();
	/*改变渲染目标,为空时则改为默认渲染目标 
	*@ texture 必须有SDL_TEXTUREACCESS_TARGET*/
	int setRenderTarget(Texture* texture);
	/*设置遮挡*/
	int renderSetClipRect(const SDL_Rect* rect);
	Rect renderGetClipRect();
	//返回SDL_Renderer
	::SDL_Renderer* getSDL_Renderer()const;
};
NS_SDL_END
#endif

Renderer.cpp

#include "Renderer.h"
#include "Window.h"
#include "Surface.h"
#include "Texture.h"

NS_SDL_BEGIN
Renderer::Renderer()
	:_renderer(nullptr)
{
}

Renderer::~Renderer()
{
	if(_renderer)
		SDL_DestroyRenderer(_renderer);

	_renderer = nullptr;
}

Renderer*Renderer::create(Window* window,int index,Uint32 flags)
{
	Renderer* renderer = new Renderer();

	if(renderer && renderer->init(window,index,flags))
		renderer->autorelease();
	else
		SDL_SAFE_DELETE(renderer);

	return renderer;
}

bool Renderer::init(Window* window,int index,Uint32 flags)
{
	//以win作为参数创建renderer
	_renderer = SDL_CreateRenderer(window->_window,index,flags);

	return true;
}

int Renderer::renderClear()
{
	return SDL_RenderClear(_renderer);	 
}

void Renderer::renderPresent()
{
	SDL_RenderPresent(_renderer);
}

void Renderer::setRenderDrawColor(Uint8 r,Uint8 g,Uint8 b,Uint8 a)
{
	SDL_SetRenderDrawColor(_renderer,r,g,b,a);
}

void Renderer::setRenderDrawColor(const Color4B&color)
{
	SDL_SetRenderDrawColor(_renderer,color.r,color.g,color.b,color.a);
}

Color4B Renderer::getRenderDrawColor()const
{
	Color4B color;

	SDL_GetRenderDrawColor(_renderer,&color.r,&color.g,&color.b,&color.a);

	return color;
}

Texture* Renderer::createTexture(Uint32 format,int access,int w,int h)
{
	if(_renderer)
		return Texture::create(SDL_CreateTexture(_renderer,format,access,w,h));
	return nullptr;
}

Texture* Renderer::createTextureFromSurface(Surface* surface)
{
	Texture* texture = nullptr;

	if(_renderer != nullptr && surface != nullptr)
	{
		texture = Texture::create(SDL_CreateTextureFromSurface(_renderer,surface->_surface));
	}
	return texture;
}

int Renderer::renderCopy(Texture*texture,const SDL_Rect*srcRect,SDL_Rect*destRect)
{
	return SDL_RenderCopy(_renderer,texture->_texture,srcRect,destRect);
}

int Renderer::renderCopyEx(Texture* texture,const SDL_Rect* srcRect,SDL_Rect* destRect,const double angle,const SDL_Point* center,SDL_RendererFlip flip)
{
	return SDL_RenderCopyEx(_renderer,texture->_texture,srcRect,destRect,angle,center,flip);
}

int Renderer::renderCopyEx(Texture* texture,const Rect& srcRect,const Rect& destRect,const double angle,const Point& center,SDL_RendererFlip flip)
{
	SDL_Rect src = srcRect.getSDL_Rect();
	SDL_Rect dest = destRect.getSDL_Rect();
	SDL_Point c = center.getSDL_Point();

	return SDL_RenderCopyEx(_renderer,texture->_texture,&src,&dest,angle,&c,flip);
}

Texture*Renderer::imgLoadTexture(const char* filePath)
{
	SDL_Texture* tex = IMG_LoadTexture(_renderer,filePath);
	
	return Texture::create(tex);
}

Texture*Renderer::imgLoadTextureThreadSafe(const char* filepath)
{
	SDL_Texture*tex = IMG_LoadTexture(_renderer,filepath);
	Texture*texture = new Texture();

	texture->init(tex);
	return texture;
}

Texture*Renderer::createTextureFromSurfaceThreadSafe(Surface* surface)
{
	Texture* texture = nullptr;

	if(_renderer != nullptr && surface != nullptr)
	{
		SDL_Texture*tex = SDL_CreateTextureFromSurface(_renderer,surface->_surface);
		
		texture = new Texture();
		texture->init(tex);
	}
	return texture;
}

int Renderer::renderDrawLine(const Point& startPos,const Point& endPos)
{
	int x1 = (int)startPos.x;
	int y1 = (int)startPos.y;
	int x2 = (int)endPos.x;
	int y2 = (int)endPos.y;

	return SDL_RenderDrawLine(_renderer,x1,y1,x2,y2);
}

int Renderer::renderDrawRect(const Rect& rect)
{
	SDL_Rect r = rect.getSDL_Rect();

	return SDL_RenderDrawRect(_renderer,&r);
}

int Renderer::renderFillRect(const Rect& rect)
{
	SDL_Rect r = rect.getSDL_Rect();

	return SDL_RenderFillRect(_renderer,&r);
}

int Renderer::renderSetScale(float scaleX,float scaleY)
{
	return SDL_RenderSetScale(_renderer,scaleX,scaleY);
}

int Renderer::renderSetLogicalSize(int w,int h)
{
	return SDL_RenderSetLogicalSize(_renderer,w,h);
}

void Renderer::renderGetLogicalSize(int& w,int& h)
{
	SDL_RenderGetLogicalSize(_renderer,&w,&h);
}

int Renderer::setRenderDrawBlendMode(SDL_BlendMode mode)
{
	return SDL_SetRenderDrawBlendMode(_renderer,mode);
}

int Renderer::getRenderDrawBlendMode(SDL_BlendMode* mode)
{
	return SDL_GetRenderDrawBlendMode(_renderer,mode);
}

int Renderer::renderSetViewport(const SDL_Rect* rect)
{
	return SDL_RenderSetViewport(_renderer,rect);
}

Rect Renderer::renderGetViewport()
{
	SDL_Rect rect;
	
	SDL_RenderGetViewport(_renderer,&rect);

	return Rect(rect);
}

int Renderer::setRenderTarget(Texture* texture)
{
	if(texture != nullptr)
		return SDL_SetRenderTarget(_renderer,texture->_texture);
	else
		return SDL_SetRenderTarget(_renderer,nullptr);
}

int Renderer::renderSetClipRect(const SDL_Rect*rect)
{
	return SDL_RenderSetClipRect(_renderer,rect);
}

Rect Renderer::renderGetClipRect()
{
	SDL_Rect rect;
	SDL_RenderGetClipRect(_renderer,&rect);

	return Rect(rect);
}

SDL_Renderer* Renderer::getSDL_Renderer()const
{
	return _renderer;
}
NS_SDL_END

Renderer的主要功能包括:

1.绘制。包括绘制图片和绘制一些线段,矩形等。

2.生成纹理。创建基于本渲染器的纹理。

3.更改渲染目标。

4.设置缩放,即使用SDL_RenderSetScale函数,它能简单地实现不同分辨率主要是手机或平板的适配(图片可能稍微有点变形)。

然后i就是main.cpp要进行稍微的改变。

#include <iostream>
#include "SDL_Engine.h"
#include "SDL.h"
#include "vld.h"

USING_NS_SDL;
using namespace std;
//初始化
void initlize(Renderer* renderer);
void clear();
//绘制
void draw(Renderer* renderer);
//更新
void update(float dt);
//事件处理
void handleEvents();

bool g_bRunning = true;
Texture* g_pTexture = nullptr;

int main(int argc,char** argv)
{
	float secondsPerFrame = 1.f/60.f;
	float time = 0.f;
	Uint32 nextTick = 0u;
	Uint32 lastTick = 0u;
	int currentFrame = 0;
	//初始化全部子系统
	SDL_Init(SDL_INIT_EVERYTHING);
	IMG_Init(IMG_INIT_PNG);
	//创建窗口
	Window* window = Window::create("SDL_EngineTest",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,800,480,SDL_WINDOW_SHOWN);
	window->retain();
	//创建渲染器
	Renderer* renderer = Renderer::create(window,-1,SDL_RENDERER_PRESENTVSYNC);
	renderer->retain();

	initlize(renderer);
	//游戏循环
	while (g_bRunning)
	{
		Uint32 currentTick = SDL_GetTicks();
		if(currentTick >= nextTick)
		{
			//帧率固定为方便调试
			float dt = secondsPerFrame;
			time += (currentTick - lastTick) / 1000.f;

			lastTick = currentTick;
			nextTick = lastTick + (Uint32)(secondsPerFrame * 1000);
			//显示当前帧数
			if (time >= 1.f)
			{
				time -= 1.f;
				printf("%d\n",currentFrame);
				currentFrame = 0;
			}
			else
				currentFrame++;

			update(dt);
			
			renderer->renderClear();
			draw(renderer);
			renderer->renderPresent();
		}
		handleEvents();

		PoolManager::getInstance()->getCurReleasePool()->clear();
	}
	renderer->release();
	window->release();
	//清除
	clear();

	PoolManager::purge();

	IMG_Quit();
	SDL_Quit();
	_CrtDumpMemoryLeaks();
	return 0;
}

void initlize(Renderer* renderer)
{
	g_pTexture = renderer->imgLoadTexture("crop7_5.png");
	g_pTexture->retain();
	//设置刷新颜色
	renderer->setRenderDrawColor(Color4B(0,255,255,255));
}

void clear()
{
	g_pTexture->release();
}

void draw(Renderer* renderer)
{
	SDL_Rect destRect = {100,100,94,48};
	renderer->renderCopy(g_pTexture,nullptr,&destRect);
}

void update(float dt)
{
}

void handleEvents()
{
	SDL_Event event = {};
	//对事件进行轮询
	while(SDL_PollEvent(&event))
	{
		switch(event.type)
		{
		case SDL_QUIT: g_bRunning = false; break;
		}
	}
}
可以看到,目前的绘制使用的是Texture和Renderer。其运行结果和上一节相同。

虽然本节结果和上一节的相同,但是使用渲染器和纹理进行绘制是很有必要的,其中最主要的一个原因就是渲染器的绘制效率是远远高于Surface的。

本节代码:链接:https://pan.baidu.com/s/1C0mbP1_jG1fAmdrnRuyXqA 密码:lc66

OpenBOR游戏引擎跨平台移植:从Windows到Android的完整实战指南 跨平台开发是现代游戏工程中的重要实践,其核心在于通过抽象层技术实现同一套代码逻辑在不同操作系统和硬件架构上的运行。其原理通常基于C/C++这类高性能语言编写核心引擎,并利用平台抽象库(如SDL2)处理底层系统交互,从而实现“一次编写,多处部署”。这种技术方案的价值在于极大提升了代码复用率,降低了多平台维护成本,尤其对于独立开发者和复古游戏项目意义重大。在应用场景上,它广泛应用于将PC端的自制或经典游戏引擎(例如专注于2D清版动作游戏的OpenBOR引擎)迁移到移动设备。本文将以OpenBOR引擎为例,详细解 阅读详情

相关推荐

AI绘画与C++游戏开发整合:FLUX模型生成角色资源的全流程实战

在游戏开发中,角色美术资源的生产往往面临成本高、周期长的挑战。随着生成式AI技术的成熟,AI绘画模型为游戏美术创作提供了新的解决方案。其核心原理是通过深度学习模型,根据文本提示词生成高质量图像,这极大地降低了美术内容的创作门槛。从技术价值看,AI生成不仅能快速产出大量素材,还能通过提示词工程保持风格统一,为独立开发者和小团队带来生产力革新。在应用场景上,AI生成的2D角色立绘可直接用于2D游戏,也可作为3D建模的参考和贴图素材。本文以“FLUX小红书极致真实V2”这一在细节表现和风格化上具有优势的模型为例,

weixin_34099526的博客 349

[笔记]音视频学习之SDL篇《五》裁剪图片成子图片(裁剪精灵表)

第五节:裁剪精灵表 文章目录目的 目的 裁剪一个图片中的多个子图片作为图片使用

二次元怪兽的博客 691

2023年从零构建游戏引擎:核心模块、ECS架构与实战代码解析

游戏引擎作为现代游戏开发的核心框架,其本质是一个集成渲染、物理、资源管理等模块的复杂软件系统。理解引擎的底层原理,不仅能帮助开发者突破现成引擎的性能瓶颈,更是掌握计算机图形学、数据结构和软件架构的深度实践。通过剖析实体组件系统(ECS)等现代架构,开发者可以构建高度定制化的专用引擎,解决超大规模策略游戏或特定风格项目的独特需求。本文以C++和OpenGL为例,从窗口创建、渲染管线到资源管理,提供可落地的代码示例和架构思路,为开发者拆解构建教学引擎或专用引擎的核心路径。

weixin_34341229的博客 470

SDL学习二(显示png图片)

// SDLSample.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include "SDL_image.h"#include "SDL.h"#include &lt;stdexcept&gt;#include &lt;string&gt;#include &lt;iostream&gt;#include "SDL.h"#include &

u011269801的专栏 2741

创建Texture(纹理)

一、填充D3D11_TEXTURE2D_DESC D3D11_TEXTURE2D_DESC desc; desc.Width = 1920; desc.Height = 1080; desc.MipLevels = desc.ArraySize = 1; desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; desc.SampleDesc.Count = 1; desc.Usage = D3D11_USAGE_DYNAMIC;

qq_15821883的博客 4072

SDL2显示图片

sdl显示图片 #include <SDL2/SDL.h> #include <SDL2/SDL_image.h> #include <iostream> using namespace std; int main(int argc, char**argv){ if( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) !...

u010745620的博客 1112

SDL_Engine游戏引擎制作 0-目录

本系列文章旨在介绍并开发一个基于SDL(Simple DirectMedia Layer)的模仿Cococs2d-x的一个游戏引擎。目前我已经使用这个开发了好几个游戏,从飞机大战,到捕鱼达人,再到植物大战僵尸。都能使用SDL_Engine进行开发,而不用修改SDL_Engine的内部代码。(本系列暂停更新,对矩阵什么的不了解。。。待更新)我个人做的一些游戏图片:植物大战僵尸超级玛丽捕鱼达人目录(不...

bull521的博客 4932

C++面向对象封装SDL游戏开发实战:从框架设计到性能优化

游戏开发的核心在于高效管理复杂交互与实时渲染,这离不开扎实的编程范式与底层库的支持。面向对象编程(OOP)通过封装、继承与多态,将游戏实体抽象为类,构建出清晰、可维护的代码结构,是应对复杂软件系统的经典方法论。其技术价值在于提升代码复用性、模块化程度与团队协作效率,广泛应用于引擎开发、工具链构建及高性能应用场景。而SDL(Simple DirectMedia Layer)作为一个轻量级、跨平台的多媒体库,封装了窗口管理、图形渲染、输入处理等底层细节,让开发者能聚焦游戏逻辑本身。结合C++的高性能与控制力,这

weixin_34413802的博客 382

C++与SDL实现双人塔防游戏:网络同步与ECS架构实战

游戏开发的核心在于对底层架构和实时交互的深刻理解。从基础的游戏循环与时间管理原理出发,通过固定时间步长和渲染插值技术确保逻辑的确定性与画面的流畅性,这是构建稳定游戏体验的基石。其技术价值在于能够锤炼开发者对性能优化、内存管理和多模块协同的工程能力。在应用场景上,这类技术尤其适合需要精细控制和高性能的实时策略、塔防等游戏类型。本文以“村庄保卫战”项目为例,深入探讨了如何运用C++与SDL库,结合实体组件系统(ECS)雏形和帧同步网络模型,实现一个支持双人对战的塔防游戏,涵盖了从权威服务器架构到客户端预测与状态

weixin_33800463的博客 353

从零构建游戏引擎:核心架构、C++实践与OpenGL渲染指南

游戏引擎作为游戏开发的核心框架,其本质是一套集成渲染、物理、音频、资源管理等子系统的软件架构。其核心原理在于通过模块化设计,将通用功能抽象为可复用的组件,从而提升开发效率与性能。在技术价值上,自研引擎不仅能提供极致的定制化控制与性能优化,更是深入理解计算机图形学、内存管理与多线程编程的绝佳实践。从应用场景看,无论是追求特定艺术风格的独立游戏,还是对性能有严苛要求的商业项目,掌握引擎底层技术都至关重要。本文聚焦于使用C++和OpenGL,从窗口管理、渲染管线到实体组件系统(ECS),手把手教你构建一个可运行的

weixin_33834910的博客 389

从零构建C语言Web游戏引擎:ECS架构与WebAssembly跨平台实践

游戏引擎是驱动现代电子游戏的核心软件框架,其核心原理在于高效地管理游戏对象、处理资源并驱动渲染循环。在追求极致性能与可控性的场景下,开发者常选择C语言这类贴近硬件的系统级语言,以实现对内存、计算资源的精细掌控。其技术价值在于能够构建轻量、高性能且可深度定制的引擎核心。随着Web技术的演进,WebAssembly(Wasm)作为一种可在浏览器中高效运行的二进制指令格式,为高性能计算密集型应用打开了新的大门。这使得将使用C/C++等语言编写的、依赖特定架构模式(如实体-组件-系统)的复杂游戏逻辑,无需重写即可部

weixin_34126557的博客 412

C++/C#游戏引擎与图形库实战:从架构选型到性能调优

游戏引擎是现代游戏开发的核心框架,它整合了图形渲染、物理模拟、音频处理等模块,为开发者提供高效的内容创作环境。其工作原理基于实体组件系统(ECS)等架构模式,通过数据与逻辑分离提升性能。在技术价值上,引擎不仅加速了开发流程,还通过底层图形API(如DirectX、Vulkan)的优化调用,实现了跨平台的高性能渲染。应用场景广泛,从3A大作到独立游戏,都依赖引擎处理复杂的实时图形计算与资源调度。本文聚焦于C++和C#在引擎开发中的实战协作,探讨了在Unity和Unreal Engine等商业引擎中,如何通过P

aaa1231722的博客 430

C++游戏开发实战:从零构建高性能游戏引擎核心架构

在实时交互应用领域,性能是核心诉求。C++以其对硬件底层的直接控制能力和零成本抽象理念,成为构建高性能系统的首选语言。通过精细的内存管理、高效的编译优化以及对多线程的深度支持,C++能够实现极致的运行时效率,这对于帧率稳定、资源密集型的应用场景至关重要。其技术价值在于,开发者不仅能实现复杂功能,更能深入理解计算机系统原理,从而精准优化性能瓶颈。在游戏开发、高频交易、仿真模拟等对延迟和吞吐量有严苛要求的场景中,这种掌控力无可替代。本文以游戏引擎开发为切入点,系统阐述了如何运用C++的底层控制力与**实体组件系

weixin_30263277的博客 384

C++与SDL2开发2D游戏:从uMario项目学习游戏引擎底层原理

游戏开发的核心在于理解其底层运行机制,而游戏循环、碰撞检测和状态机是构建任何交互式应用的基石。游戏循环通过处理输入、更新状态和渲染输出的循环驱动体验,其关键在于引入Delta Time进行时间管理,确保在不同硬件上运行速度一致。碰撞检测则多采用高效的轴对齐包围盒算法,并结合方向判断实现精确的物理反馈。这些技术共同支撑起游戏的实时性与交互性,其价值在于为开发者提供了对性能与逻辑的完全掌控力。在2D平台跳跃类游戏等应用场景中,这些原理尤为重要。以uMario这样的开源项目为例,它使用C++和SDL2库,摒弃了成

benben 444

使用C++与SDL2从零构建2D太空射击游戏:实战开发指南

游戏开发的核心在于理解实时交互程序的运行原理,其基础是游戏循环(Game Loop)这一经典架构,它通过持续处理输入、更新状态和渲染输出来驱动每一帧。在底层实现上,这涉及到对计算机图形、音频和事件系统的直接控制。SDL2(Simple DirectMedia Layer)作为一个轻量级、跨平台的多媒体库,为开发者提供了访问这些底层硬件接口的能力,同时避免了直接操作复杂系统API的繁琐,是实现从零开始构建游戏项目的理想技术选型。通过原生C++结合SDL2进行开发,开发者能够深入运用面向对象编程、内存管理和多态

搜索 455

SDL2.0的加载图片贴图

阅读目录 加载图片贴图,采用了SDL_Window、SDL_Renderer、SDL_TextureSDL_Image库 实例: 1 #include <stdio.h> 2 #include <math.h> 3 #include <string.h> 4 #include <SDL2\SDL.h> ...

weixin_30437847的博客 164

现代C++游戏引擎实战:ECS架构与Roguelike RPG系统设计

在游戏开发领域,ECS(实体-组件-系统)架构作为一种现代游戏架构范式,通过将数据(组件)、逻辑(系统)和标识(实体)分离,实现了高度的灵活性和性能优化。其核心原理在于组合优于继承,允许开发者动态地为游戏实体装配功能,这尤其适合需要大量可变实体类型的游戏,如融合了RPG成长与随机地牢的Roguelike游戏。这种架构的技术价值在于提升了代码的可维护性、可扩展性,并通过数据局部性设计优化了CPU缓存利用率,从而支撑复杂的实时计算。其应用场景广泛,从2D独立游戏到大型3D游戏的核心子系统均有涉及。本文以“Pro

weixin_34203832的博客 376

littlewolf地图系统详解:构建复古风格3D迷宫世界的终极指南

littlewolf是一个极简主义的软件图形引擎,灵感来源于早期id Software的经典作品,它通过巧妙的地图系统构建了一个令人惊叹的复古风格3D迷宫世界。这个微型游戏引擎虽然代码量极小,却实现了完整的3D渲染、碰撞检测和地图导航功能,为初学者和游戏开发者提供了一个绝佳的学习案例。😊 ## 🎮 littlewolf地图系统的核心架构 littlewolf的地图系统采用了三层结构设计,分

gitblog_01088的博客 814
上一篇: SDL_Engine游戏引擎制作 4-Surface 1.x的遗孀
下一篇: SDL_Engine游戏引擎制作 6-Director 负责全局的导演
小牛_牛sky
博客等级 码龄12年 221粉丝 130原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值