我的代码以这种方式接近GLSL着色器管理,它创建每个着色器和相关程序并删除每个着色器和程序.我最近阅读了http://www.opengl.org/wiki/GLSL_Object,并指出:
由于附加到程序对象,着色器对象即使删除着色器对象也将继续存在.只有在系统不再附加到任何程序对象时(当用户要求删除它时),它才会被系统删除.
我是否正确得到这个,如果我glDeleteShader()在链接到程序后调用着色器对象,我只需要跟踪程序?假设这一直是真的,这是安全的吗?
我今天刚刚安装了Visual Studio 2012,我想知道如何在平台上安装GLUT和OpenGL?
过去几周我一直在学习OpenGL,我在实现Phong着色器方面遇到了一些麻烦.尽管使用了smooth限定符,但似乎在顶点之间没有插值.我在这里错过了什么吗?为了给予信用到期的信用,顶点和片段着色器的代码严重影响了OpenGL SuperBible第五版.我强烈推荐这本书!
顶点着色器:
#version 330
in vec4 vVertex;
in vec3 vNormal;
uniform mat4 mvpMatrix; // mvp = ModelViewProjection
uniform mat4 mvMatrix; // mv = ModelView
uniform mat3 normalMatrix;
uniform vec3 vLightPosition;
smooth out vec3 vVaryingNormal;
smooth out vec3 vVaryingLightDir;
void main(void) {
vVaryingNormal = normalMatrix * vNormal;
vec4 vPosition4 = mvMatrix * vVertex;
vec3 vPosition3 = vPosition4.xyz / vPosition4.w;
vVaryingLightDir = normalize(vLightPosition - vPosition3);
gl_Position = mvpMatrix * vVertex;
}
Run Code Online (Sandbox Code Playgroud)
片段着色器:
#version 330
out vec4 vFragColor; …Run Code Online (Sandbox Code Playgroud) 当您学习3D编程时,您会被教导从3个转换矩阵的角度来考虑它是最简单的:
模型矩阵.该矩阵对于每个模型都是独立的,它可以根据需要旋转和缩放对象,最后将其移动到3D世界中的最终位置."模型矩阵将模型坐标转换为世界坐标".
视图矩阵.对于大量对象(如果不是对于所有对象),该矩阵通常是相同的,并且它根据当前"摄像机位置"旋转并移动所有对象.如果您对相机拍摄3D场景进行成像,并且屏幕上呈现的内容是此相机捕获的图像,则相机的位置及其查看方向定义场景的哪些部分可见以及对象如何出现在捕获的图像上.在渲染单个帧时更改视图矩阵几乎没有理由,但实际上存在这些原因(例如,通过渲染场景两次并更改其间的视图矩阵,您可以在场景中创建一个非常简单但令人印象深刻的镜像) .通常,视图矩阵在绘制的两个帧之间仅改变一次."视图矩阵将世界坐标转换为眼睛坐标".
投影矩阵.投影矩阵决定这些3D坐标如何被映射到2D坐标,例如,如果存在应用于它们的透视(对象变得越小,它们离观察者越远)(正交投影).投影矩阵几乎没有变化.如果您渲染到窗口并且窗口大小已更改,或者您正在全屏渲染并且分辨率已更改,则可能必须更改,但是仅当新窗口大小/屏幕分辨率具有与之前不同的显示宽高比时.有一些疯狂的效果,你可能想要改变这个矩阵,但在大多数情况下,它对于整个程序的实时几乎是不变的."投影矩阵将眼睛坐标转换为屏幕坐标".
这对我来说很有意义.当然,总是可以将所有三个矩阵组合成单个矩阵,因为首先将矢量乘以矩阵A然后乘以矩阵B与将矢量乘以矩阵相同C,其中C = B * A.
现在,如果你看一下经典的OpenGL(OpenGL 1.x/2.x),OpenGL知道一个投影矩阵.然而,OpenGL不提供模型或视图矩阵,它只提供组合的模型视图矩阵.为什么?此设计强制您永久保存和恢复"视图矩阵",因为它将被应用于它的模型转换"破坏".为什么没有三个单独的矩阵?
如果你看一下新的OpenGL版本(OpenGL 3.x/4.x)并且你没有使用经典的渲染管道而是使用着色器(GLSL)自定义所有内容,那么根本就没有可用的矩阵,你必须定义自己的矩阵.大多数人仍然保留投影矩阵和模型视图矩阵的旧概念.为什么要这么做?为什么不使用三个矩阵,这意味着您不必永久保存和恢复模型视图矩阵,或者使用单个组合模型 - 视图 - 投影(MVP)矩阵,这可以节省顶点着色器中的矩阵乘法对于任何单个顶点渲染(毕竟这样的乘法也不是免费的).
因此,总结一下我的问题:在具有三个单独的矩阵或单个MVP矩阵的情况下,哪个优势具有组合的模型 - 视图矩阵以及单独的投影矩阵?
我一直在尝试使用OpenGL和GLSL编写Marching Cubes算法的两遍GPU实现,类似于GPU Gems 3第一章中详述的算法.但是,glDrawArrays在我的第一次传球中的呼叫始终失败了GL_INVALID_OPERATION.
我查找了所有可以找到的文档,并发现这些条件glDrawArrays可以抛出该错误:
GL_INVALID_OPERATION如果非零缓冲区对象名称绑定到已启用的数组或GL_DRAW_INDIRECT_BUFFER绑定,并且缓冲区对象的数据存储当前已映射,则会生成.GL_INVALID_OPERATION如果glDrawArrays在执行glBegin和相应的执行之间执行,则生成glEnd.GL_INVALID_OPERATION将由glDrawArrays或glDrawElements当前程序对象中的任何两个活动采样器具有不同类型,但引用相同的纹理图像单元.GL_INVALID_OPERATION 如果几何着色器处于活动状态且模式与当前安装的程序对象中几何着色器的输入基元类型不兼容,则会生成.GL_INVALID_OPERATION如果模式是GL_PATCHES并且没有曲面细分控制着色器处于活动状态,则生成.GL_INVALID_OPERATION如果将基元的顶点记录到用于变换反馈目的的缓冲区对象,则会生成超出任何缓冲区对象大小的限制,或者超出结束位置偏移+大小-1,如下所示glBindBufferRange.GL_INVALID_OPERATIONglDrawArrays()如果不存在几何着色器,则生成变换反馈,并且模式不是允许的模式之一.GL_INVALID_OPERATIONglDrawArrays()如果存在几何着色器,则生成变换反馈,并且几何着色器的输出基元类型与变换反馈primitiveMode不匹配.GL_INVALID_OPERATION 如果绑定着色器程序无效,则生成.GL_INVALID_OPERATION如果正在使用变换反馈,则生成编辑10/10/12:绑定到变换反馈绑定点的缓冲区也绑定到数组缓冲区绑定点.这是我遇到的问题,因为我绑定了缓冲区的拼写错误.虽然规范确实声明这是非法的,但在我发现的任何文档中,它都没有列在glDrawArrays下作为它可以抛出错误的原因之一.不幸的是,我找不到任何一份官方文档,其中包括超过3篇.我不得不从众多来源收集这份清单.第7点和第8点实际上来自文档glBeginTransformFeedback,第9点似乎根本没有记录.我发现它在某个论坛帖子中提到过.但是,我仍然不认为这个列表是完整的,因为这些似乎都没有解释我得到的错误.
glBegin并glEnd没有提供连.layout (points) in,并且glDrawArrays正在调用GL_POINTS.GL_PATCHES任何类型的镶嵌着色器.layout (points) out …我正在研究一些着色器,我需要改变法线.
我在几个教程中读到了变换法线的方法,你将它们与模型视图矩阵的逆的转置相乘.但我找不到为什么会这样解释,那背后的逻辑是什么?
在OpenGL初始化期间,程序应该执行以下操作:
<Get Shader Source Code>
<Create Shader>
<Attach Source Code To Shader>
<Compile Shader>
Run Code Online (Sandbox Code Playgroud)
获取源代码可能就像将它放在一个字符串中一样简单:(示例摘自SuperBible,第6版)
static const char * vs_source[] =
{
"#version 420 core \n"
" \n"
"void main(void) \n"
"{ \n"
" gl_Position = vec4(0.0, 0.0, 0.0, 1.0); \n"
"} \n"
};
Run Code Online (Sandbox Code Playgroud)
问题是很难直接在字符串中编辑,调试和维护GLSL着色器.因此,从文件中获取字符串中的源代码更容易开发:
std::ifstream vertexShaderFile("vertex.glsl");
std::ostringstream vertexBuffer;
vertexBuffer << vertexShaderFile.rdbuf();
std::string vertexBufferStr = vertexBuffer.str();
// Warning: safe only until vertexBufferStr is destroyed or modified
const GLchar *vertexSource = vertexBufferStr.c_str();
Run Code Online (Sandbox Code Playgroud)
现在的问题是如何使用您的程序发送着色器?实际上,使用您的应用程序运送源代码可能是个问题.OpenGL支持"预编译的二进制着色器",但Open Wiki声明:
程序二进制格式不打算传输.期望不同的硬件供应商接受相同的二进制格式是不合理的.期望来自同一供应商的不同硬件接受相同的二进制格式是不合理的.[...]
如何使用C++软件实际运送GLSL着色器?
我一直在阅读:
http://alfonse.bitbucket.io/oldtut/Basics/Tut01%20Dissecting%20Display.html
我不太清楚这个功能是做什么的.
我认为它可以使用给定的VBO,但我不确定.
我以为那就是做了什么glEnableClientState(GL_VERTEX_ARRAY).
QPaintera 绘制街道地图widget
QPainterPaths它制作包含预先绘制的路径widget目前是QWidget,不是QGLWidget,但这可能会改变.QImage绘制成a 并最终将所有图像绘制到widgetQPainterPaths 已经分块了,所以这不是问题QImages约5倍QWidgetQPainterPaths,每个有大约150个线性线段QPainter::Antialiasing渲染提示绘制大约15k路径,QPen使用圆顶和圆形连接QPainterPaths(和线宽+颜色;一些绘制,一些填充)
QPainter支持QPainterPaths转换为可以在a上绘制的其他东西OpenGL buffer,这将是一个很好的解决方案.OpenGL屏幕外渲染,我知道有不同类型的OpenGL缓冲区,其中大多数不是用于2D图像渲染而是用于顶点数据.Paint Device for chunk | Rendering the chunk itself | Painting chunk on QWidget
-----------------------+----------------------------+--------------------------
QImage | 2000 ms | < …Run Code Online (Sandbox Code Playgroud) 所以,我只知道如何使用Python,但我也知道如何在3d中建模.我听说过OpenGL,我真的想学习如何使用,因为它看起来非常有用(我想用它创建简单的游戏......).我找到了PyOpenGL,OpenGL的Python绑定,但我找不到任何"真正的"文档,所以唯一的选择是研究用C++或其他东西编写的代码示例和教程.但是,正如我所说,我只知道如何使用Python.我该怎么办?