渲染纹理的问题,因为它显示为全黑

问题描述 投票:0回答:1

尽管从 learnopengl in practice 部分复制了代码,但我在渲染精灵时遇到了问题。一开始我以为什么都没有渲染,但在从黑色变成青色之后我发现纹理实际上是生成的但它是一个漆黑的矩形而不是所谓的“令人敬畏的脸”的恼人的开放微笑沐浴在这家喻户晓的电脑绿中。我尝试并尝试在线搜索解决方案,但是当您阅读本文时,您已经知道它的结果是什么,所以我以全能上帝的名义请求大家帮助我解决这个麻烦的事情,我恳求。

我正在使用 glew 和 SDL 的邪恶组合,所以这是愚蠢的代码:

着色器

#pragma once
#define GLEW_STATIC
#include <gl/glew-2.2.0/include/GL/glew.h>
#include <glm-master/glm/gtc/type_ptr.hpp>
#include <iostream>
#include <fstream>
#include <istream>
#include <sstream>

class shader
{
    
public:
    
    unsigned int prog;

    shader()
    {

    }

    void lammp(const char* vertexchar, const char* fragmentchar, const char* geochar)
    {
        


        unsigned int vex, fra;
        unsigned int geo;
        char info[512];
        int success;

        vex = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vex, 1, &vertexchar, NULL);
        glCompileShader(vex);
        glGetShaderiv(vex, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(vex, 512, NULL, info);
            std::cout << "problem: " << info << "... szmato" << std::endl;
        }

        fra = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fra, 1, &fragmentchar, NULL);
        glCompileShader(fra);
        glGetShaderiv(fra, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(fra, 512, NULL, info);
            std::cout << "problem: " << info << "... szmato" << std::endl;
        }

        

        prog = glCreateProgram();
        glAttachShader(prog, vex);
        glAttachShader(prog, fra);
        if (geochar != NULL)
        {
            geo = glCreateShader(GL_GEOMETRY_SHADER);
            glShaderSource(geo, 1, &geochar, NULL);
            glCompileShader(geo);
            glGetShaderiv(geo, GL_COMPILE_STATUS, &success);
            if (!success)
            {
                glGetShaderInfoLog(fra, 512, NULL, info);
                std::cout << "problem: " << info << "... szmato" << std::endl;
            }

            glAttachShader(prog, geo);
        }
        glLinkProgram(prog);

        glGetProgramiv(prog, GL_LINK_STATUS, &success);
        if (!success)
        {
            glGetProgramInfoLog(prog, 512, NULL, info);
            std::cout << "lol program się zesrał: " << info << " laudetur iesus christus" << std::endl;
        }


        glDeleteShader(vex);
        glDeleteShader(fra);
        if (geochar != NULL)
        {
            glDeleteShader(geo);
        }
    }

    shader &use()
    {
        glUseProgram(prog);
        return *this;
    }

    void SetFloat(const char* name, float value, bool useShader)
    {
        if (useShader)
            this->use();
        glUniform1f(glGetUniformLocation(this->prog, name), value);
    }
    void SetInteger(const char* name, int value, bool useShader)
    {
        if (useShader)
            this->use();
        glUniform1i(glGetUniformLocation(this->prog, name), value);
    }
    void SetVector2f(const char* name, float x, float y, bool useShader)
    {
        if (useShader)
            this->use();
        glUniform2f(glGetUniformLocation(this->prog, name), x, y);
    }
    void SetVector2f(const char* name, const glm::vec2& value, bool useShader)
    {
        if (useShader)
            this->use();
        glUniform2f(glGetUniformLocation(this->prog, name), value.x, value.y);
    }
    void SetVector3f(const char* name, float x, float y, float z, bool useShader)
    {
        if (useShader)
            this->use();
        glUniform3f(glGetUniformLocation(this->prog, name), x, y, z);
    }
    void SetVector3f(const char* name, const glm::vec3& value, bool useShader)
    {
        if (useShader)
            this->use();
        glUniform3f(glGetUniformLocation(this->prog, name), value.x, value.y, value.z);
    }
    void SetVector4f(const char* name, float x, float y, float z, float w, bool useShader)
    {
        if (useShader)
            this->use();
        glUniform4f(glGetUniformLocation(this->prog, name), x, y, z, w);
    }
    void SetVector4f(const char* name, const glm::vec4& value, bool useShader)
    {
        if (useShader)
            this->use();
        glUniform4f(glGetUniformLocation(this->prog, name), value.x, value.y, value.z, value.w);
    }
    void SetMatrix4(const char* name, const glm::mat4& matrix, bool useShader)
    {
        if (useShader)
            this->use();
        glUniformMatrix4fv(glGetUniformLocation(this->prog, name), 1, false, glm::value_ptr(matrix));
    }

};

