这是我简单的blitting功能:
static void blit8(unsigned char* dest, unsigned char* src)
{
byte i;
for (i = 0; i < 8; ++i) {
if (*src != 0) {
*dest = *src;
}
++dest;
++src;
}
}
Run Code Online (Sandbox Code Playgroud)
我已经在-O3,blit8并被内联.restrict(gcc)在这里没有效果.也没有以任何不同的方式递增指针,或使用另一个数字作为透明度,或另一种类型i...我甚至尝试传递一个1字节的位掩码并检查而不是解除引用src.增加i16 的限制似乎提供了一个非常小的加速(~4-6%),但我正在使用8字节而不是16字节的块.
我的瓶颈?实际上没有任何线索,我不认为这是缓存行,因为我的错过率很低(?)和64(我的缓存行大小)在改变事物时没有特别的意义.但是我不认为它的内存速度memcpy也是如此(因为速度更快,稍微更多).
cg_annotate这说blit8(没有内联):
Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw file:function
3,747,585,536 62 1 1,252,173,824 2,097,653 0 674,067,968 0 0 ppu.c:blit8.constprop.0
Run Code Online (Sandbox Code Playgroud)
常规 …
我正在尝试在 HTML5 画布上绘制 8 位像素文本。我试过了:
_context['imageSmoothingEnabled'] = false;
_context['mozImageSmoothingEnabled'] = false;
_context['oImageSmoothingEnabled'] = false;
_context['webkitImageSmoothingEnabled'] = false;
_context['msImageSmoothingEnabled'] = false;
Run Code Online (Sandbox Code Playgroud)
以及其他一些与 HTML 和 CSS 字体有关的事情,同时谷歌搜索了一个多小时。这是字体:
@font-face {
font-family: "undertalefont";
src: url("bitops.ttf");
font-style: normal;
-webkit-font-smoothing: none;
}
Run Code Online (Sandbox Code Playgroud)
当在 HTML 中使用它时,它会尝试使用奇怪形式的子像素抗锯齿。它可以按照图像编辑程序中的预期呈现字体。
所以我的问题是,我该如何阻止这个...(缩放到 200% 以查看坏的 AA)
并使其像素完美清晰?
编辑:我正在渲染文本:
_context.fillStyle = "white";
_context.font = "24px 'undertalefont'";
_context.fillText("Font rendering.", 32, 20);
Run Code Online (Sandbox Code Playgroud) 我有一个抽象的语法树,我需要转换为虚拟机的程序集.我不知道如何最好地这样做,所以我开始使用一串字符串模板.我所说的伪代码示例,比如需要编译一个带有一个条件的简单if语句:
std::string compile_if(Node* n) {
std::string str = "";
curLabel = nLabels++;
str += compile_comparison(n->getChild(0));
str += ".true"+curLabel+":";
str += compile_block(n->getChild(1));
str += ".false"+curLabel+":";
return str;
}
Run Code Online (Sandbox Code Playgroud)
其中每个compile_*基于当前/下一个AST节点生成汇编字符串.然后最后一个字符串通过汇编程序运行.这看起来很草率,难以维护,这肯定不是大多数编译器所做的.这是一个坏主意,我应该改变吗?大多数其他编译器如何生成虚拟汇编代码/机器代码?
我正在尝试制作一个Windows内核驱动程序,但每次我尝试使用KMDF模板创建一个新项目或者通过Microsoft打开一个示例驱动程序(如键盘过滤器)时,它都不起作用.
在加载现有驱动程序项目的情况下,它"无法加载".重新加载后,我收到消息框,给出了一条令人难以置信的描述性错误消息:"发生了一个或多个错误."
尝试从模板创建新的驱动程序项目时,我得到了相同的描述性消息框.
如何摆脱此错误消息并加载/创建Windows驱动程序?
由于我目前仅限于VS 2015并且不会很快使用VS 2017,我安装的WDK版本被称为"WDK for Windows 10,版本1703",可以在其他WDK下载中找到.
是说delete pointer和pointer = nullptr一样吗?可能不是,但后者会释放内存吗?怎么样delete pointer; pointer = nullptr/ pointer = nullptr; delete pointer?为什么不使用它来提供一种安全的方法来过早地删除指针,如果需要,通常会在其他时间删除它们并导致正常删除错误?
我使用以下代码初始化 SDL:
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* win = SDL_CreateWindow(
"SDL Window",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
WIDTH,
HEIGHT,
SDL_WINDOW_SHOWN
);
SDL_Renderer* ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_SOFTWARE);
SDL_GL_SetSwapInterval(1); // probably has no effect since it's not using GL
Run Code Online (Sandbox Code Playgroud)
然后我使用非 SDL 软件渲染器进行渲染,并使用以下代码将其呈现给窗口:
SDL_UpdateTexture(screenBuffer, NULL, screenData, WIDTH*4);
SDL_RenderClear(ren);
SDL_RenderCopy(ren, screenBuffer, NULL, NULL);
SDL_RenderPresent(ren);
Run Code Online (Sandbox Code Playgroud)
帧率完全没有上限,我不知道为什么。
添加| SDL_RENDERER_PRESENTVSYNC到 SDL_CreateRenderer 标志只会使窗口成为空白的白屏。虽然我需要使用该SDL_RENDERER_SOFTWARE标志(即使我没有使用 SDL 的软件渲染器来呈现屏幕),否则SDL_RenderPresent()会停顿很长时间,导致每秒大约 1 帧。
我怎样才能SDL_RenderPresent()等待 vsync,或者自己(准确地)等待它?
这是我的游戏循环代码:
while (shouldUpdate)
{
timeSinceLastUpdate = 0;
startTime = clock();
while (timeAccumulator >= timeDelta)
{
listener.handle();
em.update();
timeAccumulator -= timeDelta;
timeSinceLastUpdate += timeDelta;
}
rm.beginRender();
_x->draw();
rm.endRender();
timeAccumulator += clock() - startTime;
}
Run Code Online (Sandbox Code Playgroud)
它几乎完美地运行,但它有一些抖动,每秒几次而不是_x(一个测试实体,它在更新中所做的全部是x ++)向右移动1个像素,它实际上向右移动2个像素这是一个明显的滞后/抖动效应.我猜时钟()不够准确.那么我该怎么做才能改善这个游戏循环呢?
如果重要,我使用SDL和SDL_image.
编辑:做一些比时钟更精确的事情没有任何改变.但是,我已经想到的是,这一切都归功于timeDelta.这就是我发这篇文章时timeDelta的定义方式:
double timeDelta = 1000/60;
Run Code Online (Sandbox Code Playgroud)
但当我把它定义为别的东西时,却一直在搞乱......
double timeDelta = 16.666666;
Run Code Online (Sandbox Code Playgroud)
我注意到比赛开始的前几秒,它像黄油一样光滑.但就在几秒钟之后,游戏结结巴巴,然后又恢复了平稳,并重复了这样.我添加了更多的6(或真正的)之后的任何东西,游戏最初平滑的时间越长,并且它的延迟越大.似乎浮动错误正在攻击.那我该怎么办呢?
编辑2:我已经尝试了很多东西,现在它甚至都不好笑......有人可以帮助我完成循环的数学部分吗?既然这就是造成这种情况的原因......
EDIT3:我给一些人发了一个测试程序,有人说它非常顺利,有些人说它像我描述的那样紧张.对于愿意在这里测试它的人来说,它是(src):https://www.mediafire.com/?vfpy4phkdj97q9j
EDIT4:我改变了源代码的链接.
我用这个代码将4个2位值(无符号字符但它们只保存0-3的值)组合成1个单个无符号字符值
unsigned char nibble = 0;
nibble = (nibble & 0x03) | (output[i] & 0x03);
nibble = (nibble & 0x0C) | (output[i+1] & 0x03) << 2);
nibble = (nibble & 0x30) | (output[i+2] & 0x03) << 4);
nibble = (nibble & 0xC0) | (output[i+3] & 0x03) << 6);
Run Code Online (Sandbox Code Playgroud)
它会为除00 00 00 00之外的所有内容生成不正确的值(它通常会为2个不同的2位值组生成相同的结果).
我很困惑,因为上面的代码是这段代码的编辑,可以很好地将2个4位值组合成1个字节,那么为什么我的版本不能将4个2位值组合成1个字节呢?
char byte;
byte = (byte & 0xF0) | (nibble1 & 0xF); // write low quartet
byte = (byte & 0x0F) | ((nibble2 & 0xF) << …Run Code Online (Sandbox Code Playgroud) 我初始化一个实体指针数组并添加这样的实体......
Entity* ents[16];
Player* player = &Player(20, 24); // subclass of entity
Player* player2 = &Player(30, 30);
ents[0] = player;
ents[1] = player2;
Run Code Online (Sandbox Code Playgroud)
因为我已经知道它,所以我用16的大小来循环它们.
但是我不能对他们做任何事......因为他们中的一些不是"有效的".我无法在实体2-16上运行任何方法,因为我没有设置它们是什么.Visual Studio一直在寻找异常.所以我尝试将一个isValid方法添加到Entity类中,我甚至尝试给它一个公共布尔值并在构造函数中将其设置为true,但最终没有办法检查任何关于这些"无效实体"之一的数据而没有获得例外.因此,在尝试对其进行任何操作之前,我需要先了解一个实体是否有效.但是怎么样?
c++ ×5
c ×2
pointers ×2
arrays ×1
assembly ×1
bit ×1
bit-shift ×1
blit ×1
canvas ×1
driver ×1
fonts ×1
game-loop ×1
heap-memory ×1
html5-canvas ×1
javascript ×1
jitter ×1
kmdf ×1
math ×1
memcpy ×1
memory ×1
null ×1
optimization ×1
performance ×1
sdl-2 ×1
timing ×1
vsync ×1
wdk ×1
windows ×1
windows-10 ×1