c++ - Only one side texturing of Sphere -
i trying render sphere using opengl, assimp, glfw, glad, , glm. seems import vertices correctly , finds textures 1 side of sphere textured on outside , 1 side of sphere textured on inside. don't know causing because of how new , because texture render on both sides of shapes. disabled face culling (or whatever called) see if problem after searching answer , changed nothing.
here outside right side:
here inside view (all did walk forward):
there seems weird bugs of faces on sphere being textured incorrectly don't know if have problem.
i should mention used blender make uvmap sphere , saved .obj
edit:
sorry not being specific enough. didn't neccessarily know information necessary. don't use glcullface. these texture parameters have set:
gltexparameteri(gl_texture_2d, gl_texture_wrap_s, gl_repeat); gltexparameteri(gl_texture_2d, gl_texture_wrap_t, gl_repeat); gltexparameteri(gl_texture_2d, gl_texture_min_filter, gl_linear_mipmap_linear); gltexparameteri(gl_texture_2d, gl_texture_mag_filter, gl_linear);
i'll working on isolating problem post code isn't such mess (mine sadly) in case necessary when comes textures , loading .obj file followed tutorial on learnopengl.com closely code loading same.
in case want though there classes involved.
model.cpp:
#pragma once #include <iostream> #include <shader.h> #include <mesh.h> #include <vector> #include <string> #include <assimp\importer.hpp> #include <assimp\postprocess.h> #include <assimp\scene.h> #define stb_image_implementation #include <stb_image.h> unsigned int texturefromfile(const char * path, const std::string &directory, bool gamma = false); class model { public: model(char * path) { loadmodel(path); } void draw(shader shader); private: /* model data */ std::vector<mesh> meshes; std::string directory; /* functions */ void loadmodel(std::string path); void processnode(ainode *node, const aiscene *scene); mesh processmesh(aimesh *mesh, const aiscene *scene); std::vector<texture> loadmaterialtextures(aimaterial *mat, aitexturetype type, std::string typename); std::vector<texture> textures_loaded; }; void model::draw(shader shader) { (int = 0; < meshes.size(); i++) { meshes[i].draw(shader); } } void model::loadmodel(std::string path) { assimp::importer importer; const aiscene *scene = importer.readfile(path, aiprocess_triangulate | aiprocess_flipuvs); if (!scene || scene->mflags & ai_scene_flags_incomplete || !scene->mrootnode) { std::cout << "error::assimp::" << importer.geterrorstring() << std::endl; return; } directory = path.substr(0, path.find_last_of('/')); processnode(scene->mrootnode, scene); } void model::processnode(ainode *node, const aiscene *scene) { (unsigned int = 0; < node->mnummeshes; i++) { aimesh *mesh = scene->mmeshes[node->mmeshes[i]]; meshes.push_back(processmesh(mesh, scene)); } (unsigned int = 0; < node->mnumchildren; i++) { processnode(node->mchildren[i], scene); } } mesh model::processmesh(aimesh *mesh, const aiscene *scene) { std::vector<vertex> vertices; std::vector<unsigned int> indices; std::vector<texture> textures; (unsigned int = 0; < mesh->mnumvertices; i++) { vertex vertex; glm::vec3 vector; vector.x = mesh->mvertices[i].x; vector.y = mesh->mvertices[i].y; vector.z = mesh->mvertices[i].z; vertex.position = vector; vector.x = mesh->mnormals[i].x; vector.y = mesh->mnormals[i].y; vector.z = mesh->mnormals[i].z; vertex.normal = vector; if (mesh->mtexturecoords[i]) { std::cout << "texture coords found" << std::endl; std::cout << "texcoord equals (" << mesh->mtexturecoords[0][i].x << " , " << mesh->mtexturecoords[0][i].y << " )" << std::endl; glm::vec2 vec; vec.x = mesh->mtexturecoords[0][i].x; vec.y = mesh->mtexturecoords[0][i].y; vertex.texcoords = vec; } else vertex.texcoords = glm::vec2(0.0f, 0.0f); vertices.push_back(vertex); } (unsigned int = 0; < mesh->mnumfaces; i++) { aiface face = mesh->mfaces[i]; (unsigned int j = 0; j < face.mnumindices; j++) indices.push_back(face.mindices[j]); } if (mesh->mmaterialindex >= 0) { aimaterial * material = scene->mmaterials[mesh->mmaterialindex]; std::vector<texture> diffusemaps = loadmaterialtextures(material, aitexturetype_diffuse, "texture_diffuse"); textures.insert(textures.end(), diffusemaps.begin(), diffusemaps.end()); std::vector<texture> specularmaps = loadmaterialtextures(material, aitexturetype_specular, "texture_specular"); textures.insert(textures.end(), specularmaps.begin(), specularmaps.end()); } return mesh(vertices, indices, textures); } std::vector<texture> model::loadmaterialtextures(aimaterial * material, aitexturetype type, std::string typename) { std::vector<texture> textures; std::cout << material->gettexturecount(type) << " textures" << std::endl; (unsigned int = 0; < material->gettexturecount(type); i++) { std::cout << "getting textures" << std::endl; aistring str; material->gettexture(type, i, &str); bool skip = false; (unsigned int j = 0; j < textures_loaded.size(); j++) { if (std::strcmp(textures_loaded[j].path.c_str(), str.c_str()) == 0) { textures.push_back(textures_loaded[j]); skip = true; break; } } if (!skip) { texture texture; texture.id = texturefromfile(str.c_str(), directory); texture.type = typename; texture.path = str; textures.push_back(texture); textures_loaded.push_back(texture); } } return textures; } unsigned int texturefromfile(const char * path, const std::string &directory, bool gamma) { std::string filename = path; filename = directory + '/' + filename; std::cout << "filename = " << filename << std::endl; unsigned int textureid; glgentextures(1, &textureid); int width, height, nrchannels; unsigned char * data = stbi_load(filename.c_str(), &width, &height, &nrchannels, 0); if (data) { glenum format; if (nrchannels == 1) format = gl_red; else if (nrchannels == 3) format = gl_rgb; else if (nrchannels == 4) format == gl_rgba; glbindtexture(gl_texture_2d, textureid); glteximage2d(gl_texture_2d, 0, format, width, height, 0, format, gl_unsigned_byte, data); glgeneratemipmap(gl_texture_2d); gltexparameteri(gl_texture_2d, gl_texture_wrap_s, gl_repeat); gltexparameteri(gl_texture_2d, gl_texture_wrap_t, gl_repeat); gltexparameteri(gl_texture_2d, gl_texture_min_filter, gl_linear_mipmap_linear); gltexparameteri(gl_texture_2d, gl_texture_mag_filter, gl_linear); stbi_image_free(data); } else { std::cout << "texture failed loud path: " << path << std::endl; stbi_image_free(data); } return textureid; }
and here mesh.cpp:
#pragma once #include <glm\glm.hpp> #include <string> #include <vector> #include <shader.h> #include <sstream> struct vertex { glm::vec3 position; glm::vec3 normal; glm::vec2 texcoords; }; struct texture { unsigned int id; std::string type; aistring path; }; class mesh { public: /* mesh data */ std::vector<vertex> vertices; std::vector<unsigned int> indices; std::vector<texture> textures; /* functions */ mesh(std::vector<vertex> vertices, std::vector<unsigned int> indices, std::vector<texture> textures); void draw(shader shader); private: /* render data */ unsigned int vao, vbo, ebo; /* functions */ void setupmesh(); }; mesh::mesh(std::vector<vertex> vertices, std::vector<unsigned int> indices, std::vector<texture> textures) { this->vertices = vertices; this->indices = indices; this->textures = textures; setupmesh(); } void mesh::setupmesh() { glgenvertexarrays(1, &vao); glgenbuffers(1, &vbo); glgenbuffers(1, &ebo); glbindvertexarray(vao); glbindbuffer(gl_array_buffer, vbo); glbufferdata(gl_array_buffer, vertices.size() * sizeof(vertex), &vertices[0], gl_static_draw); glbindbuffer(gl_element_array_buffer, ebo); glbufferdata(gl_element_array_buffer, indices.size() * sizeof(unsigned int), &indices[0], gl_static_draw); //vertex positions glenablevertexattribarray(0); glvertexattribpointer(0, 3, gl_float, gl_false, sizeof(vertex), (void *)0); glenablevertexattribarray(1); glvertexattribpointer(1, 3, gl_float, gl_false, sizeof(vertex), (void *)offsetof(vertex, normal)); glenablevertexattribarray(2); glvertexattribpointer(2, 2, gl_float, gl_false, sizeof(vertex), (void *)offsetof(vertex, texcoords)); glbindvertexarray(0); } void mesh::draw(shader shader) { unsigned int diffusenr = 1, specularnr = 1; (int = 0; < textures.size(); i++) { std::cout << "hey" << std::endl; glactivetexture(gl_texture0 + i); std::stringstream ss; std::string name = textures[i].type; std::string number; if (name == "texture_diffuse") ss << diffusenr++; else if (name == "texture_specular") ss << specularnr++; number == ss.str(); shader.setfloat(("material." + name + number).c_str(), i); glbindtexture(gl_texture_2d, textures[i].id); } glactivetexture(gl_texture0); //draw mesh glbindvertexarray(vao); gldrawelements(gl_triangles, indices.size(), gl_unsigned_int, 0); glbindvertexarray(0); }
the 1 thing them when comes retrieving textures aimesh in model.cpp changed mesh->mtexturecoords[0]->x mesh->mtexturecoords[0][i].x //i being current vertex
i did because texture coordinates weren't being loaded properly. when comes how i'm rendering calling draw function on model sphere.
lastly because getting stupidly long here links vertex shader , fragment shader:
Comments
Post a Comment