[VKSpec翻译]第二章 基础

2. 基础

本章将会介绍关于Vulkan的一些基础概念,比如架构、执行模型、API命名、队列、管线配置、数字的标识、状态和状态查询、以及不同种类的对象和着色器。本章中只是系统的介绍,但是它是我们理解后文中对命令和行为更具地的描述的基础。

2.1. 主机和设备环境

Vulkan规范假定并要求主机环境属性需满足:

  • 主机必须支持 8, 16, 32 和 64 位的有、无符号的二进制补码证书,并且在其大小的粒度(字节)下可寻址。
  • 主机必须支持 32 和 64 位的浮点型, 其精度和范围要求在
    Floating Point Computation 节中介绍。
  • 上述类型在主机上的表示以及字节顺序必须与所有物理设备所支持的一样。
注意
由于Vulkan中的很多的类型和结构都可能需要同时支持主机和物理设备的操作和访问,因此为了编写可移植的和可执行的应用程序,其实现应当能够在两者中都较为高效地访问数据。

2.2. 执行模型

本节将概括的介绍Vulkan的执行模型。

我们可以使用Vulkan创建一个或多个设备(devices),每一个设备又可以用来创建一个或多个队列(queues),这些队列可能相互异步执行。设备所支持的不同队列被划分到多个家族(families)当中。而每个家族可能支持一个或多个功能,同时也可能包含多个具有相似特征的队列。在相同的家族中的队列相互是兼容(compatible)的,提交给某个家族队列的工作可以被在这个家族中的任何队列所调用。在本规范中,我们定义一个队列可能支持这四种功能:渲染,计算,转移和稀疏内存管理①。

(译者注:①中的四种功能原文中为graphics, compute, transfer 和 sparse memory management,译者并没有对Vulkan有深入的了解所以只能直译,如果有误还请多多指教)

注意
一个单独的设备可能会反馈多个相似的队列家族,同时也可能会反馈这些家族的多个成员。我们需要注意,尽管相似家族可能具有相似的功能,但他们却并不是相互直接兼容的。

设备的内存是由应用程序明确的管理的,每个设备可能使用一个或者多个堆来表示不同的内存区域。内存堆存在于设备本地和主机本地二者之一,但是总是对设备可见的,我们可以通过内存堆的类型来获得与其相关的更多细节。在实现中可能有以下几种例子:

  • 设备本地(device local)是与设备物理连接的内存。
  • 设备本地,主机可见(device local, host visible)是对主机可见的设备本地内存。
  • 主机本地,主机可见(host local, host visible)是存在于主机上,并且对设备和主机都可见的内存。

在其他架构中,可能只能使用一个堆来实现一切。

Vulkan应用通过向命令缓冲区提交命令来控制设备,这些缓冲区记录了通过Vulkan库调用发布的命令。命令缓冲区的内部是特定的底层实现,对应用程序并不透明。当其创建完成,它就可以提交到队列中一次或多次去执行,多个命令缓冲区可以在多个线程中并行构建。

提交到不同队列的命令缓冲区可能相互并行执行,甚至可以不按照顺序执行。提交到相同队列的命令缓冲区按照submission order来执行,更多介绍详synchronization chapter。在设备中执行的命令缓冲区对主机来说是同步的,一旦向队列提交完命令缓冲区,控制权就可能会立即返回给应用程序。设备和主机之间的同步,以及不同队列之间的同步需要由应用程序来管理。

Minecraft Mod中的第一个物品

上文中,我们把Mod开发环境架设好了,然后今天继续翻官方Doc,官方说:

游戏分为客户端和服务端,两端的代码可能不一样需要分开写,建议创建一个接口 IProxy 并在 Client 和 Server 下采用不同的实现

好的,按照官方的建议,我创建了一个IProxy接口:

[IProxy.java]

import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;

public interface IProxy
{
    void preInit(FMLPreInitializationEvent event);
    void init(FMLInitializationEvent event);
    void postInit(FMLPostInitializationEvent event);
}

好的,然后创建两个类,ClientProxy 和 ServerProxy ,分别实现该接口。现在我们已经按照官方的建议创建了代理,然后呢?当然就是在我们最开始创建的第一个类中,根据不同端把初始化事件转发到不同的代理当中。在FML中为我们提供了自动的代理选择注解:

@SidedProxy(clientSide = "com.boom.shaka.laka.ClientProxy", 
            serverSide = "com.boom.shaka.laka.ServerProxy")
public static IProxy proxy;

好了,有了代理,把初始化事件转发过去就好了。

好的,进入今天的正题,为了创建第一个Item做了那么多没用的工作(想一想还是有用的,不这样到时候写Mod会被服务端和客户端的差异烦死)

根据官方的Doc,注册Item需要用到下面的代码:

@SubscribeEvent
public void registerBlocks(RegistryEvent.Register<Item> event) 
{
    event.getRegistry().registerAll(item1, item2, ...);
}

