gpt4 book ai didi

c++ - glDrawArrays 意外行为

转载 作者:太空狗 更新时间:2023-10-29 20:25:49 27 4
gpt4 key购买 nike

我在 openGL 的固定流水线上花了很多时间,最近开始学习可编程流水线。我认识我的画家,着色器类不是问题,因为它们使用固定功能管道的东西。我似乎无法让 glDrawArrays 为我的生活工作。

我不确定我的错误是在我设置顶点缓冲区对象的方式上,在我的着色器中还是在其他地方。我还调试了我的代码并在整个显示函数中设置了断点,它似乎永远不会通过 glDrawArrays(),(即它在 glDrawArrays 处遇到断点,但之后没有遇到任何断点,不知道为什么。)

输出的只是一个白屏,没有别的。

这是我的代码:

float   vertices[] = {   0.75,  0.75, 0.0, 1.0,
0.75, -0.75, 0.0, 1.0,
-0.75, -0.75, 0.0, 1.0 };

GLuint vertexBufferObject;
GLuint positionLocation;
GLuint vaoObject;

void initVertexBuffer(GLuint& vertexBufferObject, float* vertexData, unsigned int size, GLenum GL_DRAW_TYPE)
{
glGenBuffers(1, &vertexBufferObject);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, size, vertexData, GL_DRAW_TYPE);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}

void main(int argc, char* argv[])
{

painter.initEngine(argc, argv, 500, 500, 0, 0, "2D3D");
painter.initGlutFuncs(display, resize, Input::MouseButtonClick, Input::MouseDrag, keyboard);

defaultShader.init("default.vert", "default.frag");
defaultShader.link();

initVertexBuffer(vertexBufferObject, vertices, sizeof(vertices), GL_STATIC_DRAW);
glGenVertexArrays(1, &vaoObject);
glBindVertexArray(vaoObject);
positionLocation = glGetAttribLocation(defaultShader.id(), "position");

painter.startMainLoop();
}

void display()
{
painter.clearDisplay();

defaultShader.bind();

glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glEnableVertexAttribArray(positionLocation);
glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);
std::cout << Framework::glErrorCheck() << std::endl;

glDrawArrays(GL_TRIANGLES, 0, 3);

glDisableVertexAttribArray(positionLocation);
glBindBuffer(GL_ARRAY_BUFFER, 0);
defaultShader.unbind();

painter.flushAndSwapBuffers();
}

顶点着色器:

#version 140

in vec4 position;

void main()
{
gl_Position = position;
}

片段着色器:

#version 140

out vec4 outColor;

void main()
{
outColor = vec4(1.0, 0.0, 1.0, 1.0);
}

编辑:根据 Joey Dewd、keltar 和 genpfault 的建议更新了代码。 我不再卡在 glDrawArrays 上,即我得到的不是白屏,而是黑屏。这让我认为我的缓冲区在某种程度上仍然没有正确设置。或者,我可能遗漏了顶点数组缓冲区初始化 (vaoObject) 所需的其他内容?

最佳答案

void initVertexBuffer(GLuint vertexBufferObject, float* vertexData, GLenum GL_DRAW_TYPE)
{
glGenBuffers(1, &vertexBufferObject);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_DRAW_TYPE);
^^^^^^^^^^^^^^^^^^ nnnnope
glBindBuffer(GL_ARRAY_BUFFER, 0);
}

sizeof(vertexData) in this context is not what you seem to hope it is .

它可能是 4 或 8,具体取决于您的 64 位版本。即,sizeof 是一个指向 float 的指针。 不是 sizeof(vertices)

您需要传入一个单独的尺寸参数:

void initVertexBuffer(GLuint& vertexBufferObject, float* vertexData, unsigned int size, GLenum GL_DRAW_TYPE)
{
glGenBuffers(1, &vertexBufferObject);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, size, vertexData, GL_DRAW_TYPE);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}

...

