【发布时间】:2015-05-03 17:11:01
【问题描述】:
我要学习 OpenGL 4,现在我使用纹理。我想将纹理应用到球体,我的顶点着色器如下所示:
#version 410
in vec4 vPosition;
in vec2 texCoord;
uniform mat4 mvpMatrix;
uniform mat4 mvMatrix;
uniform mat3 normalMatrix;
uniform vec3 vLightPosition;
smooth out vec3 vVaryingNormal;
smooth out vec3 vVaryingLightDir;
smooth out vec2 uvCoord;
void main (void)
{
uvCoord = texCoord;
vec3 vNormal = vPosition.xyz / vPosition.w;
vVaryingNormal = normalMatrix * vNormal;
vec4 vPosition4 = mvMatrix * vPosition;
vec3 vPosition3 = vPosition4.xyz / vPosition4.w;
vVaryingLightDir = normalize(vLightPosition - vPosition3);
gl_Position = mvpMatrix * vPosition;
}
定义球体的坐标和三角索引后,我使用以下代码构建了一个 VAO:
void SphereShaderProgram::BuildVAO()
{
// Generate and bind the vertex array object
glGenVertexArrays(1, &_vao);
glBindVertexArray(_vao);
// Generate and bind the vertex buffer object
glGenBuffers(1, &_vbo);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBufferData(GL_ARRAY_BUFFER, _sphereCoordinates.size() * sizeof(float), &_sphereCoordinates[0], GL_STATIC_DRAW);
// Generate and bind the index buffer object
glGenBuffers(1, &_ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, _sphereIndexes.size() * sizeof(unsigned int), &_sphereIndexes[0], GL_STATIC_DRAW);
// Generate and bind texture
_texture = LoadTexture("ball.bmp");
LoadAttributeVariables();
glBindVertexArray(0);
}
GLuint ProgramManager::LoadTexture(const char* imagepath)
{
unsigned int width, height;
unsigned char * data = LoadBMP(imagepath, &width, &height);
GLuint textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
return textureID;
}
为了加载属性,我做了以下(在使用纹理之前):
void SphereShaderProgram::LoadAttributeVariables()
{
// Vertex Attributes
GLuint VertexPosition_location = glGetAttribLocation(GetProgramID(), "vPosition");
glEnableVertexAttribArray(VertexPosition_location);
glVertexAttribPointer(VertexPosition_location, 3, GL_FLOAT, GL_FALSE, 0, 0);
}
但是,现在,我有一个数组 (_sphereTexCoords),其中包含纹理坐标,我真的不知道在传递顶点坐标时如何将它传递给顶点着色器。我必须创建另一个 VBO 吗?我虽然想做这样的事情:
GLuint TextureCoord_Location = glGetAttribLocation(GetProgramID(), "texCoord");
glEnableVertexAttribArray(TextureCoord_Location);
glVertexAttribPointer(TextureCoord_Location, 2, GL_FLOAT, GL_FALSE, 0, 0);
但我真的不知道如何指定这与_sphereTexCoords 数组有关。
编辑
我试过了,但是没用。
void SphereShaderProgram::BuildVAO()
{
// Generate and bind the vertex array object
glGenVertexArrays(1, &_vao);
glBindVertexArray(_vao);
// Generate and bind the vertex buffer object
glGenBuffers(2, _vbo);
glBindBuffer(GL_ARRAY_BUFFER, _vbo[0]);
glBufferData(GL_ARRAY_BUFFER, _sphereCoordinates.size() * sizeof(float), &_sphereCoordinates[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, _vbo[1]);
glBufferData(GL_ARRAY_BUFFER, _textureCoordinates.size() * sizeof(float), &_textureCoordinates[0], GL_STATIC_DRAW);
// Generate and bind the index buffer object
glGenBuffers(1, &_ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, _sphereIndexes.size() * sizeof(unsigned int), &_sphereIndexes[0], GL_STATIC_DRAW);
// Generate and bind texture
_texture = LoadTexture("ball.bmp");
LoadAttributeVariables();
glBindVertexArray(0);
}
void SphereShaderProgram::LoadAttributeVariables()
{
// Vertex Attributes
GLuint VertexPosition_location = glGetAttribLocation(GetProgramID(), "vPosition");
glEnableVertexAttribArray(VertexPosition_location);
glVertexAttribPointer(VertexPosition_location, 3, GL_FLOAT, GL_FALSE, 0, 0);
GLuint TextureCoord_Location = glGetAttribLocation(GetProgramID(), "texCoord");
glEnableVertexAttribArray(TextureCoord_Location);
glVertexAttribPointer(TextureCoord_Location, 2, GL_FLOAT, GL_FALSE, 0, 0);
}
绑定程序时出错。
【问题讨论】:
标签: c++ opengl textures shader