Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在现代OpenGL中绘制直线_C++_Opengl_Graphics - Fatal编程技术网

C++ 在现代OpenGL中绘制直线

C++ 在现代OpenGL中绘制直线,c++,opengl,graphics,C++,Opengl,Graphics,我只是想在屏幕上画一条线。我正在使用OpenGL4.6。我找到的所有教程都使用了glvertexinter,据我所知,这是不推荐使用的 我知道如何用缓冲区画三角形,所以我试着用一条线。它没有工作,只是显示了一个黑屏。(我使用的是GLFW和GLEW,我使用的是已经在三角形上测试过的顶点+片段着色器) //生成行 浮动线[]={ 0.0, 0.0, 1.0, 1.0 }; 无符号整数缓冲区;//ID是VRAM的指针 glGenBuffers(1,&buffer);//为三角形分配内存 glBindB

我只是想在屏幕上画一条线。我正在使用OpenGL4.6。我找到的所有教程都使用了
glvertexinter
,据我所知,这是不推荐使用的

我知道如何用缓冲区画三角形,所以我试着用一条线。它没有工作,只是显示了一个黑屏。(我使用的是GLFW和GLEW,我使用的是已经在三角形上测试过的顶点+片段着色器)

//生成行
浮动线[]={
0.0, 0.0,
1.0, 1.0
};
无符号整数缓冲区;//ID是VRAM的指针
glGenBuffers(1,&buffer);//为三角形分配内存
glBindBuffer(GL_数组_BUFFER,BUFFER);//将缓冲区设置为活动阵列
glBufferData(GL_数组_BUFFER,2*sizeof(float),line,GL_STATIC_DRAW);//用数据填充缓冲区
glvertexattributepointer(0,2,GL_FLOAT,GL_FALSE,2*sizeof(FLOAT),0);//指定缓冲区如何转换为顶点
GlenableVertexAttributeArray(0);//启用顶点数组
//循环,直到用户关闭窗口
而(!glfwWindowShouldClose(窗口))
{
//清除以前的
glClear(GLU颜色缓冲位);
//划清界限
gldrawArray(GL_线,0,2);
//交换前后缓冲区
glfwSwapBuffers(窗口);
//轮询并处理事件
glfwPollEvents();
}
我的方向是正确的,还是完全不同的方法是当前的最佳实践? 如果是,如何修复代码?

问题在于调用。第二个参数是缓冲区的大小(以字节为单位)。由于顶点数组由2个坐标和2个组件组成,因此缓冲区的大小是
4*sizeof(float)
,而不是
2*sizeof(float)

glBufferData(GL_数组_BUFFER,2*sizeof(float),line,GL_STATIC_DRAW)

glBufferData(GL_数组_BUFFER,4*sizeof(float),line,GL_STATIC_DRAW);
但请注意,这仍然不是“现代”的OpenGL。如果您想使用核心配置文件,那么您必须使用程序和


但是,如果您使用的是核心,并且设置了前向兼容性位,则行()的宽度不能大于1.0。

宽行-大于1.0的线宽值将生成
无效\u值
错误。

你必须找到一种不同的方法

我建议使用a,它沿线条带(甚至是线条循环)生成。
任务是生成粗线条带,尽可能减少CPU和GPU开销。这意味着避免在CPU上计算多边形以及几何体着色器(或细分着色器)

直线的每一段由一个四边形组成,分别由两个三角形图元和六个顶点表示

025
+-------+  +
|     /  / |
|   /  /   |
| /  /     |
+  +-------+
1   3        4
在线段之间必须找到斜接,并且必须将四边形切割为斜接

+----------------+
|              / |
|第1部分/|
|          /     |
+--------+       |
|第2部分
|       |
|       |
+-------+
使用线条带的角点创建阵列。数组必须包含第一个点和最后一个点两次。当然,通过比较索引0和数组长度来识别数组的第一个和最后一个元素是很容易的,但是我们不想在着色器中进行任何额外的检查。
如果必须绘制线循环,则必须将最后一个点添加到阵列头部,将第一个点添加到阵列尾部

点的数组存储到一个数组中。我们使用的好处是,SSBO的最后一个变量可以是一个大小可变的数组。在较旧版本的OpenGL(或OpenGL ES)中,可以使用a或甚至a

着色器不需要任何顶点坐标或属性。我们只需要知道线段的索引。坐标存储在缓冲区中。为了找到索引,我们使用当前正在处理的顶点的索引()。
要使用
N
段绘制线条条,
6*(N-1)
顶点必须进行tpo处理

我们必须创建一个“空”(没有任何顶点属性规范):

glgenvertexarray(1,&vao);
glBindVertexArray(vao);
并绘制
2*(N-1)
三角形(
6*(N-1)
顶点):

gldrawArray(GL_三角形,0,6*(N-1));
对于SSBO中的坐标数组,使用了数据类型
vec4
(请相信我,您不想使用):

layout(std430,binding=0)缓冲区TVertex
{
vec4顶点[];
};
计算线段的索引,其中顶点坐标也属于该线段,以及2个三角形中点的索引:

int line\u i=gl\u VertexID/6;
int tri_i=gl_VertexID%6;
由于我们正在绘制
N-1
线段,但数组中的元素数量为
N+2
,因此可以针对顶点着色器中处理的每个顶点访问元素形式为
顶点[line\t]
顶点[line\t+3]

顶点[line\u t+1]
顶点[line\u t+2]
分别是线段的起点和终点坐标<代码>顶点[line\u t]
顶点[line\u t+3]
是计算斜接所必需的

线条的厚度应以像素为单位设置(
均匀浮点u_厚度
)。坐标必须从模型空间转换到窗口空间。为此,必须知道视口的分辨率(
uniform vec2 u_分辨率
)。别忘了这道菜。线条的绘制甚至可以在透视投影下进行

vec4va[4];

对于(int i=0;i,以下是如何在“现代”OpenGL(3.3+)中创建两个顶点之间的直线:

顶点着色器:

#version 330 core
layout (location = 0) in vec3 aPos;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0);
}
片段着色器:

#version 330 core
out vec4 FragColor;

void main()
{
    FragColor = vec4(1.0); // white
}
GLfloat lineSeg[] =
{
    0.0f, 0.0f, 0.0f, // first vertex
    2.0f, 0.0f, 2.0f // second vertex
};

GLuint lineVAO, lineVBO;
glGenVertexArrays(1, &lineVAO);
glGenBuffers(1, &lineVBO);
glBindVertexArray(lineVAO);
glBindBuffer(GL_ARRAY_BUFFER, lineVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(lineSeg), &lineSeg, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*)0);
shader.use();
shader.setMat4("projection", projection);
shader.setMat4("view", view);
model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(0.0f, 0.5f, 0.0f));
shader.setMat4("model", model);
//glEnable(GL_LINE_SMOOTH);
//glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glBindVertexArray(lineVAO);
glLineWidth(3.3f);
glDrawArrays(GL_LINES, 0, 2);
glLineWidth(1.0f);