OpenGL着色器可以拉伸几何体

时间:2015-04-20 09:52:09

标签: c++ opengl shader

我创建了一个呈现四元组的简单程序

初始化:

Math::float3 vertices[4];
vertices[0] = Math::float3(-0.5f, 0.5f, -1.0f);
vertices[1] = Math::float3(-0.5f, -0.5f, -1.0f);
vertices[2] = Math::float3(0.5f, -0.5f, -1.0f);
vertices[3] = Math::float3(0.5f, 0.5f, -1.0f);

glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

unsigned int indices[] = {
               0, 1, 2,
               2, 3, 0
            };

glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

渲染:

glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(Math::float3), 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

glDisableVertexAttribArray(0);

它呈现完美的方形四边形。

我继续添加顶点着色器程序:

顶点着色器

layout (location = 0) in vec3 Position;

void main(){
    gl_Position = vec4(Position.x, Position.y, Position.z, 1.0);
}

片段着色器

out vec4 FragColor;

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

如果我再次运行我的程序,四边形似乎在x轴上拉伸到大约两倍,并在Y上稍微拉伸。

没有着色器

without shaders

使用着色器

with shader

有什么可能导致这种情况的想法?如果您需要更多代码段或其他信息,请告诉我们:)

更新

一些额外的代码。

打开窗口/重塑

glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(0, 0);
glutInitWindowSize(SCREEN_WIDTH, SCREEN_HEIGHT);
glutCreateWindow(TITLE);

...

if(_h == 0) _h = 1;
float ratio = 1.0f * _w / _h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, _w, _h);
gluPerspective(45.0f, ratio, 1, 1000);
glMatrixMode(GL_MODELVIEW);

更新2

我的问题遗憾地仍然存在,这里有一些额外的信息:

我的geomatry:

Math::float3 vertices[4];
vertices[0] = Math::float3(-0.5, -0.5f, -1.0f);
vertices[1] = Math::float3(0.5f, -0.5f, -1.0f);
vertices[2] = Math::float3(0.5f, 0.5f, -1.0f);
vertices[3] = Math::float3(-0.5f, 0.5f, -1.0f);

unsigned int indices[] = { 0, 1, 2, 2, 3, 0 };

我的顶点着色器

#version 330

layout (location = 0) in vec3 Position;

uniform mat4 MVP;

void main()
{
  gl_Position = MVP * vec4(Position.x, Position.y, Position.z, 1.0);
}

设置视图

#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600

#define FOV 60.0f
#define RATIO 1.0f * SCREEN_WIDTH / SCREEN_HEIGHT
#define ZNEAR 1.0f
#define ZFAR 1000.0f

if(_h == 0) _h = 1;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, _w, _h);
gluPerspective(FOV, RATIO, ZNEAR, ZFAR);
glMatrixMode(GL_MODELVIEW);

初始化

Math::float3 vertices[4];
vertices[0] = Math::float3(-0.5, -0.5f, -1.0f);
vertices[1] = Math::float3(0.5f, -0.5f, -1.0f);
vertices[2] = Math::float3(0.5f, 0.5f, -1.0f);
vertices[3] = Math::float3(-0.5f, 0.5f, -1.0f);

glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices,      GL_STATIC_DRAW);

unsigned int indices[] = { 0, 1, 2, 2, 3, 0 };

glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

sl = new Loader::ShaderLoader();
sl->Initialize();
sl->AddShader("data/shaders/shader.vs", VERTEX_SHADER);
sl->AddShader("data/shaders/shader.fs", FRAGMENT_SHADER);

sl->CompileShaders();   

渲染

MVP = glGetUniformLocation(sl->GetShaderProgram(), "MVP");

float m[16];

f -= 0.01f;

m[0] = 1.0f;
m[1] = 0.0f;
m[2] = 0.0f;
m[3] = 0.0f;

m[4] = 0.0f;
m[5] = 1.0f;
m[6] = 0.0f;
m[7] = 0.0f;

m[8] = 0.0f;
m[9] = 0.0f;
m[10] = 1.0f;
m[11] = 0.0f;

m[12] = 0.0f;
m[13] = 0.0f;
m[14] = 0.0f;
m[15] = 1.0f;

glUniformMatrix4fv(MVP, 1, GL_TRUE, m);

glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

glDisableVertexAttribArray(0);

我还为每次渲染调用打印了MVP的值,并且由于某种原因它始终为0。

再次欢迎任何其他提示,谢谢!

2 个答案:

答案 0 :(得分:1)

很可能您使用固定功能设置了非身份转换链(非身份投影和/或模型视图矩阵)。使用着色器时,不使用固定函数矩阵,这可以解释差异。

答案 1 :(得分:1)

这是由OpenGL中PVM(投影视图模型)矩阵的不同方法引起的。在固定管道中,该矩阵由函数glMatrixMode定义。

使用着色器时,这些矩阵通常会发送到顶点着色器,并在此处理。

您的顶点着色器将是这样的:

in vec3 Position;
uniform mat4 Projection;
uniform mat4 View;
uniform mat4 Model;

void main(){
    gl_Position = Projection * View * Model * vec4(Position.x, Position.y, Position.z, 1.0);
}

这应该提供有关这三个矩阵的更多信息:Tutorial 3 matrices