Наложение текстур с подсветкой фонг

Я пытаюсь добавить освещение Phong к моей сцене, в которой я загрузил меш с текстурами. Это мой класс загрузки нагрузки:

#define INVALID_OGL_VALUE 0xFFFFFFFF
#define INVALID_MATERIAL 0xFFFFFFFF
#define SAFE_DELETE(p) if (p) { delete p; p = NULL; }

Mesh::MeshEntry::MeshEntry()
{
VB = INVALID_OGL_VALUE;
IB = INVALID_OGL_VALUE;
NumIndices  = 0;
MaterialIndex = INVALID_MATERIAL;
};

Mesh::MeshEntry::~MeshEntry()
{
if (VB != INVALID_OGL_VALUE)
{
glDeleteBuffers(1, &VB);
}

if (IB != INVALID_OGL_VALUE)
{
glDeleteBuffers(1, &IB);
}
}

void Mesh::MeshEntry::Init(const std::vector<Vertex>& Vertices,
const std::vector<unsigned int>& Indices)
{
NumIndices = Indices.size();

glGenBuffers(1, &VB);
glBindBuffer(GL_ARRAY_BUFFER, VB);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * Vertices.size(), &Vertices[0], GL_STATIC_DRAW);

glGenBuffers(1, &IB);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IB);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * NumIndices, &Indices[0], GL_STATIC_DRAW);
}

Mesh::Mesh()
{
}Mesh::~Mesh()
{
Clear();
}void Mesh::Clear()
{
for (unsigned int i = 0 ; i < textures_cnt.size() ; i++) {
SAFE_DELETE(textures_cnt[i]);
}
}/*Loads mesh
*@Filename -   name of the .obj file
**********************************************************/
bool Mesh::LoadMesh(const std::string& Filename){

Assimp::Importer Importer;
bool rc = false;

//clear previous loaded mesh
Clear();

//read file content
const aiScene* oScene = Importer.ReadFile(Filename.c_str(), aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs );

if(oScene){

printf ("  %i animations\n", oScene->mNumAnimations);
printf ("  %i cameras\n", oScene->mNumCameras);
printf ("  %i lights\n", oScene->mNumLights);
printf ("  %i materials\n", oScene->mNumMaterials);
printf ("  %i meshes\n", oScene->mNumMeshes);
printf ("  %i textures\n", oScene->mNumTextures);

submeshes_cnt.resize(oScene->mNumMeshes);
textures_cnt.resize(oScene->mNumMaterials);

/*.........Initialize the meshes in the scene one by one...........*/
for (unsigned int i = 0 ; i < submeshes_cnt.size() ; i++) {

const aiMesh* paiMesh = oScene->mMeshes[i];
InitMesh(i, paiMesh);
}

// Extract the directory part from the file name
std::string::size_type SlashIndex = Filename.find_last_of("/");
std::string Dir;

if (SlashIndex == std::string::npos) {
Dir = ".";
}
else if (SlashIndex == 0) {
Dir = "/";
}
else {
Dir = Filename.substr(0, SlashIndex);
}
/*.................Initialization of meshes end....................*//*.............Initialize the materials.............................*/
for(unsigned int i = 0 ; i < oScene->mNumMaterials ; i++) {
const aiMaterial* pMaterial = oScene->mMaterials[i];

textures_cnt[i] = NULL;

if (pMaterial->GetTextureCount(aiTextureType_DIFFUSE) > 0) {
aiString Path;

if (pMaterial->GetTexture(aiTextureType_DIFFUSE, 0, &Path, NULL, NULL, NULL, NULL, NULL) == AI_SUCCESS) {
std::string FullPath = Dir + "/" + Path.data;
textures_cnt[i] = new Texture(GL_TEXTURE_2D, FullPath.c_str());

if (!textures_cnt[i]->Load()) {
printf("Error loading texture '%s'\n", FullPath.c_str());
delete textures_cnt[i];
textures_cnt[i] = NULL;
rc = false;
}
else {
printf("Loaded texture '%s'\n", FullPath.c_str());
}
}
}
}
/*.................Initialization of materials end....................*/
}
else {
printf("Error parsing '%s': '%s'\n", Filename.c_str(), Importer.GetErrorString());
}

return rc;
}void Mesh::InitMesh(unsigned int Index, const aiMesh* paiMesh)
{
submeshes_cnt[Index].MaterialIndex = paiMesh->mMaterialIndex;

std::vector<Vertex> Vertices;
std::vector<unsigned int> Indices;

const aiVector3D Zero3D(0.0f, 0.0f, 0.0f);

for (unsigned int i = 0 ; i < paiMesh->mNumVertices ; i++) {
const aiVector3D* pPos      = &(paiMesh->mVertices[i]);
const aiVector3D* pNormal   = &(paiMesh->mNormals[i]);
const aiVector3D* pTexCoord = paiMesh->HasTextureCoords(0) ? &(paiMesh->mTextureCoords[0][i]) : &Zero3D;

Vertex v(Vector3f(pPos->x, pPos->y, pPos->z),
Vector2f(pTexCoord->x, pTexCoord->y),
Vector3f(pNormal->x, pNormal->y, pNormal->z));

Vertices.push_back(v);
}

for (unsigned int i = 0 ; i < paiMesh->mNumFaces ; i++) {
const aiFace& Face = paiMesh->mFaces[i];
assert(Face.mNumIndices == 3);
Indices.push_back(Face.mIndices[0]);
Indices.push_back(Face.mIndices[1]);
Indices.push_back(Face.mIndices[2]);
}

submeshes_cnt[Index].Init(Vertices, Indices);
}

