Open Source Game Development

攻防世界_reserve新手_game、hello CTF、open_source 1、game 拖进IDA,打开字符串窗口 双击Done!!!the flag is 这行 然后右键list cross reference to,确定 需要大概理解代码的意思,然后用python简化代码,如下: a=[18,64,98,5,2,4,6,3,6,48,49,65,32,12,48,65,31,78,62,32,49,32,1,57,96,3,21,9,4,62,3,5,4,1,2,3,44,65,78,32,16,97,54,16,44,52,32,64,8... 阅读详情

Open Source Game Development

Published On: Wednesday, June 27, 2007 | Last Modified On: Wednesday, June 27, 2007

 

Introduction

A 3D game engine is a complex collection of code. Anyone entering into game development would have to spend at least a year developing a game engine or purchase a pricey game engine to utilize. Of course, another option would be to use an open source engine, but game developers have often shied away from these due to their lack of features and reliability. However, these days there are several open source engines (or low-cost commercial engines) that have a rich set of features and offer stability.

Open source engines, however, do not necessarily have the performance of their more expensive commercial counterparts as they do not always take advantage of the latest features available on the CPU and GPU. The intent of this paper is to go over a few of the most common open source game engines and show how Intel® tools and technologies can bring goodness to open source game development by getting the best possible performance out of these engines.


Game Engine Block Diagram

The block diagram below is of a typical single-player 3D engine, and displays the complexity of modern game engines. It shows the various subsystems and dependence between them. The "tools" portion of the engine (level editors, geometry and animation exporters, scripted event generators, etc.) have been left out for the sake of simplicity.



Figure 1. Block Diagram of a Modern 3D Game Engine
click here for larger image

Open Source Game Engines

There are several open source engines available on the Internet, some of which are listed below. This paper will focus on both the Object-Oriented Graphics rendering 3D engine and the Quake* 3 game engine.

The following is a short list of some of the open source game engines that are available for use:

·                   Object-Oriented Graphics Rendering (www.ogre3d.org*)

·                   Quake 3 (www.idsoftware.com/business/techdownloads/*)

·                   Crystal Space* (www.crystalspace3d.org*)

·                   Irrlicht Engine (http://irrlicht.sourceforge.net*)


The following is a short list of freely available 3D engines that are not open source and may charge a minimal fee for commercial use:

·                   Ca3D Engine (CA3DE) (www.ca3d-engine.de*)

·                   Power Render 3D Engine (www.powerrender.com*)

·                   Torque Game Engine (www.garagegames.com*)


Optimization Activities

Optimizing software for performance need not be a daunting task. There are several techniques that can be implemented to increase the performance of a game engine. While detailed descriptions of all of these items is beyond the scope of this paper, they each have several papers written about them which can be downloaded from http://developer.intel.com. Check the Additional Resources section for links to some of these papers.

Profiling

Profiling is an important step when it comes to optimizing your code. Without profiling, you wouldn’t know what portion of your code to target. A helpful tool for profiling application time and other events is the Intel® VTune™ Performance Analyzer. Among other things, VTune™ can show you the execution breakdown of all the modules on the entire system. By first creating a profile, you won't end up spending time optimizing a section of code that is barely executed and instead target the more heavily executed portion of your code.

SIMD Optimizations

Single Instruction Multiple Data, or SIMD, is essentially operating on multiple pieces of data at once. Intel's implementation of SIMD is called SSE. The set of instructions can operate on integer, single-precision floating-point, and double-precision floating-point data. Since these instructions can operate on more than one piece of data at a time, they can execute certain algorithms much quicker than standard single data instructions.

Threading

As seen in the previous block diagram, 3D game engines are very complex and stress every aspect of the system. When running, they tend to grow in complexity with the amount of compute power thrown at them. Industry trends in performance have moved from pure frequency to multi-core/multi-processor machines. Intel has already shipped millions of processors with Hyper-Threading Technology—the latest iteration is the dual-core processor (two processor cores in one physical package).

To take advantage of multiple cores, games need to be designed for parallelism. For a given problem, domain concurrency usually can be expressed in terms of:

·                   The tasks that need to get done (Task Parallelism)

·                   The data that gets worked on (Data Parallelism)

·                   The flow of data (Pipelined Parallelism)


Task Parallelism (Functional Decomposition)

A game engine is composed of many complex subsystems. Some of these subsystems can be executed in parallel on multiple threads, giving us Task Parallelism. In most games, these subsystems are often very tightly coupled with many interrelated dependencies. Care must be taken to architect the engine to reduce dependencies amongst the various subsystems, thereby reducing the synchronization needed and maximizing the benefit of parallel execution.

Data Parallelism (Data Decomposition)

Parallelism can also be achieved by data decomposition, which is when the same independent operations are applied to different subsections of data in parallel. Compute-intensive loops are ideal candidates for this kind of decomposition like visibility determination, or game physics/simulation solvers. This technique can be applied to different subsystems over time giving a fork join parallelism.

 
Figure 2. Data Flow Parallelism (Producer-Consumer Decomposition)
click here for larger image



Often data dependencies exist between tasks that can't be eliminated. For example, the I/O Subsystem needs to load world data before it can be processed. One way to work around the data dependency is to try and decompose the problem using the "Producer-Consumer" approach. The output of the producer (I/O thread) becomes the input of the consumer (compute thread). The consumer thread has to wait before the producer thread has started generating output. The threads will start executing serially until data is loaded and then assumes parallel execution. This approach is often referred to as Producer-Consumer Decomposition or Pipelined Parallelism.


Figure 3. Threading models to expressing parallelism
click here for larger image



Automatic Parallelization

The simplest way to parallelize loops (data decomposition) is to let the compiler do the analysis and parallelization of the loops for you simply by compiling the source with the Intel® C++ Compiler (version 7.0 or greater) with the Qparallel option. The switch enables the feature, and a few simple guidelines like not modifying the loop counter within the loop, avoiding branching, and not accessing global state from within the loop increases the likelihood that the compiler will identify and parallelize a loop. Use the -Qpar_report3 switch to have the compiler generate a report on which loops are successfully parallelized and the dependencies that prevent parallelization of others. (-Qpar_report[n] will allow varying degrees of reporting.)

Compiler-Directed Parallelism with OpenMP*

Automatic parallelization is limited in its abilities to generate parallel code. The compiler can do a much better job with user input. This is accomplished with OpenMP* pragmas. The original serial code is left intact and a few #pragmas are sprinkled in. For example, to parallelize for loop, all you have to do is add '#pragma omp parallel for' above the for loop. The Intel C++ compiler 7.0 (or greater) and Microsoft Visual Studio* 2005 support OpenMP. The pragmas are ignored by default, so to enable OpenMP-based parallelism, the source must be compiled with the /Qopenmp option.

for ( i=start; i <= end; i++ )

{

// do some compute intensive work here

}

 

// Parallel version

#pragma omp parallel for

for ( i=start; i <= end; i++ )

{

// do some compute intensive work here

}

 

OpenMP automatically runs multiple copies of the loop body in parallel using a pool of threads, each of which works on a different iteration of the loop. In this example, all the variables except the loop iteration variable are shared. Often threads will need private copies of certain variables in order to avoid data races. Identification of these variables is a hard task to do by inspection, but becomes much easier when building the source project with the Intel® C++ Compiler with the /Qtcheck and /Qopenmp options. After this is done, running the application through Intel® Thread Checker will identify the variables and areas with probable data race conditions that may need to be made private.

Threading with Libraries

Thread libraries (e.g. Win32* threads, or pThreads) can be used to drive explicitly defined threads. Thread libraries are flexible enough to address most kinds of parallelism discussed above. They are more invasive and time consuming to use, but provide the programmer with flexibility and direct control. The Intel® Thread Checker can be used with programs threaded with the Win32 or pThread APIs to provide insight into potential problems like data races and deadlocks. Creating threads is expensive; therefore, if using the threading libraries, it is probably worthwhile to generate a pool of threads during initialization, and set events to wake up threads to perform their tasks when necessary. When the threads finish their tasks, they can go back to a resting state, releasing hardware resources for other tasks.

Intel® Thread Profiler can be used to analyze and maximize performance of applications using OpenMP and Win32 threads.


Quake* 3

Profiling

So, where do we begin threading? Profiling, Profiling, Profiling. A good understanding of application behavior is needed before we can decide what type of parallelism is best suited for a particular subsystem.

Sampling the application with the Intel® VTune™ Performance Analyzer will give us a detailed analysis of the amount of CPU time being used by each module and function. This information provides useful insight into doing a functional decomposition, meaning it will help us decide what portions of the engine we would want to run on multiple threads in parallel to maximize performance.

Generating a call graph of the application running a specific workload using the Intel® VTune™ Performance Analyzer will give us a detailed analysis showing the self time (time being spent in a function) and total time (time spent in a function and all the functions called within it) at each node, along with the call hierarchy. This information, along with the sampling data, can provide useful insight into where it's best along the call tree to do a data decomposition.

Sampling Quake* 3 with the Intel VTune Performance Analyzer in timedemo mode and ignoring the demo load time we get the following data:

Thread

Process

Clockticks

Instructions Retired

%Clockticks

thread74

quake3.exe

8,437

8,034

99.98

thread103

quake3.exe

2

1

0.02


This table shows that even though Quake 3 spawns two threads, most of the work (99.98%) is done by a single thread. Delving further into the processes running on that thread, we can see that 51% of the time is being spent in the graphics driver and about 32% of the time is being spent in the engine:

Module

Process

Clocktick samples

%Clockticks

Instructions Retired

CPI

ati2dvag.dll

quake3.exe

4,308

51.06

52.44

1.027

quake3.exe

quake3.exe

2,719

32.23

36.05

0.894

atioglxx.dll

quake3.exe

599

7.1

5.65

1.319

Other32

quake3.exe

352

4.17

2.36

1.853

ntdll.dll

quake3.exe

129

1.53

1.56

1.032

hal.dll

quake3.exe

163

1.93

0.71

2.86

ntoskrnl.exe

quake3.exe

55

0.65

0.19

3.667


Threading

The best place to do a functional decomposition with would be moving the renderer on a separate thread. This will involve moving all the qgl (quake GL) calls over to a single thread as the graphics drivers are not yet thread-safe and will not handle calls from shared contexts on different threads very well. The front-end will prepare a frame and the back-end will render it on a separate thread. Some of the functionality is in place in the Quake 3 source base, but it is not enabled. Managing object lifetimes can also be challenging as the objects cannot be deleted until the back-end is done rendering them. Double-buffering the data needed every frame would be necessary for the front-end to prepare the next frame while the back-end renders the previous frame.


Ogre* 3D

Profiling

For the data gathered below, we generated profiles for four of the demos available for Ogre*. These four demos highlight how applications can use Ogre differently and stress different parts of the engine. The following tables show the four different demo profiles:


Click here for larger view

By looking at these four profiles you can immediately see that they do indeed stress different parts of the engine. OgreOde focuses on the physics simulation which is located in OgreOde_Core.dll; DynTex does some very CPU-intensive calculations and thus most of its time is spent within its own module; Fresnel makes heavy use of the Ogre API; and CelShading causes the video card driver to maximize its processing.

This is why profiling an application is important. It will tell you what application areas to target, and prevents you from spending extra time optimizing a section of code that will barely be used.

Now that you have the profiles and know which items consume the most cycles, it's time to optimize them. The following section will discuss how to use the Intel® Streaming SIMD Extensions instructions to speed up calculations, and the Ogre threading section will point out how to thread some items to get speed benefits on Intel processors with Hyper-Threading Technology or Dual-Core Intel® Xeon® Processors.

SIMD Optimizations

Previously, we took profiles of the four Ogre demos and got vastly different results on which module was spending the most time executing on the CPU. This section describes how to convert the core CPU-intensive areas to SSE and SSE2. Of the four demos, DynTex and Fresnel would benefit the most from SIMD optimizations.

Let's take a look at DynTex. According to VTune™, most time is spent in the runStep function located in the DynTex.cpp file. There are several blocks of code in this function that could be converted to SSE, but we will focus on the code that calculates the chemical reaction beginning at line 170 in the cpp file (shown in the code snippet below).

This block of code can be easily optimized using SSE2. All the data is lined up in an array that can be loaded four-at-a-time using SIMD. The following code snippets show a comparison between the original source, and how you might want to optimize the loop. Please take into account that the SIMD code is assuming properly aligned memory and a loop iteration count that is divisible by four.

// Reaction (Grey-Scott)

idx = reactorExtent+1;

int U,V;

 

for ( y=0; y < reactorExtent-2; y++ )

{

        for( x=0; x < reactorExtent-2; x++ )

        {

               U = chemical[0][idx];

               V = chemical[1][idx];

               int UVV = MULT( MULT( U, V ), V );

               delta[0][idx] += -UVV + MULT( F, (1<<16)-U );

               delta[1][idx] += UVV - MULT( F+k, V );

               idx++;

        }

        idx += 2;

}

 

Scalar C Code

__m128i _mm_mullo_epi32( __m128i a, __m128i b )

{

        __m128i t0;

        __m128i t1;

 

        t0 = _mm_mul_epu32(a,b);

        t1 = _mm_mul_epu32( _mm_shuffle_epi32( a, 0xB1 ),

                                 _mm_shuffle_epi32( b, 0xB1 ) );

 

        t0 = _mm_shuffle_epi32( t0, 0xD8 );

        t1 = _mm_shuffle_epi32( t1, 0xD8 );

 

        return _mm_unpacklo_epi32( t0, t1 );

}

 

#define _MM_MULT( X, Y )       _mm_srai_epi32( _mm_mullo_epi32( X, Y ), 16 )

 

// Reaction (Grey-Scott)

idx = reactorExtent+1;

const __m128i xNeg1 = _mm_set1_epi32( -1 );

const __m128i x1 = _mm_set1_epi32( 1 );

const __m128i x10000 = _mm_set1_epi32( 1 << 16 );

__m128i xU, xV;

__m128i xK = _mm_set1_epi32( k );

__m128i xF = _mm_set1_epi32( F );

 

for ( y=0; y < reactorExtent-2; y++ )

{

        for ( x=0; x < reactorExtent-2; x+=4 )

        {

               __m128i xDelta0 = _mm_load_si128( (__m128i*)&delta[0][idx] );

               __m128i xDelta1 = _mm_load_si128( (__m128i*)&delta[1][idx] );

               xU = _mm_load_si128( (__m128i*)&chemical[0][idx] );

               xV = _mm_load_si128( (__m128i*)&chemical[1][idx] );

               __m128i xUVV = _MM_MULT( _MM_MULT( xU, xV ), xV );

               __m128i xNegUVV = _mm_add_epi32( _mm_xor_si128( xUVV, xNeg1 ), x1 );

               xDelta0 = _mm_add_epi32( xDelta0, _mm_add_epi32( xNegUVV,

                               _MM_MULT( xF, _mm_sub_epi32( x10000, xU ) ) ) );

               xDelta1 = _mm_add_epi32(xDelta1,_mm_sub_epi32( xUVV,

                               _MM_MULT( _mm_add_epi32( xF, xK ), xV ) ) );

               _mm_store_si128( (__m128i*)&delta[0][idx], xDelta0 );

               _mm_store_si128( (__m128i*)&delta[1][idx], xDelta1 );

               idx+=4;

        }

        idx += 4;

}

 

SIMD Intrinsics Code

If you're new to SIMD programming, this code could seem somewhat complex. The SIMD instructions used can perform operations on four integer items at a time, which is why the loop increment x, and the index idx, are incremented in steps of four. The one curious item is why the statement idx+= 2 in the outer for-loop became idx+=4. This is because the algorithm uses the instructions to read in aligned data from memory, causing these loads to be faster. The grids used in these calculations now need to have some buffer space so that the next line of loads will start on a 16-byte aligned boundary. All code that accesses these grids will now have to take into account that there is some buffer space.

Of course, you could always try using the Intel® C++ Compiler instead of writing the SIMD code yourself. For blocks of code like this, the Intel compiler will typically catch it and vectorize it for you with SIMD (assuming you set the appropriate switch in the compiler). It will even cover all the cases of unaligned memory and an uneven (not divisible by four) number of iterations. However, with this code, the compiler will not be able to properly align the memory during allocation, causing most loads to be unaligned, so it would still be best to do this one by hand.

Fresnel is somewhat different in that the code using up most of the CPU time is located in Ogre. Also, it is floating-point intensive, which will benefit from SSE as opposed to DynTex which was integer-intensive (and used SSE2 instructions). This time, however, the CPU-intensive code is located within the OgreMain dll. The function that is consuming the most time is softwareVertexBlend, located in the OgreMesh.cpp file.

A common problem with vectorizing 3D is the order of the data. Consider a vertex in 3D coordinates. Something like this would normally be stored as 3 floats (labeled x, y, z) contiguously in memory. An array of these would be something like: X, Y, Z, X, Y, Z, X, Y, Z. When vectorizing this, it is not possible to evenly load up four coordinates into a SIMD register (which operates on 4 floats at a time). Ogre suffers from the same vectorization problem.

Four possible ways to do SIMD operations on this code are:

·                   Fill a SIMD register to ¾ capacity

·                   Load the SIMD register with a mix of vertex information

·                   Transpose the data into the correct format

·                   Rearrange the data structures to be SIMD-friendly


The first is filling a SIMD register to ¾ capacity. For this you would need to do 2 loads on the data since there is no way to load 3 floats at a time. First load 1 float (e.g. X) and then load the other 2 floats (e.g. Y and Z). This will leave one of the items as empty, essentially wasting one of the slots and getting only ¾ of the potential processing power. The next method operates on 4 items at a time except it is a mixed bag of X, Y, and Z. The following is what this would look like:



As you can see, you will need to operate on four X, Y, Z vectors to do this effectively. It can also pose a challenge depending on what kind of calculations you need to do on the data. The third method loads up four X, Y, Z vectors and then transposes the data so that you get X|X|X|X, Y|Y|Y|Y, and Z|Z|Z|Z in the SIMD registers. Again, you have to have four vectors to work with. The final method is to re-order the data structures so that instead of it being X, Y, Z, it has an array of four values for each coordinate, as such:

struct Vector3D

{

        float x[4];

        float y[4];

        float z[4];

};

 

While this does waste some space at the end for items that aren't a multiple of four vectors, it does speed up SIMD calculations quite significantly.

Threading OGRE3D

We are now going to focus on the other two demos that were profiled in the profiling section, OgreOde and CelShading. By threading the correct locations in OgreMain, a significant speed up can be seen in these two demos (assuming that there is more than 1 microprocessor present in the system). The two demos would require the threading to be done in two different locations. For the OgreOde demo it would be done in the Listener class (either within Ogre or the application) and for the CelShading demo the threading would have to take place in the rendering subsystem.

There are two possible ways to thread the OgreOde demo. Ogre has what is called a Listener class, which a program overrides, that get called by the Ogre engine for certain events, such as pre-render and post-render. To make the threading more general-purpose you would want to thread the area in Ogre where the dispatching of the calls is done. That can be found in the Ogre::Root class in the OgreRoot.cpp file in two functions – Root::_fireFrameStarted and Root::_fireFrameEnded. The other method would be to thread the calls to OgreOde within the demo itself.

There are two possible ways to thread the OgreOde demo. Ogre has what is called a Listener class, which a program overrides, that get called by the Ogre engine for certain events, such as pre-render and post-render. To make the threading more general-purpose you would want to thread the area in Ogre where the dispatching of the calls is done. That can be found in the Ogre::Root class in the OgreRoot.cpp file in two functions – Root::_fireFrameStarted and Root::_fireFrameEnded. The other method would be to thread the calls to OgreOde within the demo itself.

The CelShading demo's performance (in this case) can be improved by threading the rendering. Threading the renderer has its own issues that need to be dealt with beyond that of threading the listener. The renderer can be found in the Ogre::RenderSystem class located in the OgreRenderSystem.h file. Upon examining the file you will notice that there are several pure virtual functions. These functions are implemented by plug-ins for the different 3D graphics APIs. It would be here that you would need to insert another layer that creates a thread and accompanying synchronization for using calls into the plug-in.

If you do decide to place the renderer on its own thread you need to realize that you can no longer make API calls directly into it. All commands will have to be issued through a synchronized access queue from the main code to the graphics API. Something to watch out for is to not delete the graphics resources that the render system is still using. All objects in Ogre have graphics resources associated with them that the graphics card uses for rendering. It is possible (and not uncommon) that all instances of a certain type of object have been deleted and therefore the corresponding graphics resource used to describe it is no longer needed. Since the rendering is happening concurrently, it still might be using that resource and therefore the resource cannot be deleted until after the end of the frame.


Conclusion

For some games, open source engines are a viable alternative to the expensive commercial game engines available on the market. In recent years they have gotten much more stable and provide a rich set of features that should satisfy all but the most demanding of games for the hard-core gamer. While they may be somewhat behind in performance, with the tools and technologies discussed in this paper those concerns should be readily alleviated. Intel® VTune™ will easily target potential areas for optimizations to eliminate time wasted on non-critical sections of code; Intel's SIMD instructions will speed-up execution of certain blocks of code by operating on more than one piece of data at a time; and threading will divide program execution to take advantage of the available processors in a system to quicken execution time.

 

 
ubuntu24.04+vscode编译开源项目LearnOpenGL下的实战游戏项目BreakOut ubuntu24+vscode编译LearnOpenGL实战游戏项目 阅读详情

相关推荐

Opensource Game Studio:开源游戏工作室-开源

开源游戏工作室团队的主要目标是免费创建用于创建计算机游戏的工具集,以及在其帮助下创建游戏。 目前,我们正在开发游戏引擎,在其中我们尝试将最好的东西与我们自己的开发成果相结合,这些东西是我们在世界上找到的开源和免费软件中最好的。 目前,我们正在开发麻将纸牌游戏,这将是通往我们的工具集和全面RPG的漫长道路的第一步。

首款超全开源游戏合集!4000+ Star!

除了经典重制,这里还有大量优秀的原创开源游戏,如古代战争 RTS 0 A.D.、后末日生存 Roguelike Cataclysm: Dark Days Ahead、体素 RPG Veloren 等,展现了开源社区强大的创造力。再不然,就想找点免费的、极客味儿十足的游戏解闷儿?类型全覆盖:动作冒险、RPG、RTS、城市建造、模拟经营、FPS、平台跳跃、回合策略……一位国外大佬整理的开源游戏列表,点进去一看,原来那么多儿时神作都有开源重制版,能在现代电脑上重温,还能自己改代码加关卡!

weixin_48635316的博客 529

LVGL9.2移植至正点原子阿波罗STM32F429开发板

LVGL(Light and Versatile Graphics Library)是一个开源的图形库,旨在为嵌入式系统提供高效、灵活的图形用户界面(GUI)解决方案。它具有小巧的内存占用和高性能的渲染能力,支持多种硬件平台,包括单片机、DSP 和 ARM 处理器等。LVGL 支持丰富的控件(如按钮、标签、图标、滚动条等),并提供强大的主题、样式和动画功能,使得开发者能够轻松设计出美观且响应迅速的界面。

m0_51149752的博客 3173

最常用的开源游戏引擎

http://hereland.com/2009-05-top-opensource-game-engine/ 开源即开放原代码(Open Source),游戏引擎好比赛车的引擎,是用于控制所有游戏功能的主程序,从计算碰撞、物理加速系统和物体的相对位置,到接受玩家的输入,以及按照正确的音量输出声音等等。无论是角色扮演游戏、即时策略游戏、冒险解谜游戏或是动作射击游戏,哪怕是一个只有1

ad33k编程开发 1331

IAR9.20.4安装与注册全攻略:附资源及典型问题解决方案

本文提供IAR9.20.4的详细安装与注册指南,涵盖环境准备、安装步骤、权限设置及注册机使用技巧。针对典型问题如评估版残留、权限不足和杀毒软件拦截等,给出了具体解决方案,帮助用户顺利完成IAR开发环境的搭建与激活。

a2b3c4d5e的博客 296

在CoppeliaSim里实现一个最简单的强化学习

前言 上一篇文章中介绍了CoppeliaSim的一些基本知识和一个简单的用python去控制CoppeliaSim里面四旋翼无人机运动的一个例子。文章链接 :https://blog.youkuaiyun.com/qq_37051669/article/details/115324851 本文将继续介绍如何利用CoppeliaSim的物理环境去实现一个最简单的强化学习。 如何实现强化学习 强化学习(Reinforcementlearning)是机器学习中的一个领域,强调如何基于环境而行动,以取得最大化的预期利.

qq_37051669的博客 3764

【GitHub项目推荐--OpenSpeedy:开源游戏变速器 - 突破帧率限制的流畅游戏体验】

​​OpenSpeedy​​ 是一款开源免费的游戏速度修改工具,专为游戏玩家和开发者设计,能够突破游戏帧率限制,提供更流畅、更丝滑的游戏加速体验。该项目采用Ring3级别的Hook技术,无需内核修改即可实现对游戏时间的精确控制,支持x86和x64架构的进程,兼容多种游戏引擎,是单机游戏优化和开发测试的理想工具。🔗 ​GitHub地址⚡ ​核心价值​:游戏加速 · 帧率解锁 · 开源免费 · 安全无害。

j8267643的博客 1万+

LangChain4j-针对性操作Function-call+系统预设角色

如果我们想要对一些敏感信息进行针对化的操作,不仅仅是接口大模型去进行回复。比如我们现在数据库里面有一些菜品,那么用户提问,店里有多少套餐,那么云端大模型肯定是不知道的,我们希望捕获这些关键字然后进行自己的业务查询或者处理,这个时候就可以使用function-call。

DDDDDouble的博客 454

Open Source Game Clones

Open Source Game ClonesThis site tries to gather open-source reimplementations of great old games in one place. If you think that some information is missing or have any suggestions - feel free to con

OpenHero 开勇 6157

ENVI_基于无人机数据的果树提取与相对健康监测

一、数据处理 1.计算植被指数VDVI或GDVI:Band Math / Spectral Indices 2.制作掩膜:ROI——Threshold——Subset 二、单地块果树提取 1.绘制感兴趣区shp 2.确定果树提取参数:Count Crops 3.输出果树矢量文件:Convert Crops To Shapefile 4.果树相对健康程度分析:Calculate Crop Me...

提供技术服务、资源分享 429690771 1399

大数据领域数据产品的交通运输行业应用

您是否经历过早高峰被堵在桥上,看着导航显示“前方5公里缓行”却无能为力?是否见过货车司机绕远路导致成本飙升?这些“交通痛点”的背后,是传统交通管理依赖经验决策的局限。本文将聚焦“大数据数据产品”这一核心工具,从技术原理到实际应用,全面解析它如何为交通运输行业“开天眼”,解决从城市拥堵到物流效率的一系列难题。本文将按照“问题引入→概念拆解→技术原理→实战案例→应用场景→未来趋势”的逻辑展开,用生活化比喻降低理解门槛,用代码和数学模型提升专业性,最终帮您建立“大数据+交通”的完整认知框架。交通数据。

操作系统内核探秘的博客 237

国外10款开源的Html5小游戏

The great thing about HTML5 games is that they run on all modern browsers that include browsers on smartphones such as iPhone, and Windows Phone. Having a look at Open Source HTML5 games is a good way

Kiven's Program Space 1万+

LCZ数据下载及处理-以重庆市为例(完整Python代码)

LCZ数据下载及处理-以重庆市为例(完整Python代码)

WW、forever的博客 611

如何选择Open Source Games:新手必看的10个游戏推荐

还在为选择开源游戏而烦恼吗?作为游戏爱好者,你可能已经厌倦了商业游戏的重复性和高昂的价格。开源游戏提供了免费、透明且可自定义的体验,但面对如此多的选择,新手往往不知从何开始。🤔 本文将为你推荐10个精选开源游戏,涵盖不同类型,让你轻松入门开源游戏世界! ## 🎮 什么是开源游戏? 开源游戏是完全免费的游戏,其源代码对所有人开放,这意味着你可以查看、修改甚至重新分发游戏。与商业游戏相比,开源

gitblog_00593的博客 474

核磁共振常用的文件格式介绍:NIfTI volume 格式 (*.nii), GIFTI 格式 (*.gii), CIFTI 格式 (*.nii)

NIfTI volume 格式 (*.nii)GIFTI 格式 (*.gii)CIFTI 格式 (*.nii)Scene file文件 (*.scene)规格文件 (*.spec)解剖 (*.annot)一个场景文件包含一个或多个场景;每个场景实际上是保存时 wb_view 内部状态的快照。这包括有关加载哪些文件、如何显示、如何配置选项卡的信息(选择了哪些表面、在每个层中选择了哪些文件、打开了哪些层、哪些视图旋转、调色板设置、平铺选项卡等),以及在它们上面添加了哪些注释(文本、箭头、圆圈等)。

从事脑科学核磁共振方法学研究,在Nature communications等权威期刊发表研究论文,熟练掌握磁共振处理方法和统计学方法,欢迎大家和我交流。 3043

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

探索开源游戏克隆世界:Open Source Game Clones

如果你对游戏开发充满热情,并且喜欢探索那些致敬经典的作品,那么这个项目将会是你的一片乐园。**Open Source Game Clones** 是一个致力于收集并展示开源游戏的平台,这些游戏复刻了众多我们熟知和喜爱的经典之作。 ## 项目介绍 Open Source Game Clones 是一个由社区驱动的项目,它不仅提供了一个网站([https://osgameclones.com](h...

gitblog_00038的博客 690

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

【亲测免费】 麻将游戏项目(majiang-cocos-creator)使用教程

``` majiang-cocos-creator/ ├── assets/ │ ├── animations/ │ ├── materials/ │ ├── prefabs/ │ ├── scenes/ │ ├── scripts/ │ ├── textures/ │ └── ... ├── library/ ├── local/ ├── packages/ ├──

gitblog_00518的博客 924

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Game Programming Open Source

Game Programming Open Source 本文的PDF可以从http://www.pmtsolution.net下载。  更多关于Open Source游戏开发,欢迎访问http://www.openge.org  Open Source游戏开发  第一版 2003年2月 2日  PMT 编辑  本文是“PMT Files”的一部分,收集、整理和汇编了Open Source游戏和游

NETTE DE BLOG 914

game open source

http://forum.vcmi.eu/portal.php http://osgameclones.com/

visualassist4680的专栏 373

Game of Thrones Open Source Project Tutorial

Game of Thrones Open Source Project Tutorial 1. 项目介绍 该项目基于GitHub的Fedeztk所维护的got,灵感源自于广受欢迎的电视剧《权力的游戏》(Game of Thrones),尽管具体功能细节未在提供信息中明确,我们可假设它可能涉及数据处理、API服务或与该主题相关的工具开发。此开源项目旨在为开发者社区提供一个围绕《权力的游戏》的数据分析...

gitblog_00531的博客 508

python game engine_The Best Open Source Game Engine: In Search Of Perfection

The game engine is a core software component of computer and video games and other interactive graphics applications processed in real time. It provides the basic set of demanded technologies, simplif...

weixin_29239661的博客 469

Go Open Source

Go Open Source(wang hailong) Go Apache, go Sourceforge.net, go GNU (if you use linux).go 3D engine list. (if you like 3D Game, VR) start from www.quakesrc.org. Open Source Project 提供

buaawhl的专栏 2528

8 Open Source Android Game Engines

Most Android game developers don’t know what to do, they always admire iPhone developers can play it with the free game engine such as Cocos2d-iPhone, and complain there are no the same one on Andro

michaelpp的专栏 1559

The Best Open Source Game Engine: In Search Of Perfection

https://www.greatsoftline.com/the-best-open-source-game-engine-in-search-of-perfection/ The game engine is a core software component of computer and video games and other interactive graphics ap...

dechen6073的博客 666
上一篇: Game Programming Open Source
下一篇: Multithreaded Game Programming and Hyper-Threading Technology
nette
博客等级 码龄20年 61粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值