You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenGL 1.1基础3D渲染中纹理映射异常问题求助

OpenGL 1.1基础3D渲染中纹理映射异常问题求助

各位好,我正在尝试用OpenGL 1.1实现基础的3D渲染功能,但纹理映射始终无法正常工作,想请大家帮忙排查一下问题所在。

我的代码如下:

#define GLFW_INCLUDE_GLU
#include <GLFW/glfw3.h>
#include <gl/GL.h>
#include <gl/GLU.h>
#include <stdio.h>
#include <vector>
#include <filesystem>
#define TINYOBJLOADER_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#include "tiny_obj_loader.h"
#include "stb_image.h"

using namespace std;

int main() {
    if (!glfwInit()) {
        const char* error;
        glfwGetError(&error);
        printf("GLFW failed to intialize: %s", error);
        return 1;
    }

    GLFWwindow* window = glfwCreateWindow(640, 480, "MRE", NULL, NULL);
    glfwMakeContextCurrent(window);

    tinyobj::attrib_t attrib;
    vector<tinyobj::shape_t> shape;
    vector<tinyobj::material_t> material;
    vector<GLuint> textures;

    tinyobj::LoadObj(&attrib, &shape, &material, nullptr, nullptr, 
        (filesystem::current_path() / "model" / "animegirl.obj").generic_string().c_str(),
        (filesystem::current_path() / "model" / "").generic_string().c_str());

    for (int i = 0; i < material.size(); i++) {
        if (material[i].diffuse_texname != "") {
            stbi_set_flip_vertically_on_load(true);
            int w;
            int h;
            int n;
            unsigned char* tex = stbi_load(
                (filesystem::current_path() / "model" / material[i].diffuse_texname).generic_string().c_str(),
                &w, &h, &n, 4);
            GLuint glTex;
            glGenTextures(1, &glTex);
            glBindTexture(GL_TEXTURE_2D, glTex);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex);
            textures.push_back(glTex);
        } else {
            textures.push_back(0);
        }
    }

    glClearColor(0.2, 0.2, 0.2, 0.2);
    glViewport(0, 0, 640, 480);
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_DEPTH_TEST);

    glMatrixMode(GL_PROJECTION);
    gluPerspective(60, (float)(640.0 / 480.0), 2, 500);
    gluLookAt(0, 0, 200, 0, 0, 0, 0, 1, 0);

    while (true) {
        glfwPollEvents();

        glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        for (int i = 0; i < shape.size(); i++) {
            glBegin(GL_TRIANGLES);
            int offset = 0;
            int lastMat = 0;
            for (int j = 0; j < shape[i].mesh.num_face_vertices.size(); j++) {
                int mati = shape[i].mesh.material_ids[j];
                if (mati >= 0) {
                    tinyobj::material_t mat = material[mati];
                    if (textures[mati] != 0 && mati != lastMat) {
                        glEnd();
                        glBindTexture(GL_TEXTURE_2D, textures[mati]);
                        glBegin(GL_TRIANGLES);
                        lastMat = mati;
                    }
                }
                for (int k = 0; k < shape[i].mesh.num_face_vertices[j]; k++) {
                    tinyobj::index_t id = shape[i].mesh.indices[offset + k];
                    glVertex3f(
                        attrib.vertices[3 * size_t(id.vertex_index)],
                        attrib.vertices[3 * size_t(id.vertex_index) + 1],
                        attrib.vertices[3 * size_t(id.vertex_index) + 2]);
                    if (id.normal_index >= 0) {
                        glNormal3f(
                            attrib.normals[3 * size_t(id.normal_index)],
                            attrib.normals[3 * size_t(id.normal_index) + 1],
                            attrib.normals[3 * size_t(id.normal_index) + 2]);
                    }
                    if (id.texcoord_index >= 0) {
                        glTexCoord2f(
                            attrib.texcoords[2 * size_t(id.texcoord_index)],
                            attrib.texcoords[2 * size_t(id.texcoord_index) + 1]);
                    }
                }
                offset += shape[i].mesh.num_face_vertices[j];
            }
            glEnd();
        }

        glfwSwapBuffers(window);
    }
}

这是测试模型在Blender中的渲染效果:
Blender渲染的测试模型

而在我的引擎里渲染出来的效果是这样的:
我的引擎渲染效果

放大面部区域后,能更清晰地看到纹理出现了严重的变形:
放大后的面部纹理变形细节

我原本预期模型能呈现出类似Blender的渲染效果(除了光影效果会更简单一些),但现在纹理完全错乱了,希望大家能帮我找出问题所在。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 10:38:04