OpenGL网格错误的位置
Posted
技术标签:
【中文标题】OpenGL网格错误的位置【英文标题】:OpenGL Mesh Wrong Position 【发布时间】:2014-07-30 12:07:19 【问题描述】:我正在尝试创建一个简单的三角形网格,在弄清楚为什么我只是得到一个白屏(由于某种原因 x64 配置给我带来了问题)之后,我面临一个新问题:
我的顶点的位置并不是我想要的。我不知道为什么。 我应该得到的是一个看起来像这样的三角形:
我得到的是:
我使用 GLEW 1.10.0 加载 OpenGL,使用 GLM 0.9.5.4 加载 OpenGL 数学内容,使用 SDL 2.0.3 加载窗口内容。在 Visual Studio 2013 Ultimate 中运行在 Windows 8.1 上的所有内容,并带有最新的 Nvidia 图形驱动程序。
Main.cpp:
#include "Display.h"
#include "Shader.h"
#include "Mesh.h"
using namespace std;
int main(int argc, char** argv)
Display display(1200, 800, "Hello World");
Vertex vertecies[] =
Vertex(vec3(-0.5, -0.5, 0)),
Vertex(vec3(0.5, -0.5, 0)),
Vertex(vec3(0, 0.5, 0))
;
Mesh mesh(vertecies, sizeof(vertecies) / sizeof(vertecies[0]));
Shader shader(".\\res\\BasicShader");
while (!display.IsClosed())
display.Clear(1.0f, 1.0f, 1.0f, 1.0f);
shader.Bind();
mesh.Draw();
display.Update();
return 0;
Mesh.cpp:
#include "Mesh.h"
Mesh::Mesh(Vertex* vertecies, unsigned int numVertecies)
m_drawCount = numVertecies;
glGenVertexArrays(1, &m_vertexArrayObject);
glBindVertexArray(m_vertexArrayObject);
glGenBuffers(NUM_BUFFERS, m_vertexArrayBuffers);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexArrayBuffers[POSITION_VB]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertecies[0]) * numVertecies, vertecies, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const void*)offsetof(Vertex, m_pos));
glBindVertexArray(0);
Mesh::~Mesh()
glDeleteBuffers(NUM_BUFFERS, m_vertexArrayBuffers);
glDeleteVertexArrays(1, &m_vertexArrayObject);
void Mesh::Draw()
glBindVertexArray(m_vertexArrayObject);
glDrawArrays(GL_TRIANGLES, 0, m_drawCount);
glBindVertexArray(0);
Display.cpp:
#include "Display.h"
Display::Display(int width, int height, string title)
SDL_Init(SDL_INIT_EVERYTHING);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
m_window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL);
m_glContext = SDL_GL_CreateContext(m_window);
m_isClosed = false;
GLenum status = glewInit();
if (status != GLEW_OK)
cerr << "Could not initialize GLEW!" << endl;
Display::~Display()
SDL_GL_DeleteContext(m_glContext);
SDL_DestroyWindow(m_window);
SDL_Quit();
void Display::Clear(float r, float g, float b, float a)
glClearColor(r, g, b, a);
glClear(GL_COLOR_BUFFER_BIT);
bool Display::IsClosed()
return m_isClosed;
void Display::Update()
SDL_GL_SwapWindow(m_window);
SDL_Event e;
while (SDL_PollEvent(&e))
if (e.type == SDL_QUIT)
m_isClosed = true;
顶点着色器:
#version 420 core
layout(location = 0) in vec3 position;
void main()
gl_Position = vec4(position, 1.0);
片段着色器:
#version 420 core
out vec4 frag;
void main()
frag = vec4(1.0, 0.0, 0.0, 1.0);
Vertex.h:
#pragma once
#include <glm\glm.hpp>
using namespace glm;
struct Vertex
public:
Vertex(const vec3& pos);
virtual ~Vertex();
vec3 m_pos;
;
Vertex.cpp:
#include "Vertex.h"
Vertex::Vertex(const vec3& pos)
m_pos = pos;
Vertex::~Vertex()
编辑:现在一切都已修复。
【问题讨论】:
您的 Vertex 类/结构是如何布局的?你能发布它的声明吗? @kolrabi 当然,刚刚添加了 Vertex.h 和 Vertex.cpp... 你不应该修正你的答案 【参考方案1】:这可能是一个数据对齐问题,您的 Vertex 类是padded。然后,OpenGL 会将填充字节解释为有效数据。
您可以通过打印sizeof(Vertex)
的结果来验证这一点,如果它确实是填充的,那么它将是 8(您提到的是 64 平台)。
这告诉 OpenGL 在内存中有紧密封装的浮点数,没有填充:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
设置顶点指针的更好方法是:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const void*)offsetof(Vertex, m_pos));
这也使您可以轻松添加更多属性。
【讨论】:
感谢您的快速答复!它终于奏效了!唯一的问题是offsetof
有 2 个参数,一个类型和一个类型的成员,所以我只是把我的 Vertex 类变成了一个结构,将 m_pos
设为公共并写了 (const void*)offsetof(Vertex, m_pos)
而不是 (const void*)offsetof(Vertex.m_pos)
。跨度>
啊,是的,对不起,这是我的错字。以上是关于OpenGL网格错误的位置的主要内容,如果未能解决你的问题,请参考以下文章