哈哈45137 2022-04-09 20:25 采纳率: 0%
浏览 64

OpenGL 渲染贴图纯色的问题

渲染一张图片,但是貌似只能渲染出纯色

#pragma once

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <fstream>

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <gl/GL.h>
#include <glm/glm.hpp>

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

//如果调整了窗口大小就调用该回调
void framebufffer_size_callback(GLFWwindow* window, int32_t width, int32_t height)
{
    glViewport(0, 0, width, height);
}
//输入检测
void processInput(GLFWwindow* window)
{
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
    {
        glfwSetWindowShouldClose(window, true);
    }
}

class Shader
{
public:
    uint32_t id;

public:
    //读取着色器代码
    std::string ReadShaderCode(const char* path)
    {
        std::string ret;
        std::ifstream fs;
        std::stringstream buf;
        fs.open(path);
        if (fs.is_open()) {
            buf << fs.rdbuf();
            ret = buf.str();
        }
        else {
            printf("Read shader source code erro");
        }
        fs.close();
        return ret;
    }

    //检测着色器编译是否成功
    GLuint ShaderIsCompile(GLint shader)
    {
        GLint success;    //是否成功编译
        GLchar infoLog[512];    //储存错误消息
        glGetShaderiv(shader, GL_COMPILE_STATUS, &success);    //检查是否编译成功
        if (!success) {
            glGetShaderInfoLog(shader, 512, NULL, infoLog);
            std::cout << "Shader compile erro:" << infoLog << std::endl;
        }
        return success;
    }

    //检测着色器链接是否成功
    GLuint ShaderIsLink(GLint shaderProgram)
    {
        GLint success;    //是否成功编译
        GLchar infoLog[512];    //储存错误消息
        glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);    //检查是否编译成功
        if (!success) {
            glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
            std::cout << "Shader link erro:" << infoLog << std::endl;
        }
        return success;
    }

    Shader(const char* vertexSourceCodePath, const char* fragmentSourceCodePath)
    {
        //-----读取着色器-----
        std::string vertexShaderSource = ReadShaderCode(vertexSourceCodePath);
        std::string frgmentShaderSource = ReadShaderCode(fragmentSourceCodePath);
        const char* vertexShaderCode = vertexShaderSource.c_str();
        const char* frgmentShaderCode = frgmentShaderSource.c_str();

        //-----编译着色器-----
        GLint vertexShader = NULL, fagmentShader = NULL;
        //创建着色器
        fagmentShader = glCreateShader(GL_FRAGMENT_SHADER);
        //附加源码到着色器
        glShaderSource(vertexShader, 1, &vertexShaderCode, NULL);
        glShaderSource(fagmentShader, 1, &frgmentShaderCode, NULL);
        //编译着色器
        glCompileShader(vertexShader);
        glCompileShader(fagmentShader);
        //检测着色器编译是否成功
        ShaderIsCompile(vertexShader);
        ShaderIsCompile(fagmentShader);

        //-------着色器程序-------
        //创建程序对象
        this->id = glCreateProgram();
        //将着色器附加到程序对象并链接
        glAttachShader(this->id, vertexShader);
        glAttachShader(this->id, fagmentShader);
        glLinkProgram(this->id);
        //检测着色器链接是否成功
        ShaderIsLink(this->id);
        //激活程序对象
        glUseProgram(this->id);
        //删除已经不需要的着色器对象
        glDeleteShader(vertexShader);
        glDeleteShader(fagmentShader);
    }

    //设置着色器Uniform值 Float vec4
    void SetUniformValueInt(float x, float y, float z, float w, const char* name)
    {
        //查找uniform的位置
        GLint up = glGetUniformLocation(this->id, name);
        //设置值
        glUniform4f(up, x, y, z, w);
    }

    //使用着色器
    void Use()
    {
        glUseProgram(this->id);
    }

    //关闭着色器
    void Close()
    {
        glDeleteProgram(id);
    }
};

class NEO_Render
{
private:
    GLFWwindow* window = nullptr;

    unsigned int texture;
    unsigned int VBO, VAO, EBO;

    //初始化渲染器
    void InitRender(int32_t width, int32_t height, const char* title)
    {
        /*-----------GLFW窗口创建-----------*/
        glfwInit();
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
        //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);

        glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);

