我正在尝试使用OpenGL来构建一些渲染软件,我过去已经使用过OpenGL,但是我找不到我的代码错误的地方。所以我已经实现了:
这是我的网格类函数和构造函数的初始化和显示:
$ python3
Python 3.6.6 (default, Sep 12 2018, 18:26:19)
[GCC 8.0.1 20180414 (experimental) [trunk revision 259383]] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlite3
>>> sqlite3.version
'2.6.0'
>>> sqlite3.sqlite_version
'3.22.0'
这是我的渲染循环查看器..:
Mesh::Mesh(char* meshSource)
{
//Creation d'un triangle pour quelques debug...
struct Vertex v0;
struct Vertex v1;
struct Vertex v2;
//Position local
v0.coord = vec3(-1.0f,-1.0f,0.0f);
v1.coord = vec3(1.0f,-1.0f,0.0f);
v2.coord = vec3(0.0f,1.0f,0.0f);
//Coouleur des points
v0.color = vec3(1.0,0.0,0.0);
v1.color = vec3(0.0,1.0,0.0);
v2.color = vec3(0.0,0.0,1.0);
//normals des points
v0.normal = vec3(0.0,0.0,-1.0);
v1.normal = vec3(0.0,0.0,-1.0);
v2.normal = vec3(0.0,0.0,-1.0);
Vertices.push_back(v0);
Vertices.push_back(v1);
Vertices.push_back(v2);
//sert a la premiere initialisation...
_ready = false;
}
void Mesh::init(Shader *_shader)
{
glGenVertexArrays(1,&_vao);
glGenBuffers(1,&_vbo);
checkGLError();
//bind des caracteristiques du mesh...
glBindVertexArray(_vao);
glBindBuffer(GL_ARRAY_BUFFER,_vbo);
checkGLError();
//On donne nos données au VBO.
glBufferData(GL_ARRAY_BUFFER, sizeof(vec3) * Vertices.size(), Vertices.data(), GL_STATIC_DRAW);
checkGLError();
int vertex_loc = _shader->getAttribLocation("V_position");
std::cout << "vertex_loc = " << vertex_loc << std::endl;
if(vertex_loc>=0)
{
glEnableVertexAttribArray(vertex_loc);
glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
}
int color_loc = _shader->getAttribLocation("V_color");
std::cout << "color_loc = " << color_loc << std::endl;
if(color_loc>=0)
{
glEnableVertexAttribArray(color_loc);
glVertexAttribPointer(color_loc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)sizeof(vec3));
}
int normal_loc = _shader->getAttribLocation("V_normal");
std::cout << "normal_loc = " << normal_loc << std::endl;
if(normal_loc>=0)
{
glEnableVertexAttribArray(normal_loc);
glVertexAttribPointer(normal_loc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(2*sizeof(vec3)));
}
if(vertex_loc>=0)
glDisableVertexAttribArray(vertex_loc);
if(color_loc>=0)
glDisableVertexAttribArray(color_loc);
if(normal_loc>=0)
glDisableVertexAttribArray(normal_loc);
glBindVertexArray(0);
this->_ready = true;
}
void Mesh::draw(Shader *_shader)
{
if(!_ready)
{
init(_shader);
std::cout << "Initialisation du mesh terminer" << std::endl;
}
glBindVertexArray(_vao);
glDrawArrays(GL_TRIANGLE_STRIP, 0,3);
glBindVertexArray(0);
}
和我的main.cpp
void S2Viewer::runLoop()
{
/* Loop until the user closes the window */
glClearColor(1.0, 1.0, 1.0, 0.0);
glEnable (GL_DEPTH_TEST);
while (!glfwWindowShouldClose(_S2viewer))
{
Shaders[0]->use();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for (std::vector<Mesh*>::iterator mesh = Meshs.begin(); mesh < Meshs.end(); mesh++)
{
(*mesh)->draw(Shaders[0]);
}
glfwSwapBuffers(_S2viewer);
glfwPollEvents();
Shaders[0]->desactivate();
}
glfwTerminate();
}
这里是我的顶点着色器:
int main(int argc,char** argv)
{
std::cout << "Hello fuck**g World" <<std::endl;
S2Viewer viewer;
viewer.init();
//initialisation des shaders et des mesh...
Mesh mesh = Mesh("mesh");
Shader shader("/Users/benz/Documents/projPerso/Moteur_S2_Engine/data/shader/simple.vert","/Users/benz/Documents/projPerso/Moteur_S2_Engine/data/shader/simple.frag");
viewer.addMesh(&mesh);
viewer.addShader(&shader);
viewer.runLoop();
}
这是我的片段着色器:
#version 410 core
layout(location = 0) in vec3 V_position;
layout(location = 1) in vec3 V_color;
layout(location = 2) in vec3 V_normal;
void main()
{
gl_Position = vec4(V_position, 1.);
}
当我运行我的代码时,它可以完美编译,但是什么也不显示。 问题并非来自着色器,因为我过去在以前的软件中使用过我的类着色器。 再加上glGetError不显示任何错误,我也不知道我的问题在哪里..
PS:我在macOS上
答案 0 :(得分:1)
启用顶点属性的状态存储在Vertex Array Object中。
在您的代码中启用了顶点属性,但是您又一次禁用了它们。最后,存储在顶点数组对象状态向量中的顶点属性的状态为“禁用”。
跳过禁用顶点属性
glBindVertexArray(_vao);
....
if(vertex_loc>=0)
{
glEnableVertexAttribArray(vertex_loc);
glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
}
....
if(vertex_loc>=0)
glDisableVertexAttribArray(vertex_loc); // <---- delete this
....
glBindVertexArray(0);
glBufferData
的第二个参数必须是整个缓冲区的大小(以字节为单位)。
您的缓冲区包含Vertices.size()
个元素,每个元素的大小为sizeof(Vertex)
,因此缓冲区大小(以字节为单位)为sizeof(Vertex) * Vertices.size()
:
glBufferData(GL_ARRAY_BUFFER,
sizeof(Vertex) * Vertices.size(), // <---- sizeof(Vertex) istead of sizeof(vec3)
Vertices.data(), GL_STATIC_DRAW);