void main(int argc, char* argv[])
{
...
initVertexBuffer(vertexBufferObject, vertices, sizeof(vertices), GL_STATIC_DRAW);
...
}

或者像 std::vector 这样的连续(重要!)标准容器:

template< typename Container >
void initVertexBuffer(GLuint& vertexBufferObject, const Container& vertexData, GLenum GL_DRAW_TYPE)
{
glGenBuffers(1, &vertexBufferObject);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, vertexData.size() * sizeof( typename Container::value_type ), &vertexData[0], GL_DRAW_TYPE);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}

完整示例:

#include <GL/glew.h>
#include <GL/freeglut.h>

#include <iostream>
#include <vector>
using namespace std;

struct Program
{
static GLuint Load( const char* vert, const char* geom, const char* frag )
{
GLuint prog = glCreateProgram();
if( vert ) AttachShader( prog, GL_VERTEX_SHADER, vert );
if( geom ) AttachShader( prog, GL_GEOMETRY_SHADER, geom );
if( frag ) AttachShader( prog, GL_FRAGMENT_SHADER, frag );
glLinkProgram( prog );
CheckStatus( prog );
return prog;
}

private:
static void CheckStatus( GLuint obj )
{
GLint status = GL_FALSE;
if( glIsShader(obj) ) glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
if( glIsProgram(obj) ) glGetProgramiv( obj, GL_LINK_STATUS, &status );
if( status == GL_TRUE ) return;
GLchar log[ 1 << 15 ] = { 0 };
if( glIsShader(obj) ) glGetShaderInfoLog( obj, sizeof(log), NULL, log );
if( glIsProgram(obj) ) glGetProgramInfoLog( obj, sizeof(log), NULL, log );
std::cerr << log << std::endl;
exit( -1 );
}

static void AttachShader( GLuint program, GLenum type, const char* src )
{
GLuint shader = glCreateShader( type );
glShaderSource( shader, 1, &src, NULL );
glCompileShader( shader );
CheckStatus( shader );
glAttachShader( program, shader );
glDeleteShader( shader );
}
};

#define GLSL(version, shader) "#version " #version "\n" #shader


void initVertexBuffer(GLuint& vertexBufferObject, float* vertexData, unsigned int size, GLenum GL_DRAW_TYPE)
{
glGenBuffers(1, &vertexBufferObject);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, size, vertexData, GL_DRAW_TYPE);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}

GLuint prog;
GLuint vaoObject;
void init()
{
const char* vert = GLSL
(
140,
in vec4 position;
void main()
{
gl_Position = position;
}
);

const char* frag = GLSL
(
140,
out vec4 outColor;
void main()
{
outColor = vec4(1.0, 0.0, 1.0, 1.0);
}
);

prog = Program::Load( vert, NULL, frag );
glUseProgram( prog );

glGenVertexArrays(1, &vaoObject);
glBindVertexArray(vaoObject);

float vertices[] =
{
0.75, 0.75, 0.0, 1.0,
0.75, -0.75, 0.0, 1.0,
-0.75, -0.75, 0.0, 1.0
};
GLuint vertexBufferObject;
initVertexBuffer(vertexBufferObject, vertices, sizeof(vertices), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);

GLuint positionLocation = glGetAttribLocation(prog, "position");
glEnableVertexAttribArray(positionLocation);
glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);
}

void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glUseProgram( prog );
glBindVertexArray(vaoObject);
glDrawArrays(GL_TRIANGLES, 0, 3);

glutSwapBuffers();
}

int main(int argc, char **argv)
{
glutInit( &argc, argv );
glutInitContextVersion( 3, 1 );
glutInitContextProfile( GLUT_COMPATIBILITY_PROFILE );
glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
glutInitWindowSize( 600, 600 );
glutCreateWindow( "GLUT" );

glewExperimental = GL_TRUE;
glewInit();

init();

glutDisplayFunc( display );
glutMainLoop();
return 0;
}

关于c++ - glDrawArrays 意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22598820/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com