我一直在尝试使用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和Direct3D渲染管道中,几何着色器在顶点着色器之后和片段/像素着色器之前处理.现在显然在片段/像素着色器没有意义之后处理几何着色器,但我想知道为什么不把它放在顶点着色器之前?
从软件/高级角度来看,至少,它似乎更有意义:首先运行几何着色器以创建所需的所有顶点(并转储仅与几何着色器相关的任何数据),然后运行这样创建的所有顶点上的顶点着色器.有一个明显的缺点,现在必须在每个新创建的顶点上运行顶点着色器,但是在当前管道中需要为几何着色器中的每个顶点运行需要完成的任何逻辑. ,据推测; 所以那里没有太大的表现.
我假设,因为几何着色器在两个管道中处于这个位置,所以存在硬件原因,或者说它更有意义的非显而易见的管道原因.
(我知道在运行几何着色器之前需要进行多边形链接(如果它需要单点作为输入,可能不会这样做)但是我也知道它需要在几何着色器之后运行,所以它仍然不会在这些阶段之间运行顶点着色器的感觉?)
所以我现在已经尝试了一段时间,将顶点属性数组传递给几何着色器.它是一个float数组(其中每个顶点的属性只是一个浮点值)
现在,当我把它放在几何着色器中时:
attribute float nodesizes;
Run Code Online (Sandbox Code Playgroud)
着色器编译器抱怨:
OpenGL requires geometry inputs to be arrays
Run Code Online (Sandbox Code Playgroud)
我如何完全传递它?
另外,这是我的顶点属性的代码:
glBindAttribLocation(programid, 1, "nodesizes");
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, array);
glEnableVertexAttribArray(1);
Run Code Online (Sandbox Code Playgroud)
难道我做错了什么?
我试图在尝试修改内容之前编写一个简单的几何着色器,它只是通过顶点.
我的顶点着色器是
#version 150 core
in vec3 inPosition;
in vec4 inColor;
out vec4 vertexColor;
void main() {
vertexColor = inColor;
gl_Position = vec4(inPosition, 1.0);
}
Run Code Online (Sandbox Code Playgroud)
我的几何着色器是
#version 150 core
layout (triangles) in;
layout (triangle_strip, max_vertices=3) out;
void main() {
gl_Position = gl_in[0].gl_Position;
EmitVertex();
gl_Position = gl_in[1].gl_Position;
EmitVertex();
gl_Position = gl_in[2].gl_Position;
EmitVertex();
EndPrimitive();
}
Run Code Online (Sandbox Code Playgroud)
我的片段着色器是
#version 150 core
in vec4 vertexColor;
out vec4 fragColor;
void main() {
fragColor = vertexColor;
}
Run Code Online (Sandbox Code Playgroud)
如果没有链接几何着色器,一切正常.但是,当我在几何着色器中链接时,它停止工作.我错过了什么?我的几何着色器是否需要vertexColor来自我的顶点着色器的输入,如果是这样,如何完成?
所以,我一直在尝试使用几何着色器从线条邻接原语中绘制一个圆柱体,它适用于4个顶点,但我想这样做,我可以将它应用于更长的线条.问题是,它在第四个顶点之后完全混乱.我知道原语让着色器访问邻接信息,但我不知道如何访问它,所以我的问题是:
我如何使用邻接信息?并且,是否可以使用相同的绘图调用为多个行执行此操作?
如果您能提供伪代码示例,我将非常感谢.
我正在尝试编写一个几何着色器来替换glLineWidth行为。我想绘制具有可自定义宽度的线条(现在使用统一的线条就足够了)。无论相机投影或与线条所在位置的距离如何,线条应始终具有相同的粗细。
基于大量的谷歌搜索,我想出了以下几何着色器:
#version 330
layout (lines) in;
layout (triangle_strip, max_vertices = 4) out;
uniform mat4 u_model_matrix;
uniform mat4 u_view_matrix;
uniform mat4 u_projection_matrix;
uniform float u_thickness = 4; // just a test default
void main()
{
float r = u_thickness / 2;
mat4 mv = u_view_matrix * u_model_matrix;
vec4 p1 = mv * gl_in[0].gl_Position;
vec4 p2 = mv * gl_in[1].gl_Position;
vec2 dir = normalize(p2.xy - p1.xy);
vec2 normal = vec2(dir.y, -dir.x);
vec4 offset1, offset2;
offset1 = vec4(normal * r, …Run Code Online (Sandbox Code Playgroud) 我想用几何着色器从点数据绘制一个正方形。
在 中vertex shader,我发出一个点。
#version 330 core
void main() {
gl_Position = vec4(0, 0, 0, 1.0);
}
Run Code Online (Sandbox Code Playgroud)
在几何着色器中,我想创建一个三角形带形成一个正方形。
尺寸目前无关紧要,因此模型的尺寸应为1(范围从(-0.5,-0.5)从初始点位置到(+0.5,+0.5)。
我需要帮助来计算发射顶点的位置,如代码所示:
#version 330 core
layout(points) in;
layout(triangle_strip, max_vertices=4) out;
out vec2 tex_coord;
uniform mat4x4 model;
uniform mat4x4 view;
uniform mat4x4 projection;
void main() {
int i;
for(i = 0; i < gl_in.length(); ++i) {
mat4x4 trans;
trans = //???
gl_Position = projection * view * model * trans * gl_in[i].gl_Position;
tex_coord = vec2(0, 0);
EmitVertex();
trans = …Run Code Online (Sandbox Code Playgroud) 更新:
我创建了一个记录良好的ipython笔记本.如果您只想要代码,请查看第一个答案.
题
我有40x40x40的灰度值.这需要旋转/移位/剪切.
这是一个有用的同类转换集合:http://www.lfd.uci.edu/~gohlke/code/transformations.py.html
我需要像处理一对(位置矢量,值)来处理我体积中的每个体素.然后我将变换位置并从变换矢量集合中为每个坐标采样新值.
抽样似乎相当困难,我很高兴找到这个:https: //docs.scipy.org/doc/scipy-0.18.1/reference/generated/scipy.ndimage.affine_transform.html#scipy.ndimage.affine_transform
给定的矩阵和偏移用于通过仿射变换为输出中的每个点找到输入中的对应坐标.这些坐标处的输入值由所请求顺序的样条插值确定.根据给定的模式填充输入边界之外的点.
听起来很完美.
但用法非常棘手.这里有人使用该代码来旋转图像.他的旋转矩阵是2x2,所以它不是同质坐标.我尝试将同源坐标(2D)中的平移矩阵传递给函数:
dim =10
arr=np.zeros((dim,dim))
arr[0,0]=1
mat=np.array([[1,0,1],[0,1,0],[0,0,1]])
out3=scipy.ndimage.affine_transform(arr,mat)
print("out3: ",out3)
Run Code Online (Sandbox Code Playgroud)
这会产生错误:
Traceback (most recent call last):
File "C:/Users/212590884/PycharmProjects/3DAugmentation/main.py", line 32, in <module>
out3=scipy.ndimage.affine_transform(arr,mat)
File "C:\Users\212590884\AppData\Local\Continuum\Anaconda2\lib\site-packages\scipy\ndimage\interpolation.py", line 417, in affine_transform
raise RuntimeError('affine matrix has wrong number of rows')
RuntimeError: affine matrix has wrong number of rows
Run Code Online (Sandbox Code Playgroud)
显然,这不适用于齐次坐标.如何使用它来移动数据?
这只是在2D中,在3D中我甚至无法旋转音量:
dim =10
arr=np.zeros((dim,dim,dim))
arr[0,0]=1
angle=10/180*np.pi
c=np.cos(angle)
s=np.sin(angle)
mat=np.array([[c,-s,0,0],[s,c,0,0],[0,0,1,0],[0,0,0,1]])
out3=scipy.ndimage.affine_transform(arr,mat)
print("out3: ",out3)
Run Code Online (Sandbox Code Playgroud)
错误消息是相同的: affine matrix has wrong number …
在添加几何着色器之前,我在顶点着色器中声明了一个变量:
out vec3 normal;
Run Code Online (Sandbox Code Playgroud)
由片段着色器接收为:
in vec3 normal;
Run Code Online (Sandbox Code Playgroud)
但是,如果我向程序添加几何着色器,链接器会告诉我法线尚未声明为前一阶段的输出。但我不确定如何在几何着色器中接收或发送输出。