然后看到这里使用到了Item这个类型,再次查阅文档,再加上自己的尝试,写出了一个测试Item:

[TestItem.java]

import net.minecraft.item.Item;

public class TestItem extends Item
{
    public TestItem()
    {
        super();
        this.
            setRegistryName("Test").
            setUnlocalizedName("testItem");
    }
}

这里呢,有一点需要注意setRegistryName(string)是必须的操作,不然注册的时候会报错。

到这里,我们所需要的一切都有了,然而运行时我却没有发现那激动人心的新Item,再次查阅资料,发现所有事件处理器(Event Handler)都是需要注册到主 EventBus 上边的,具体注册代码如下:

MinecraftForge.EVENT_BUS.register(yourEventHandler);

好了,这回运行时果然看到了我的新Item~

*★,°*:.☆( ̄▽ ̄)/$:*.°★* 。

文章最后附上本次的Java源码: MyFirstMCItem.zip (下载48)

架设Minecraft mod开发环境

说了好几次要去学MC Mod开发,但是最后都咕咕咕了(好吧这次也没准会咕),今天在我内心对未知的强烈渴望的驱动之下,打开了IDEA,开工~

好吧,作为一个从未开发过Java项目,或者说,连gradle都没听说过的一只小白来说,刚下载好MDK后,我蒙了,还好官方有详细的文档,我们来看下边这段:

  1. Obtain a source distribution from forge’s files site. (Look for the Mdk file type, or Src in older 1.8/1.7 versions).
  2. Extract the downloaded source distribution to an empty directory. You should see a bunch of files, and an example mod is placed in src/main/java for you to look at. Only a few of these files are strictly necessary for mod development, and you may reuse these files for all your projects These files are:
    • build.gradle
    • gradlew.bat
    • gradlew
    •  the gradle folder
  3. Move the files listed above to a new folder, this will be your mod project folder.
  4. Open up a command prompt in the folder you created in step (3), then run gradlew setupDecompWorkspace. This will download a bunch of artifacts from the internet needed to decompile and build Minecraft and forge. This might take some time, as it will download stuff and then decompile Minecraft. Note that, in general, these things will only need to be downloaded and decompiled once, unless you delete the gradle artifact cache.
  5. Choose your IDE: Forge explicitly supports developing with Eclipse or IntelliJ environments, but any environment, from Netbeans to vi/emacs, can be made to work.
    • For Eclipse, you should run gradlew eclipse – this will download some more artifacts for building eclipse projects and then place the eclipse project artifacts in your current directory.
    • For IntelliJ, simply import the build.gradle file.
  6. Load your project into your IDE.
    • For Eclipse, create a workspace anywhere (though the easiest location is one level above your project folder). Then simply import your project folder as a project, everything will be done automatically.
    • For IntelliJ, you only need to create run configs. You can run gradlew genIntellijRuns to do this.

全英文!!!没事我看。。。看得懂的。大体上就是下载好MDK并解压,然后移动下面四个文件

  • build.gradle
  • gradlew.bat
  • gradlew
  •  the gradle folder

到一个新的文件夹中组建你的新项目,然后跑命令行初始化,然后选IDE,然后。。。。

等待,实际上没有那么的复杂。我使用了IDEA,于是从步骤四开始是这样的:

  1. Launch IDEA and choose to open/import the build.gradle file, using the default gradle wrapper choice. While you wait for this process to finish, you can open the gradle panel, which will get filled with the gradle tasks once importing is completed.
  2. Run the setupDecompWorkspace task (inside the forgegradle task group). It will take a few minutes, and use quite a bit of RAM. If it fails, you can add -Xmx3G to the Gradle VM options in IDEA’s gradle settings window, or edit your global gradle properties.
  3. Once the setup task is done, you will want to run the genIntellijRuns task, which will configure the project’s run/debug targets.
  4. After it’s done, you should click the blue refresh icon on the gradle panel (there’s another refresh icon on the main toolbar, but that’s not it). This will re-synchronize the IDEA project with the Gradle data, making sure that all the dependencies and settings are up to date.

打开IDEA,打开你新创建的文件夹中的build.gradle,然后运行几个task(在gradle选项卡中)

  1. setupDecompWorkspace负责初始化与MC反编译相关的资源,这里可能会比较慢(可以考虑梯子)
  2. genIntellijRuns因为使用了IDEA,所以显然(划掉)需要执行这一任务

一切都结束了之后,我们把src文件夹也复制过去,里边有一个示例Mod,然后跑runClient就好了~

注:关于调试,只要环境搭好了,直接就可以调试的(逃

重启网站计划

高三结束了,又有时间做网站了,再加上腾讯云超值的学生价(120元一年喂喂!),给予了我继续做网站的决心~嗯,这次不会再弃坑了

#include "iostream"

using namespace std;

int main()
{
    cout<<"Hello World"<<endl;
}