我最近写一些的OpenGL 3.3代码与顶点数组对象(VAO)并测试它以后英特尔图形适配器,我发现,我感到失望,该元件阵列缓冲器结合显然不是VAO状态的一部分,作为呼叫:
glBindVertexArray(my_vao);
glDrawElements(GL_TRIANGLE_STRIP, count, GL_UNSIGNED_INTEGER, 0);
Run Code Online (Sandbox Code Playgroud)
没有效果,而:
glBindVertexArray(my_vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, my_index_buffer); // ?
glDrawElements(GL_TRIANGLE_STRIP, count, GL_UNSIGNED_INTEGER, 0);
Run Code Online (Sandbox Code Playgroud)
渲染几何体.我认为这是在英特尔执行的OpenGL(因为它是在GL_ARB_vertex_array_object即使在GL_OES_vertex_array_object明确提出(和)该元素阵列的一个单纯的错误是保存状态的一部分),但随后在移动的NVIDIA Quadro 4200发生这不好玩.
它是我的代码中的驱动程序错误,规格错误或错误吗?代码在GeForce 260和480上完美运行.
有没有类似的经历?
什么也奇怪的是,GL_EXT_direct_state_access不具有结合元件阵列缓冲器到VAO的函数(但是它确实有功能来指定顶点ATTRIB阵列,因此阵列缓冲器).GPU制造商是否违反规范并欺骗我们,或者是什么?
编辑:
我原本不打算显示任何源代码,因为我认为这里没有必要.但是根据要求,这是重现问题的最小测试用例:
static GLuint n_vertex_buffer_object, p_index_buffer_object_list[3];
static GLuint p_vao[2];
bool InitGLObjects()
{
const float p_quad_verts_colors[] = {
1, 0, 0, -1, 1, 0,
1, 0, 0, 1, 1, 0,
1, 0, 0, 1, -1, 0,
1, 0, 0, -1, -1, 0, // red quad
0, 0, 1, -1, 1, 0,
0, 0, 1, …Run Code Online (Sandbox Code Playgroud) 与任何优化问题一样,这个主题受到很多打击,但我找不到我想的东西.
很多教程,甚至SO问题都有类似的提示; 一般涵盖:
可能还有一些/很多其他人.我(出于好奇的原因)在我的应用程序中使用几个顶点缓冲区渲染2800万个三角形.我已经尝试了所有上述技术(据我所知),几乎没有性能变化.
虽然我在实施中收到大约40FPS,这绝不是问题,但我仍然很好奇这些优化'技巧'实际上在哪里使用?
我的CPU在渲染过程中空闲了大约20-50%,因此我认为我是GPU必须提高性能.
注意:我现在正在研究gDEBugger
Cross在Game Development上发布
我正在运行该配置:
glxinfo 给我这个参数:
OpenGL renderer string: Mesa X11
OpenGL version string: 2.1 Mesa 8.0.4
OpenGL shading language version string: 1.20
OpenGL extensions:
Run Code Online (Sandbox Code Playgroud)
我的目标是运行OpenGL 3.3(以及GLSL 3.3).如果我很容易遇到开发问题,那么我就失去了硬件和驱动程序,那么有人知道通过我的配置实现这一目标的方法吗?
我知道OpenGL 4和3非常相似,尤其是3.1和4.1.由于两者基本上一起发布,因此很难理解OpenGL 4.0/4.1的基本原理.
在以前的OpenGL版本中,次要版本会向上递增,直到大量更改累积到新的主要版本中.OpenGL 3.x和4.x引入了向后兼容的API变化,然后OpenGL 3.2和3.3被认为是3系列的特定分支,它们不向前兼容,而3.1与4.1+兼容
与OpenGL 3.1相比,OpenGL 4.1提供哪些主要差异,保证将其归入新的主要版本?
额外奖励:在任何情况下,任何差异都会导致GL3的性能提升或只是可访问性吗?
编辑:基于答案的一些额外发现
OpenGL 3.3用于补充OpenGL 4.0,以尽可能多地将功能集成到旧硬件中.OpenGL的3和4,3.3之间进行选择可以是一个更好的选择有时.4.1添加了GL ES 2.0兼容性和一些不错的功能.
更大的工作流程差异之一是通过新的曲面细分着色器在管道中添加GPU编程步骤.另一个是要渲染的多个视口.我相信新的细节级别功能会改变我正在使用的工作流程,也许还会改变其他工作流程,尽管我还没有深入研究这个功能.
如果您发现任何误解或需要改进的地方,请与我们联系.
主题演讲(显然是在回答问题时从答案中删除了..暂时参考实际答案是什么.)
附录G-K对于OpenGL 3.1功能,通过OpenGL 4.1 功能
Khronos Group发布OpenGL 4.0可能"更容易阅读":)
- 采样器对象
- 实例化数组和着色器
texture_cube_map_array和texture_gather
GLSL 4.0和动态LOD
- shader_subroutine和sample_shading
- separate_shader_objects
- 增加纹理/渲染缓冲区所需的大小
- 64位浮点顶点属性
- get_program_binary
- +2 Tesselation着色器
我将OpenGL中的场景以低分辨率渲染到帧缓冲区中.然后我打算将这个版本绘制到整个屏幕上(用GL_NEAREST进行升级).我使用纹理blitting(glBlitFramebuffer)来做到这一点.在我的Nvidia GPU上,这可以工作,但是当我在Intel i7集成显卡上执行完全相同的代码时,目标帧缓冲区上的y位置似乎是错误的(即图像渲染得太远了).
glGetError没有返回错误.由于Nvidia的驱动程序往往非常宽容,我希望我错过了Nvidia不关心的OpenGL规范中的细节.我搜索了互联网和stackoverflow,无法找到描述的类似问题.两位司机都报告支持OpenGL 3.0
我的绘图代码:
//setup viewport for small image
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, image.getWidth(), image.getHeight());
//bind small framebuffer
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glDrawBuffers(GL_COLOR_ATTACHMENT0);
glClear(GL_COLOR_BUFFER_BIT);
//draw
renderRotatedFull(1);//nothing interesting at all happening here
//reset Viewport
glPopAttrib();
//prepare and execute blitting
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glDrawBuffers(GL_BACK_LEFT);
glBlitFramebuffer(0, 0, image.getWidth(), image.getHeight(), 0, 0, Game.width,
Game.height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
//throws exception if there is an OpenGL error
org.lwjgl.opengl.Util.checkGLError();
Run Code Online (Sandbox Code Playgroud)
初始化完成如下:
fbo =glGenFramebuffers();
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
rbo = glGenRenderbuffers();
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, image.getWidth(), image.getHeight());
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, …Run Code Online (Sandbox Code Playgroud) 我已经设法实现OpenGL调试上下文(真棒,最后!)并且大多数事情看起来都很好,但是我看到了一个性能警告,我无法找到有关的信息.
[ 0.0330 - 388.6340] OpenGL Version: 4.2.0 Quadro 600/PCIe/SSE2 NVIDIA Corporation
[ 0.0000 - 549.1920] OpenGL: Program/shader state performance warning: Fragment Shader is going to be recompiled because the shader key based on GL state mismatches. [source=API type=PERFORMANCE severity=MEDIUM id=131218]
Run Code Online (Sandbox Code Playgroud)
我知道自从上次编译着色器以来,它与OpenGL状态有关.
我们拥有的是在上下文之间共享的纹理上运行的四个着色器,并且错误信息仅在创建新上下文后显示.因此,上下文创建可能会改变OpenGL状态机的状态.有可能甚至无法解决它,因为每个上下文都以它自己的"干净"状态机开始吗?
这可能不是什么大问题,因为它只发生在上下文创建时,但是我们运行了很多上下文(至少同时有15个上下文),所以看看我是否能够修复警告会很有趣并一劳永逸地摆脱它.
我正在尝试使用GLKitfor 创建一个简单的应用程序OSX 10.8,但找不到任何示例.苹果文档刚刚从复制iOS到Mac没有真正的例子.我有一个3.2 profile设置的上下文,一个CVDisplayLink绘图,但没有.我正试图从iOS(也用GlKit)制作一些简单的绘图.任何帮助,将不胜感激.谢谢.
我知道透视划分是通过将x,y和z除以w来完成的,以获得标准化的设备坐标.但我无法理解这样做的目的.此外,它与剪辑有什么关系吗?
我正在尝试编写现代的OpenGL,但是遇到了一些让我烦恼的东西.
我有这段代码:
glUseProgram(skybox_program->id);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox->id);
glUniform1i(get_program_uniform(skybox_program, "cubemap_tex"), 1);
//From here
GLint save_cull_mode, save_depth_mode;
glGetIntegerv(GL_CULL_FACE_MODE, &save_cull_mode);
glGetIntegerv(GL_DEPTH_FUNC, &save_depth_mode);
glCullFace(GL_FRONT);
glDepthFunc(GL_LEQUAL);
//To here
glUniformMatrix4fv(get_program_uniform(skybox_program, "camera"), 1, GL_FALSE, cam_rot.mat);
glBindVertexArray(skybox_vao);
glDrawArrays(GL_TRIANGLES, 0, 6 * 2 * 3);
//And these next 2 lines
glCullFace(save_cull_mode);
glDepthFunc(save_depth_mode);
glUseProgram(0);
Run Code Online (Sandbox Code Playgroud)
正如您可能已经意识到的那样,此代码绘制了一个天空盒.部分原因是禁用剔除(所以我们可以在里面看到方框)并更改深度功能(基本上是优化,其中一部分在着色器中,部分在此处).我想保存并恢复这些值,但由于我无法使用gl[Push/Pop]Attrib,我必须自己做.这对于两个属性来说并不是什么大不了的事,但如果我使用更多属性,这很快就会变成一个巨大的痛苦(而且,据我所知,速度glGet*很慢,因为速度不是很快).我读到推送/弹出功能已被弃用,因为它们主要用于处理FFP状态,但这显然不是FFP状态,但推/弹功能非常适合使用.我应该用什么呢?或者我必须处理它?
opengl-3 ×10
opengl ×8
performance ×2
3d ×1
c ×1
deprecated ×1
fbo ×1
glkit ×1
image ×1
intel ×1
java ×1
lwjgl ×1
macos ×1
nvidia ×1
opengl-4 ×1
optimization ×1
sdl ×1
shader ×1
ubuntu-12.04 ×1
vertex-array ×1