void Mesh::Render(){

//enable VAOs for vertices, normals, textures
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);

for(unsigned int i = 0 ; i < submeshes_cnt.size() ; i++){

glBindBuffer(GL_ARRAY_BUFFER, submeshes_cnt[i].VB);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)12);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)20);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, submeshes_cnt[i].IB);

const unsigned int MaterialIndex = submeshes_cnt[i].MaterialIndex;

if (MaterialIndex < textures_cnt.size() && textures_cnt[MaterialIndex]) {
textures_cnt[MaterialIndex]->Bind(GL_TEXTURE0);
}

glDrawElements(GL_TRIANGLES, submeshes_cnt[i].NumIndices, GL_UNSIGNED_INT, 0);
}

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);}

вершинный шейдер:

#version 420

uniform mat4 camera;
uniform mat4 model;

in vec3 vert;
in vec2 vertTexCoord;

out vec2 fragTexCoord;

void main() {
// Pass the tex coord straight through to the fragment shader
fragTexCoord = vertTexCoord;

// Apply all matrix transformations to vert
gl_Position = camera * model * vec4(vert, 1);
}

фрагментный шейдер:

#version 420

uniform sampler2D tex;

in vec2 fragTexCoord;

out vec4 finalColor;

void main() {
//note: the texture function was called texture2D in older versions of GLSL
finalColor = texture(tex, fragTexCoord);
}

вот что я получаю:
до

но когда я пытаюсь добавить освещение фонг, когда я добавляю атрибут для нормалей в мой вершинный шейдер, это то, что я получаю:
после

В чем проблема?
Спасибо за помощь.

//редактировать
загрузка шейдера и ссылка

shprogram::shprogram(const std::vector<shader>& shaders) :
_object(0)
{
if(shaders.size() <= 0)
throw std::runtime_error("No shaders were provided to create the program");

//create the program object
_object = glCreateProgram();
if(_object == 0)
throw std::runtime_error("glCreateProgram failed");

//attach all the shaders
for(unsigned i = 0; i < shaders.size(); ++i)
glAttachShader(_object, shaders[i].getObject());

//link the shaders together
glLinkProgram(_object);

//detach all the shaders
for(unsigned i = 0; i < shaders.size(); ++i)
glDetachShader(_object, shaders[i].getObject());

//throw exception if linking failed
GLint status;
glGetProgramiv(_object, GL_LINK_STATUS, &status);
if (status == GL_FALSE) {
std::string msg("Program linking failure: ");

GLint infoLogLength;
glGetProgramiv(_object, GL_INFO_LOG_LENGTH, &infoLogLength);
char* strInfoLog = new char[infoLogLength + 1];
glGetProgramInfoLog(_object, infoLogLength, NULL, strInfoLog);
msg += strInfoLog;
delete[] strInfoLog;

glDeleteProgram(_object); _object = 0;
throw std::runtime_error(msg);
}
}