雪碧

#pragma once

#include "shader.h"


class skin2D
{

    
public:
    unsigned int ID;

    unsigned int Width, Height;

    unsigned int Internal_Format;
    unsigned int Image_Format;
    unsigned int Wrap_S;
    unsigned int Wrap_T;
    unsigned int Filter_Min;
    unsigned int Filter_Max;
  
   
    skin2D()
    {
        glGenTextures(1, &this->ID);
    }
    void Generate(unsigned int width, unsigned int height, unsigned char* data)
    {
        this->Width = width;
        this->Height = height;
        
        glBindTexture(GL_TEXTURE_2D, this->ID);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, this->Wrap_S);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, this->Wrap_T);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, this->Filter_Min);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, this->Filter_Max);
      
        glTexImage2D(GL_TEXTURE_2D, 0, this->Internal_Format, width, height, 0, this->Image_Format, GL_UNSIGNED_BYTE, data);
        
      
        glBindTexture(GL_TEXTURE_2D, 0);

    }
    
    void Bind() const
    {
        glBindTexture(GL_TEXTURE_2D, this->ID);
    }
};

精灵渲染器

class skinmaker
{
    // Render state
    shader       shaqer;
    unsigned int quadVAO;
    // Initializes and configures the quad's buffer and vertex attributes
    void initRenderData()
    {
        unsigned int VBO;
        float vertices[] = {
            // pos      // tex
            0.0f, 1.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 1.0f, 0.0f,
            0.0f, 0.0f, 0.0f, 0.0f,

            0.0f, 1.0f, 0.0f, 1.0f,
            1.0f, 1.0f, 1.0f, 1.0f,
            1.0f, 0.0f, 1.0f, 0.0f
        };

        glGenVertexArrays(1, &this->quadVAO);
        glGenBuffers(1, &VBO);

        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

        glBindVertexArray(this->quadVAO);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
    }
public:
    // Constructor (inits shaders/shapes)
    skinmaker(shader shaber)
    {
        this->shaqer = shaber;
        this->initRenderData();
    }
    // Destructor
    ~skinmaker();
    // Renders a defined quad textured with given sprite
    void IeatCrayons(skin2D& texture, glm::vec2 position, glm::vec2 size = glm::vec2(10.0f, 10.0f), float rotate = 0.0f, glm::vec3 color = glm::vec3(1.0f))
    {
        this->shaqer.use();
        glm::mat4 model =
            glm::mat4(1.0f);
        model = glm::translate(model, glm::vec3(position, 0.0f));  // first translate (transformations are: scale happens first, then rotation, and then final translation happens; reversed order)

        model = glm::translate(model, glm::vec3(0.5f * size.x, 0.5f * size.y, 0.0f)); // move origin of rotation to center of quad
        model = glm::rotate(model, glm::radians(rotate), glm::vec3(0.0f, 0.0f, 1.0f)); // then rotate
        model = glm::translate(model, glm::vec3(-0.5f * size.x, -0.5f * size.y, 0.0f)); // move origin back

        model = glm::scale(model, glm::vec3(size, 1.0f)); // last scale

        this->shaqer.SetMatrix4("model", model, false);

        // render textured quad
        this->shaqer.SetVector3f("spriteColor", color, false);

        glActiveTexture(GL_TEXTURE0);
        texture.Bind();

        glBindVertexArray(this->quadVAO);
        glDrawArrays(GL_TRIANGLES, 0, 6);
        glBindVertexArray(0);
   
    }
};

