[英]C++ Drawing arrays with OpenGL
我是“新OpenGL”服务方法的新手。
我认为我误解了,或者不了解使用OpenGL绘制数据的某些步骤。
假定我可以打开OpenGL上下文,请(阅读此问题的SO用户)能否阐明在OpenGL中渲染描述直线的点数组所需的所有步骤。
目前,我一直在这样做:
// In main:
float* my_points = new float[100];
// Fill my_points with some data to be drawn as a continuous line on the screen in x-y space.
// Inside esMainLoop, inside drawing function:
GLfloat* points = new GLfloat[3 * 100]; // x,, y, z points
// Copy data to points
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, points); // No idea what this is or how it works
glEnableVertexAttribArray(0);
glDrawArrays(GL_LINE_STRIP, 0, 100);
// In function called when CTRL+C is pressed:
delete my_points;
以前(几年前),我使用过诸如glBindBuffers,glGenBuffers等之类的东西。我也不理解这些东西,或者我是否需要它们,因此出现了问题。
glVertexAttribPointer(index, size, type, normalized, stride, pointer);
此函数采用当前绑定的GL_VERTEX_BUFFER
并告诉opengl在指定index
处的哪里可以找到顶点属性的数据
特别是points
是从缓冲区开始的偏移量,如果绑定了默认缓冲区0,则它引用程序存储器,在这种情况下,它指向points
组
type
表示缓冲区中二进制数据的类型, size
是单个顶点中有多少个数据元素, normalized
告诉opengl是否映射整数值是否需要映射到0.0-1.0
EDIT更新程序以显示随时间变化的数据
下面的程序从OpenGL 3.2+中的数组生成一个带有旋转白色矩形的窗口:
除了几个glBind...(0)
调用之外,该示例是最少的-不幸的是,以OpenGL中的“新”方式绘制简单的东西非常glBind...(0)
。
#include "gl2stuff.h"
int main()
{
if (!glfwInit())
return -1;
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,2);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT,GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window(glfwCreateWindow(200,150,"", NULL,NULL));
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
glewInit();
// points for a 2D rectangle
GLfloat points[]={-0.5,-0.5,0.5,-0.5,0.5,0.5,-0.5,0.5,-0.5,-0.5};
GLfloat nPoints=5;
/* vertex shader: read an array of 2D-points
in the input attribute "vertex" and just pass
them on as your position in the [-1,1]x[-1,1]x[-1,1]
viewing volume
*/
const char* vShader =
"#version 150 core\n"
"in vec2 vertex;"
"void main() {gl_Position = vec4(vertex,0,1);}";
/* fragment shader:
draw everything in white
*/
const char* fShader =
"#version 150 core\n"
"out vec4 color;"
"void main() {color=vec4(1,1,1,1);}";
/* create an OpenGL program, compile the shaders,
attach them to the program and link
*/
GLuint program(glCreateProgram());
GLuint vertexShader(glCreateShader(GL_VERTEX_SHADER));
GLuint fragmentShader(glCreateShader(GL_FRAGMENT_SHADER));
glShaderSource(vertexShader, 1, &vShader, NULL);
glCompileShader(vertexShader);
glAttachShader(program, vertexShader);
glShaderSource(fragmentShader, 1, &fShader, NULL);
glCompileShader(fragmentShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
/* create a vertex buffer object (VBO)
for your data and transfer the data
from host memory to GPU memory
*/
GLuint vBuffer;
glGenBuffers(1,&vBuffer);
glBindBuffer(GL_ARRAY_BUFFER,vBuffer);
glBufferData(GL_ARRAY_BUFFER,sizeof(points),points,GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER,0);
// generate vertex array object (VAO)
GLuint vertexArray;
glGenVertexArrays(1,&vertexArray);
/* enable attribute array for "vertex" in your
shader and bind vBuffer to it; a VAO must
be bound while doing this (this stores the
the information about the vertex attributes;
you can conveniently switch between multiple
VAOs, but you need at least one)
*/
glBindVertexArray(vertexArray);
GLuint vertexLocation(GLuint(glGetAttribLocation(program,"vertex")));
glEnableVertexAttribArray(vertexLocation);
glBindBuffer(GL_ARRAY_BUFFER,vBuffer);
glVertexAttribPointer(vertexLocation, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)0 );
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindVertexArray(0);
/* finally we are ready to draw;
before drawing, make sure you call glUseProgram()
and bind the correct VAO. If there is only one
program and/or VAO it's ok if you just do these once
before you enter your drawing loop
*/
glUseProgram(program);
glBindVertexArray(vertexArray);
while(true)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_LINE_STRIP, 0, nPoints);
glfwSwapBuffers(window);
// modify data and update buffer
double t(glfwGetTime());
points[0]=cos(t)*0.5;points[1]=sin(t)*0.5;
points[2]=cos(t+1.57)*0.5;points[3]=sin(t+1.57)*0.5;
points[4]=cos(t+3.14)*0.5;points[5]=sin(t+3.14)*0.5;
points[6]=cos(t+4.71)*0.5;points[7]=sin(t+4.71)*0.5;
glBindBuffer(GL_ARRAY_BUFFER,vBuffer);
glBufferData(GL_ARRAY_BUFFER,sizeof(points),points,GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER,0);
}
glBindVertexArray(0);
return 0;
}
请注意,该程序仅用于说明。 通常,您将时间统一传递给着色器,然后让着色器处理旋转!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.