- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
所以我正在制作塔防游戏。我与他们共享了一个构建,这样我就可以检查在另一台主机上是否一切正常。
实际发生的是,虽然一切都在我这边完美呈现(在我的 mac/xcode + windows/visual studio 2012 上),但在我 friend 这边,几何图形似乎搞砸了。我屏幕上的每个对象都由一个 VBO 表示,我每次都使用它来渲染到不同的位置。但似乎我的 VBO 具有从所有模型导入的所有几何图形。 (因此塔旁边有树。)
结果如下:
(我的电脑) (我 friend 的电脑)
到目前为止,我已经设法将此问题调试到一定程度。我可以说这不是我导入模型的方式,因为在将它们作为 VBO 发送到 gpu 之前,我正在创建一个包含所有 vector 的 debug.txt 文件,并且在两台计算机上它们输出相同的值。所以他们的 vector 不会被内存问题或类似的问题弄乱。所以我在想,也许这就是我设置或渲染 VBO 的方式
但最让我印象深刻的是,为什么某些东西在我的电脑上可以正常工作,而在我 friend 的电脑上却不行。我确定的一个区别是我的计算机是一个开发者站(无论这意味着什么),而我 friend 的计算机不是。
这是我的 VBO 加载函数和我的 VBO 绘图函数:我使用 glfw 创建我的窗口和上下文,并包含 glew header 以启用一些较新的 opengl 功能。
void G4::Renderer::LoadObject(
G4::TILE_TYPES aType,
std::vector<float> &v_data,
std::vector<float> &n_data,
std::vector<float> &t_data,
float scale,
bool has_texture,
unsigned int texture_id
)
{
unsigned int vertices_id, vertices_size, normals_id, texturecoordinates_id;
vertices_size = static_cast<unsigned int>(v_data.size());
glGenBuffers(1, &vertices_id);
glGenBuffers(1, &normals_id);
//::->Vertex array buffer upload.
glBindBuffer(GL_ARRAY_BUFFER, vertices_id);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*v_data.size(), &v_data.front(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//::->Normal Array buffer upload.
glBindBuffer(GL_ARRAY_BUFFER, normals_id);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*n_data.size(), &n_data.front(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
if (has_texture)
{
glGenBuffers(1, &texturecoordinates_id);
glBindBuffer(GL_ARRAY_BUFFER, texturecoordinates_id);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*t_data.size(), &(t_data[0]), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
this->vbos[aType].Update(vertices_id, vertices_size, normals_id, texture_id, texturecoordinates_id, scale, has_texture);
}
绘制代码:
void G4::Renderer::DrawUnit(G4::VBO aVBO, bool drawWithColor, float r, float g, float b, float a)
{
bool model_has_texture = aVBO.HasTexture();
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
if (model_has_texture && !drawWithColor) {
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
}
if (drawWithColor)
{
glColor4f(r, g, b, a);
}
glScalef(aVBO.GetScaleValue(), aVBO.GetScaleValue(), aVBO.GetScaleValue());
glBindBuffer(GL_ARRAY_BUFFER, aVBO.GetVerticesID());
glVertexPointer(3, GL_FLOAT, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, aVBO.GetNormalsID());
glNormalPointer(GL_FLOAT, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
if (model_has_texture && !drawWithColor)
{
glBindTexture(GL_TEXTURE_2D, aVBO.GetTextureID());
glBindBuffer(GL_ARRAY_BUFFER, aVBO.GetTextureCoordsID());
glTexCoordPointer(2, GL_FLOAT, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
glDrawArrays(GL_TRIANGLES, 0, aVBO.GetVerticesSize());
if (model_has_texture && !drawWithColor) {
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D);
}
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}
我没有想法,希望有人能指导我如何进一步调试它。
最佳答案
OpenGL 规范。没有指定当您发出具有比缓冲区存储更多顶点的绘图调用时应该发生的确切行为。这可能在一台机器上正常工作而不在另一台机器上正常工作的原因归结为实现。如果出现这种情况,每个供应商都可以为所欲为,因此渲染伪像可能会出现在 AMD 硬件上,但根本不会出现在 nVIDIA 或 Intel 上。更糟糕的是,当要求绘制太多顶点时,调用 glDrawArrays (...)
实际上不会产生任何错误状态。您肯定需要在来自多个供应商的硬件上测试您的软件以捕获此类错误;谁制造了您计算机中的 GPU 以及驱动程序版本,与操作系统和编译器一样重要。
尽管如此,还是有一些方法可以捕捉到这些愚蠢的错误。 gDEBugger 就是其中之一,还有一个新的 OpenGL 扩展,我将在下面讨论。我更喜欢使用新的扩展,因为根据我的经验,除了已弃用的 API 调用和错误(可以配置 gDEBugger 来监控)之外,该扩展还可以警告您使用低效对齐的数据结构和各种其他可移植性和性能问题。
我想添加一些我用来在我的软件中使用 OpenGL 调试输出的代码,因为这是一个错误行为的示例,它实际上不会生成您可以使用 glGetError (...) 捕获的错误
。有时,您可以使用 Debug Output 捕获这些错误(不过,我只是对其进行了测试,这不是其中一种情况)。您将需要一个 OpenGL 调试上下文才能正常工作(设置它的过程高度依赖于平台),但它是一个上下文标志,就像向前/向后兼容和核心一样(glfw 应该让这对您来说很容易)。
x86 平台的自动断点宏
// Breakpoints that should ALWAYS trigger (EVEN IN RELEASE BUILDS) [x86]!
#ifdef _MSC_VER
# define eTB_CriticalBreakPoint() if (IsDebuggerPresent ()) __debugbreak ();
#else
# define eTB_CriticalBreakPoint() asm (" int $3");
#endif
启用 OpenGL 调试输出(需要调试上下文和相对较新的驱动程序,OpenGL 4.x 时代)
// SUPER VERBOSE DEBUGGING!
if (glDebugMessageControlARB != NULL) {
glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
glDebugMessageControlARB (GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
glDebugMessageCallbackARB ((GLDEBUGPROCARB)ETB_GL_ERROR_CALLBACK, NULL);
}
一些重要的实用函数,用更有意义的文本替换枚举值
const char*
ETB_GL_DEBUG_SOURCE_STR (GLenum source)
{
static const char* sources [] = {
"API", "Window System", "Shader Compiler", "Third Party", "Application",
"Other", "Unknown"
};
int str_idx =
min ( source - GL_DEBUG_SOURCE_API,
sizeof (sources) / sizeof (const char *) );
return sources [str_idx];
}
const char*
ETB_GL_DEBUG_TYPE_STR (GLenum type)
{
static const char* types [] = {
"Error", "Deprecated Behavior", "Undefined Behavior", "Portability",
"Performance", "Other", "Unknown"
};
int str_idx =
min ( type - GL_DEBUG_TYPE_ERROR,
sizeof (types) / sizeof (const char *) );
return types [str_idx];
}
const char*
ETB_GL_DEBUG_SEVERITY_STR (GLenum severity)
{
static const char* severities [] = {
"High", "Medium", "Low", "Unknown"
};
int str_idx =
min ( severity - GL_DEBUG_SEVERITY_HIGH,
sizeof (severities) / sizeof (const char *) );
return severities [str_idx];
}
DWORD
ETB_GL_DEBUG_SEVERITY_COLOR (GLenum severity)
{
static DWORD severities [] = {
0xff0000ff, // High (Red)
0xff00ffff, // Med (Yellow)
0xff00ff00, // Low (Green)
0xffffffff // ??? (White)
};
int col_idx =
min ( severity - GL_DEBUG_SEVERITY_HIGH,
sizeof (severities) / sizeof (DWORD) );
return severities [col_idx];
}
我的调试输出回调(有点乱,因为它在我的软件中以不同颜色打印每个字段)
void
ETB_GL_ERROR_CALLBACK (GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar* message,
GLvoid* userParam)
{
eTB_ColorPrintf (0xff00ffff, "OpenGL Error:\n");
eTB_ColorPrintf (0xff808080, "=============\n");
eTB_ColorPrintf (0xff6060ff, " Object ID: ");
eTB_ColorPrintf (0xff0080ff, "%d\n", id);
eTB_ColorPrintf (0xff60ff60, " Severity: ");
eTB_ColorPrintf ( ETB_GL_DEBUG_SEVERITY_COLOR (severity),
"%s\n",
ETB_GL_DEBUG_SEVERITY_STR (severity) );
eTB_ColorPrintf (0xffddff80, " Type: ");
eTB_ColorPrintf (0xffccaa80, "%s\n", ETB_GL_DEBUG_TYPE_STR (type));
eTB_ColorPrintf (0xffddff80, " Source: ");
eTB_ColorPrintf (0xffccaa80, "%s\n", ETB_GL_DEBUG_SOURCE_STR (source));
eTB_ColorPrintf (0xffff6060, " Message: ");
eTB_ColorPrintf (0xff0000ff, "%s\n\n", message);
// Force the console to flush its contents before executing a breakpoint
eTB_FlushConsole ();
// Trigger a breakpoint in gDEBugger...
glFinish ();
// Trigger a breakpoint in traditional debuggers...
eTB_CriticalBreakPoint ();
}
由于我实际上无法让您的情况触发调试输出事件,我想我至少会展示一个我能够触发的事件示例。这不是您可以使用 glGetError (...)
捕获的错误,也不是与此相关的错误。但这肯定是一个 draw call 问题,如果不使用此扩展,您可能会在项目期间完全忘记 :)
OpenGL Error:============= Object ID: 102 Severity: Medium Type: Performance Source: API Message: glDrawElements uses element index type 'GL_UNSIGNED_BYTE' that is not optimal for the current hardware configuration; consider using 'GL_UNSIGNED_SHORT' instead.
关于c++ - 不同电脑的渲染问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18064988/
在我的 OpenGL 程序中,我按顺序执行以下操作: // Drawing filled polyhedrons // Drawing points using GL_POINTS // Displa
我想传递一个包含原始页面的局部变量,这个变量只包含一个带有值的符号。 当我使用此代码时,它运行良好,可以在部分中访问 origin 变量: render :partial => "products",
为什么这个 HTML/脚本(来自“JavaScript Ninja 的 secret ”)不渲染? http://jsfiddle.net/BCL54/
我想在阅读完 View 后返回到特定的网页位置(跳转到页内 anchor )。换句话说,在 views.py 中,我想做类似的事情: context={'form':my_form} return r
我有一个包含单条折线的 PathGeometry,并以固定的间隔向该线添加一个新点(以绘制波形)。使用 Perforator 工具时,我可以看到每次向直线添加一个点时,WPF 都会将整个 PathGe
尝试了解如何消除或最小化网站上不同 JavaScript 库的渲染延迟。 例如,如果我想加载来自许多社交网络的“即时”关注按钮,它们似乎会相互阻止渲染,并且您会收到令人不快的弹出窗口。 (func
我有以 xyz 点格式表示 3D 表面(即地震断层平面)的数据。我想创建这些表面的 3D 表示。我使用 rgl 和 akima 取得了一些成功,但是它无法真正处理可能会自行折叠或在同一 x,y 点具有
我正在用 Libgdx 编写一个小游戏。 我有一个 Render[OpenGL] 线程,它不断对所有对象调用 render() 和一个更新线程不断对所有对象调用 update(double delta
我有一个 .Rmd 文件包含: ```{r, echo=FALSE, message=FALSE, results='asis'} library(xtable) print(xtable(group
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 9 年前。 Improve
请不要评判我,我只是在学习 Swift。 最近我安装了 MetalPetal 框架,并按照说明操作: https://github.com/MetalPetal/MetalPetal#example-
如果您尝试渲染 Canvas 宽度和高度之外的图像,计算机是否仍会尝试渲染它并使用资源来尝试渲染它?我只是想找出在尝试渲染图像之前检查图像是否在 Canvas 内是否更好。 最佳答案 我相信它仍然在无
我在 safari 中渲染时遇到问题。 在 firefox、chrome 和 IE 上。如下图所示: input.searchbox{-webkit-border-radius:10px;-moz-b
我正在尝试通过远程桌面在 Windows7 下运行我在 RHEL7 服务器中制作的 java 程序。 服务器中的所有java程序都无法通过远程桌面呈现。如果我在服务器位置访问服务器本身,它们看起来没问
我正处于一个新项目的设计阶段,该项目将采用数据集并将其加载到文档中,然后围绕模板呈现文档。呈现的文件可以是 CSV 数据集、PDF 营销信函、电子邮件……很多东西。数据不会是数学方程式,我只是在寻找一
有没有办法在不同的 div 下渲染 React 组件的子组件? ... ... ... ... ...
使用以下代码: import numpy as np from plotly.offline import iplot, init_notebook_mode import plotly.graph_
截至最近, meteor 的所有文档都指出 onRendered是一种在模板完成渲染时获取回调的新方法。和 rendered只是为了向后兼容。 但是,这似乎对我不起作用。 onRendered永远不会
所以在我的基本模板中,我有:{% render "EcsCrmBundle:Module:checkClock" %} 然后我创建了 ModuleController.php ... getDoctr
我正在使用 vue-mathjax 来编译我的 vue 项目中的数学方程。它正在编译第一个括号 () 之间的文本。我想防止编译括号内的字符串。在文档中我发现,对于$符号,如果我们想逃避编译,我们需要使
我是一名优秀的程序员,十分优秀!