资源管理器

#pragma once

#include <map>
#include <string>

#include "skin.h"
#include "shader.h"
#include "stb_image.h"
#include <iostream>
#include <sstream>
#include <fstream>


class ResourceManager
{
public:
 
    static std::map<std::string, shader>    Shaders;
    static std::map<std::string, skin2D> Textures;
    
    static shader    LoadShader(const char* vShaderFile, const char* fShaderFile, const char* gShaderFile, std::string name)
    {
        Shaders[name] = loadShaderFromFile(vShaderFile, fShaderFile, gShaderFile);
        return Shaders[name];
    }

    static shader    GetShader(std::string name) 
    {
        return Shaders[name];
    }

    static skin2D LoadTexture(const char* file, bool alpha, std::string name) 
    {
        Textures[name] = loadTextureFromFile(file, alpha);
        return Textures[name];
    }

    
    static skin2D& GetTexture(std::string name);
   

   
    static void      Clear()
    {
        
        for (auto iter : Shaders)
            glDeleteProgram(iter.second.prog);
            for (auto iter : Textures)
            glDeleteTextures(1, &iter.second.ID);
    }

private:
   
    ResourceManager() { }

    static shader  loadShaderFromFile(const char* vShaderFile, const char* fShaderFile, const char* gShaderFile = nullptr)
    {
        std::string vertexCode;
        std::string fragmentCode;
        std::string geometryCode;
        try
        {
            // open files
            std::ifstream vertexShaderFile(vShaderFile);
            std::ifstream fragmentShaderFile(fShaderFile);
            std::stringstream vShaderStream, fShaderStream;
            // read file's buffer contents into streams
            vShaderStream << vertexShaderFile.rdbuf();
            fShaderStream << fragmentShaderFile.rdbuf();
            // close file handlers
            vertexShaderFile.close();
            fragmentShaderFile.close();
            // convert stream into string
            vertexCode = vShaderStream.str();
            fragmentCode = fShaderStream.str();
            // if geometry shader path is present, also load a geometry shader
            if (gShaderFile != nullptr)
            {
                std::ifstream geometryShaderFile(gShaderFile);
                std::stringstream gShaderStream;
                gShaderStream << geometryShaderFile.rdbuf();
                geometryShaderFile.close();
                geometryCode = gShaderStream.str();
            }
        }
        catch (std::exception e)
        {
            std::cout << "ERROR::SHADER: Failed to read shader files" << std::endl;
        }
        const char* vShaderCode = vertexCode.c_str();
        const char* fShaderCode = fragmentCode.c_str();
        const char* gShaderCode = geometryCode.c_str();
        // 2. now create shader object from source code
        shader shaqer;
        shaqer.lammp(vShaderCode, fShaderCode, gShaderFile != nullptr ? gShaderCode : nullptr);
        return shaqer;
    }

    static skin2D loadTextureFromFile(const char* file, bool alpha);
  
};

这是个愚蠢的 .CCP 文件

#include "resouces.h"

std::map<std::string, shader> ResourceManager::Shaders;
std::map<std::string, skin2D> ResourceManager::Textures;

skin2D ResourceManager::loadTextureFromFile(const char* file, bool alpha)
{
  
    // create texture object
    skin2D texture;
    if (alpha)
    {
        texture.Internal_Format = GL_RGBA;
        texture.Image_Format = GL_RGBA;
    }
    // load image
    int width, height, nrChannels;
    unsigned char* data = stbi_load(file, &width, &height, &nrChannels, 0);
    // now generate texture
    texture.Generate(width, height, data);
    // and finally free image data
    stbi_image_free(data);
    return texture;
}