        window = glfwCreateWindow(width, height, title, nullptr, nullptr);
        if (window == nullptr)
        {
            printf("创建窗口失败...\n");
            glfwTerminate();
            return;
        }

        glfwMakeContextCurrent(window);

        //防止报错
        glewExperimental = GL_TRUE;
        glewInit();
    }
    //渲染主循环
    void MainLoop()
    {
        Shader shaderObj = Shader("VertexShader.vert", "FragmentShader.frag");

        SetRenderConfig(shaderObj);

        while (glfwWindowShouldClose(window) == 0)
        {
            processInput(window);

            glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT);

            RenderModel(shaderObj);

            glBindVertexArray(VAO);
            glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
            glBindVertexArray(0);

            glfwSwapBuffers(window);
            glfwPollEvents();
        }
    }

public:
    //设置渲染配置
    void SetRenderConfig(Shader& shaderObj)
    {
        float vertices[] = {
            //     ---- 位置 ----       ---- 颜色 ----     - 纹理坐标 -
             0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f,   // 右上
             0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f,   // 右下
            -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f,   // 左下
            -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f    // 左上
        };
        unsigned int indices[] = {  // note that we start from 0!
            0, 1, 3,  // first Triangle
            1, 2, 3   // second Triangle
        };

        glGenBuffers(1, &VBO);        //生成VBO对象
        glGenVertexArrays(1, &VAO);    //生成VAO对象
        glGenBuffers(1, &EBO);        //生成EBO对象

        glBindVertexArray(VAO);

        glBindBuffer(GL_ARRAY_BUFFER, VBO); //绑定VBO到GL_ARRAY_BUFFER目标上
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);    //复制顶点数据到缓冲

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);    //绑定EBO到GL_ELEMENT_ARRAY_BUFFER目标上
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_DYNAMIC_DRAW);    //复制索引数据到缓冲

        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);    //位置数据格式
        glEnableVertexAttribArray(0);    //启用位置属性

        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));    //顶点颜色数据格式
        glEnableVertexAttribArray(1);    //启用顶点颜色属性

        glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));    //顶点数据格式
        glEnableVertexAttribArray(2);    //启用顶点属性

        glGenTextures(1, &texture);
        glBindTexture(GL_TEXTURE_2D, texture);
        //环绕方式
        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);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        int32_t width, height, nrChannels;
        unsigned char* data = stbi_load("awesomeface.png", &width, &height, &nrChannels, 0);
        if (data)
        {
            //根据图片数据生成纹理
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
            glGenerateMipmap(GL_TEXTURE_2D);    //自动生成MIPMAP
        }
        else
        {
            printf("Load image erro!!!");
        }
        stbi_image_free(data);    //释放图像内存

        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
    }

    //绘制模型到窗口
    void RenderModel(Shader& shaderObj)
    {
        shaderObj.Use();
    }

    //运行渲染器
    void Run()
    {
        InitRender(1280, 720, "Hello");
        MainLoop();
        Close();
    }
    //关闭渲染器
    void Close()
    {
        glfwTerminate();
        return;
    }

    NEO_Render()
    {

    }
    ~NEO_Render()
    {

    }
};


顶点着色器

#version 430 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;

out vec3 ourColor;
out vec2 TexCoord;

void main()
{
    gl_Position = vec4(aPos, 1.0);
    ourColor = aColor;
    TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}

片元着色器


#version 430 core
out vec4 FragColor;

in vec3 ourColor;
in vec2 TexCoord;

// texture sampler
uniform sampler2D texture1;

void main()
{
    FragColor = texture(texture1, TexCoord);
}

img

修改贴图坐标无效,修改图片格式无效

我想要达到的结果类似

img

  • 写回答

1条回答 默认 最新

  • 赵4老师 2022-04-11 11:17
    关注

    找OpenGL官网相关例子代码编译链接调试一下。

    评论

报告相同问题?

问题事件

  • 创建了问题 4月9日

悬赏问题

  • ¥15 Fluent齿轮搅油
  • ¥15 八爪鱼爬数据为什么自己停了
  • ¥15 交替优化波束形成和ris反射角使保密速率最大化
  • ¥15 树莓派与pix飞控通信
  • ¥15 自动转发微信群信息到另外一个微信群
  • ¥15 outlook无法配置成功
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素