OpenGL 纹理显示纹理的纯色,而不是整个纹理

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

主.cpp

#include<glad/glad.h>
#include<GLFW/glfw3.h>
#include<iostream>
#include<fstream>

#include"glheader.h"

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"



//Variables
const int tilesX = 30;
const int tilesY = 18;

int height = 720/2;
int width = 1280/2;

float incrementX = (float)2 / (tilesX-1);
float incrementY = (float)2 / (tilesY-1);

float vertices[] = {
//Vertices       //Texture
1.f, 1.f,      0.0f, 0.0f,
1.f, -1.f,     1.0f, 0.0f,
-1.f, 1.f,     0.0f, 1.0f,
-1.f, -1.f,    1.0f, 1.0f,
};
unsigned int indices[] = {
0, 1, 2,
2, 3, 1
};



int main(){
    glfwInit();

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    
    // Create window
    GLFWwindow* window = glfwCreateWindow(width, height, "Lentern", NULL, NULL);

    if (window == NULL) {
        std::cout << "Could not Create Window" << std::endl;
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);

    // Loading GLAD
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
        std::cout << "Could not load GLAD" << std::endl;
        return -1;
    }

    
    glViewport(0, 0, width, height);


//GLGen
    unsigned int VBO;
    unsigned int VAO;
    unsigned int EBO;

    unsigned int grasstexture;

    unsigned int shaderProgram;

    //createVertices(VAO, VBO, EBO, vertices, indices);
    //VAO
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);
    //VBO
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    //EBO
    glGenBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
    glEnableVertexAttribArray(0);


//Shader
    createShader(shaderProgram, "vert.vert", "frag.frag");

//Texture
    glGenTextures(1, &grasstexture);
    glBindTexture(GL_TEXTURE_2D, grasstexture);

    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_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    int width, height, nrChannels;
    unsigned char* data = stbi_load("grassy_path_plains.png", &width, &height,
        &nrChannels, 0);

    if (data) {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB,
            GL_UNSIGNED_BYTE, data);
    }
    else {
        std::cout << "Could not load texture image";
    }

    stbi_image_free(data);


//Render Loop
    //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    while (!glfwWindowShouldClose(window))
    {

        glUseProgram(shaderProgram);

        glBindTexture(GL_TEXTURE_2D, grasstexture);
        glBindVertexArray(VAO);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }


    glfwTerminate();
    return 0;    
}

glheader.cpp

#include"glheader.h"



void createShader(unsigned int& shaderProgram, const char* vertexFile, const char* fragmentFile) {

    std::string vertSoruce = getFileContents(vertexFile);
    std::string fragSoruce = getFileContents(fragmentFile);

    const char* vertexShaderSource = vertSoruce.c_str();
    const char* fragmentShaderSource = fragSoruce.c_str();

    unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);

    unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);

    shaderProgram = glCreateProgram();

    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);

    glLinkProgram(shaderProgram);

    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    vertexShaderSource = NULL;
    fragmentShaderSource = NULL;
}

void createVertices() {}//yet to be implemented

getFileContents 来自另一个名为

reader.h
的标头,这没有问题

着色器

//vertex
#version 330 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 atexCord;

out vec2 texCord;

void main () {
    gl_Position = vec4(aPos, 0.0,  1.0);
    texCord = atexCord;
}


//fragment - different file
#version 330 core
out vec4 FragColor;

in vec2 texCord;

uniform sampler2D grassTexture;

void main()
{
    FragColor = texture(grassTexture, texCord);
}

我认为问题出在着色器或纹理坐标或整个片段着色器的进出中的某个地方
质感
在此输入图片描述

结果
在此输入图片描述
它是纹理第一个像素的颜色

c++ opengl shader textures
1个回答
0
投票

我不使用 C++,所以我可能错过了一些东西,但尝试将片段着色器中的

grassTexture
重命名为
texture0
并重新运行它。当您将纹理绑定到纹理单元 0 时,OpenGL 将自动使用
texture0
。要拥有命名采样器,您需要将 int 传递给采样器,告诉它您的草纹理将绑定到哪个纹理单元。它应该看起来像这样:

GLint texture_location;
texture_location = glGetUnifromLocation(shaderProgram, "grassTexture");
glUniform1i(texture_location, 0);

要将纹理绑定到特定的纹理单元,请在渲染之前使用这段代码

glActiveTexture(GL_TEXTURE0 + textureUnit);
glBindTexture(GL_TEXTURE_2D, texture);

所以你基本上需要告诉 OpenGL

grassTexture
将使用纹理单元 0。我相信你可以使用 32 个不同的纹理单元(0-31),它们都可以是不同的纹理/采样器。

编辑:刚刚注意到您启用了顶点属性 0 两次。所以你的 UV 顶点属性永远不会被启用。

glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
    glEnableVertexAttribArray(0); // <-- This should be 1
© www.soinside.com 2019 - 2024. All rights reserved.