shprogram::~shprogram() {
//might be 0 if ctor fails by throwing exception
if(_object != 0) glDeleteProgram(_object);
}

GLuint shprogram::object() const {
return _object;
}

void shprogram::use() const {
glUseProgram(_object);
}

bool shprogram::isInUse() const {
GLint currentProgram = 0;
glGetIntegerv(GL_CURRENT_PROGRAM, &currentProgram);
return (currentProgram == (GLint)_object);
}

void shprogram::stopUsing() const {
assert(isInUse());
glUseProgram(0);
}

GLint shprogram::attrib(const GLchar* attribName) const {
if(!attribName)
throw std::runtime_error("attribName was NULL");

GLint attrib = glGetAttribLocation(_object, attribName);
if(attrib == -1)
throw std::runtime_error(std::string("Program attribute not found: ") + attribName);

return attrib;
}

GLint shprogram::uniform(const GLchar* uniformName) const {
if(!uniformName)
throw std::runtime_error("uniformName was NULL");

GLint uniform = glGetUniformLocation(_object, uniformName);
if(uniform == -1)
throw std::runtime_error(std::string("Program uniform not found: ") + uniformName);

return uniform;
}

void shprogram::setUniformMatrix2(const GLchar* name, const GLfloat* v, GLsizei count, GLboolean transpose) {
assert(isInUse());
glUniformMatrix2fv(uniform(name), count, transpose, v);
}

void shprogram::setUniformMatrix3(const GLchar* name, const GLfloat* v, GLsizei count, GLboolean transpose) {
assert(isInUse());
glUniformMatrix3fv(uniform(name), count, transpose, v);
}

void shprogram::setUniformMatrix4(const GLchar* name, const GLfloat* v, GLsizei count, GLboolean transpose) {
assert(isInUse());
glUniformMatrix4fv(uniform(name), count, transpose, v);
}

void shprogram::setUniform(const GLchar* name, const glm::mat2& m, GLboolean transpose) {
assert(isInUse());
glUniformMatrix2fv(uniform(name), 1, transpose, glm::value_ptr(m));
}

void shprogram::setUniform(const GLchar* name, const glm::mat3& m, GLboolean transpose) {
assert(isInUse());
glUniformMatrix3fv(uniform(name), 1, transpose, glm::value_ptr(m));
}

void shprogram::setUniform(const GLchar* name, const glm::mat4& m, GLboolean transpose) {
assert(isInUse());
glUniformMatrix4fv(uniform(name), 1, transpose, glm::value_ptr(m));
}

void shprogram::setUniform(const GLchar* uniformName, const glm::vec3& v) {
setUniform3v(uniformName, glm::value_ptr(v));
}

void shprogram::setUniform(const GLchar* uniformName, const glm::vec4& v) {
setUniform4v(uniformName, glm::value_ptr(v));
}

настройка униформы

//bind shader program
gProgram->use();

//set the "camera" uniform
gProgram->setUniform("camera", gCamera.matrix());

//set the "model" uniform in the vertex shader, based on the gDegreesRotated global
gProgram->setUniform("model", glm::rotate(glm::mat4(), 150.0f ,glm::vec3(0,1,0)));gProgram->setUniform("light.position", gLight.position);
gProgram->setUniform("light.intensities", gLight.intensities);

0

Решение

Вы ни явно не устанавливаете местоположения атрибутов в источнике шейдера, ни связываете их перед связыванием шейдера, ни запрашиваете их. GL может свободно использовать любой допустимый индекс атрибута для любого активного входного атрибута.

Ты только предполагать 0 — позиция, 1 — текстовая координата, а 2 — нормальная. Для случая position + texcoord это может сработать случайно, но при добавлении нормали все индексы могут быть перепутаны. Либо использовать layout(location=...) (увидеть GL_ARB_explicit_attrib_location для деталей) в коде GLSL, или используйте glBindAttribLocation() указать отображение, которое вы хотите.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]