我的代码中有一个循环函数调用PeekMessage以检索事件.
目前它看起来像这样:
while (PeekMessage(&Message, NULL, 0, 0, PM_REMOVE))
{
// Process events
}
Run Code Online (Sandbox Code Playgroud)
现在我想在不同的位置来管理输入,这意味着我想检索信息,如WM_KEYDOWN,WM_MOUSEMOVE在不同的地方(鼠标和键盘事件),我的主回路的不同的时间.
PeekMessage的第三和第四个参数允许定义一个范围消息以返回的,所以我可以利用这一点,使用所提供的宏WM_KEYFIRST,WM_KEYLAST,WM_MOUSEFIRST和WM_MOUSELAST.但它不方便,因为我有两个范围来检查输入,因此剩下的所有内容都有三个范围.
最后一个参数是一个标志,我可以传递PM_REMOVE | PM_QS_INPUT输入.但是,我应该在另一个循环中传递什么,我想要获取所有其他消息?没有PM_QS_EVERYTHING_EXCEPT_INPUT宏......
这样做最优雅的方式是什么?
我正在使用全向点光源.我已经使用立方体贴图纹理实现阴影贴图作为6个帧缓冲区的颜色附加,并在其每个像素中编码光到片段的距离.
现在我希望,如果可以的话,以这种方式改变我的实现:
将立方体贴图中的深度值转换回距离时出现问题.我使用光到片段向量(在世界空间中)来获取立方体贴图中的深度值.此时,我不知道正在使用六个面中的哪一个,也不知道2D纹理坐标与我正在读取的深度值相匹配.那么如何将该深度值转换为距离?
以下是我的代码片段来说明:
深度纹理:
glGenTextures(1, &TextureHandle);
glBindTexture(GL_TEXTURE_CUBE_MAP, TextureHandle);
for (int i = 0; i < 6; ++i)
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT,
Width, Height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Run Code Online (Sandbox Code Playgroud)
帧缓冲结构:
for (int i = 0; i < 6; ++i)
{
glGenFramebuffers(1, &FBO->FrameBufferID);
glBindFramebuffer(GL_FRAMEBUFFER, FBO->FrameBufferID);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, TextureHandle, 0);
glDrawBuffer(GL_NONE);
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试编写片段着色器来实现我的代码:
float ComputeShadowFactor(samplerCubeShadow ShadowCubeMap, vec3 VertToLightWS)
{
float ShadowVec = texture(ShadowCubeMap, vec4(VertToLightWS, …Run Code Online (Sandbox Code Playgroud) Visual Studio 2015 引入了两个新警告 C4473 和 C4477,它们会在字符串格式化函数的格式字符串与关联的变量参数之间不匹配时发出通知:
warning C4473: 'printf' : not enough arguments passed for format string
warning C4477: 'printf' : format string '%p' requires an argument of type 'void *', but variadic argument 1 has type 'int'
Run Code Online (Sandbox Code Playgroud)
这些警告非常有帮助,并且已经被其他流行的编译器支持了一段时间(gcc 和 clang,-wformat我相信有选项,尽管我对这些编译器不太熟悉)。
现在我的问题是我想使用自定义Log(format, ...)函数来处理日志记录,这将执行额外的工作(例如,写入文件和控制台,或添加时间戳)。
但为了这个问题,我们假设我只是简单地调用printf:
void Log(const char * format, ...)
{
va_list args;
va_start(args, format);
printf(format, args);
va_end(args);
}
Run Code Online (Sandbox Code Playgroud)
Log通过这样做,如果我使用不匹配的参数调用函数,则不会显示上面的警告:
printf("Error: %p\n", 'a'); // warning C4477
printf("Error: %p\n"); // warning C4473
Log("Error: …Run Code Online (Sandbox Code Playgroud) 我正在使用ANTLR4来解析一个简单的脚本语言.
此语言对FOR循环使用以下语法:
FOR [I] = 1 to [N]
instructions
NEXT [I]
Run Code Online (Sandbox Code Playgroud)
为了正确,FOR循环必须在FOR关键字之后和NEXT关键字之后具有完全相同的标记.
例如,这是正确的:
FOR I = 1 TO 10
NEXT I
Run Code Online (Sandbox Code Playgroud)
虽然这是不正确的:
FOR I = 1 TO 10
NEXT J
Run Code Online (Sandbox Code Playgroud)
到目前为止,我有一个看起来像这样的规则:
forloop
: FOR VARNAME EQUAL INT TO INT instructions NEXT VARNAME
;
Run Code Online (Sandbox Code Playgroud)
使用以下相关词法规则(我删除了常量关键字FOR : 'FOR';):
fragment ALPHA : [a-zA-Z_];
fragment ALPHANUM : [a-zA-Z_0-9];
fragment DIGIT : [0-9];
VARNAME : ALPHA ALPHANUM*;
INT : DIGIT+;
Run Code Online (Sandbox Code Playgroud)
但是,此规则将解释为第二个实际上不正确的示例.
如何告诉ANTLR4第二个VARNAME必须与规则中的第一个相同?