skin2D& ResourceManager::GetTexture(std::string name)
{
   skin2D& skin = Textures[name];
   return skin;
}

这里是主要代码 YUPII! (免除我这种自我强加的痛苦)

#define GLEW_STATIC
#include <gl/glew-2.2.0/include/GL/glew.h>
#define STB_IMAGE_IMPLEMENTATION
#include "window.h"
#include "InputMenager.h"
#include "shader.h"
#include "resouces.h"
#include "glm-master/glm/glm.hpp"

#undef main
int main()
{
    
    int Width = 800, Height = 600;

    window w = window("Praise to God!", Width, Height);
    
    glewInit();

    InputMen in;
    bool e = false;

    skinmaker* Renderer;
    

    ResourceManager::LoadShader("Shaders/shader.vs", "Shaders/shader.frag", nullptr, "sprite");
    // configure shaders
    glm::mat4 projection = glm::ortho(0.0f, static_cast<float>(Width),static_cast<float>(Height), 0.0f, -1.0f, 1.0f);
    ResourceManager::GetShader("sprite").use().SetInteger("image", 0, true);
    ResourceManager::GetShader("sprite").SetMatrix4("projection", projection, true);
    // set render-specific controls
    Renderer = new skinmaker(ResourceManager::GetShader("sprite"));
    // load textures
    ResourceManager::LoadTexture("awesomeface.png", true, "face");
    
    while (!e)
    {
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        Renderer->IeatCrayons(ResourceManager::GetTexture("face"), glm::vec2(200.0f, 100.0f), glm::vec2(300.0f, 400.0f), 45.0f);
        
        w.Display();
        

        while (SDL_PollEvent(&in.input) != NULL)
        {
            if (in.ButtonDown(SDL_SCANCODE_SPACE)) e = true;
        }


        
        
    }
}

所以我请大家帮我解决这个对你来说可能是轻而易举的麻烦事, 所以请告诉我我的错是什么我做错了什么或者我忘记了什么,无论如何如果你还在读这篇文章上帝保佑你并感谢你提供的任何帮助

c++ opengl textures glm-math glew
1个回答
0
投票

如果您不生成mipmaps(使用

glGenerateMipmap
),设置
GL_TEXTURE_MIN_FILTER
很重要。由于默认过滤器是
GL_NEAREST_MIPMAP_LINEAR
,如果您不将最小化功能更改为
GL_NEAREST
GL_LINEAR
,则纹理将是“Mipmap 不完整”。

Wrap_S
对象(类
Wrap_T
)的
Filter_Min
Filter_Max
Texture
skin2D
属性永远不会被设置。我建议使用适当的默认值设置属性:

class skin2D
{
public:
    unsigned int ID = 0;
    unsigned int Width = 0,
    unsigned int Height = 0;
    unsigned int Internal_Format = GL_RGBA;
    unsigned int Image_Format = GL_RGBA;
    unsigned int Wrap_S = GL_REPEAT;
    unsigned int Wrap_T = GL_REPEAT;
    unsigned int Filter_Min = GL_LINEAR_MIPMAP_LINEAR;
    unsigned int Filter_Max = GL_LINEAR;
  
    skin2D()
    {
        glGenTextures(1, &this->ID);
    }
    void Generate(unsigned int width, unsigned int height, unsigned char* data)
    {
        this->Width = width;
        this->Height = height;   
        glBindTexture(GL_TEXTURE_2D, this->ID);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, this->Wrap_S);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, this->Wrap_T);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, this->Filter_Min);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, this->Filter_Max);
        glTexImage2D(GL_TEXTURE_2D, 0, this->Internal_Format, width, height, 0, this->Image_Format, GL_UNSIGNED_BYTE, data); 
        glBindTexture(GL_TEXTURE_2D, 0);
    }

    // [...]
© www.soinside.com 2019 - 2024. All rights reserved.