顶点着色器中的位移贴图

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

我是opengl新手 我想使用顶点着色器制作地形。 我将位移图(geo_texture)映射到 256*256 顶点平面(网格) 顶点着色器:

out vec3 color;
out vec2 texCoord;

uniform mat4 model;
uniform mat4 proj_view;
uniform sampler2D geo_texture;

void main()
{
   color = aPos;
   texCoord = aTexCoord;

   vec4 displacement = texture(geo_texture, texCoord);
   vec3 pos = aPos;
    pos.y += normalize( displacement.x);  

   gl_Position = proj_view * model * vec4(pos, 1.0);   
}

这是我的纹理类

Texture::Texture(const char *fileName, GLuint shader_program_id, const char *uniName){
    uniformName = uniName;

    int width_texture, height_texture, channel_texture;
    unsigned char* bytes = stbi_load(fileName, &width_texture, &height_texture, &channel_texture, 0);
    const char* failureReason = stbi_failure_reason();
    if(failureReason!=nullptr){
        glfwSetErrorCallback(glfw_error_callback);
    }

    GLuint texture;
    glGenTextures(1, &texture);
    glActiveTexture(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width_texture, height_texture, 0, GL_RGB, GL_UNSIGNED_BYTE, bytes );

    glGenerateMipmap(GL_TEXTURE_2D);

    stbi_image_free(bytes);
    glBindTexture(GL_TEXTURE_2D, 0);
    glGetUniformLocation(shader_program_id, uniformName);
    uni_texture = texture;
}

和主要:

int main(int argc, char** argv)
{   
    if (argc>=2) chdir(argv[1]);

    
    
    glfwInit();

    // set glfw's OpenGL to VERSION=3.3
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    // set glfw's to CORE profile (modern functions ONLY)
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    GLFWwindow* window = glfwCreateWindow(window_width, window_height, extract_version(argv[0]), NULL, NULL);
    
    // event handling
    glfwSetErrorCallback(glfw_error_callback);
    glfwSetWindowCloseCallback(window, glfw_window_close_callback);
    glfwMakeContextCurrent(window);

    //load GLAD to configures OpenGL
    gladLoadGL();
    // adjust viewport
    glViewport(0, 0, window_width, window_height);

    // Generates Shader object using shaders defualt.vert and default.frag
    Shader geo_shader = Shader(geo_vert, geo_frag);
    Shader blade_shader = Shader(blade_vert, blade_frag);


    // camera
    float fov = glm::radians(45.0f), near = 0.1f, far = 1000.0f;
    glm::vec3 eye_position = glm::vec3(0.0f, 0.5f, 150.0f), eye_direction = glm::vec3(0.0f, 0.0f, -1.0f);
    Camera cam = Camera(eye_position, eye_direction, window_width, window_height, fov, near, far);

    //model
    ObjLoader obj = ObjLoader();
    Mesh geo_mesh = obj.load_obj_from_file(geo_obj, false, false, true);
    std::vector<glm::mat4> instance_mats;


    srand(static_cast<unsigned int>(time(nullptr)));
    
    float rotation =45.0f;
    glm::vec3 scale = glm::vec3(0.1f);
    glm::mat4 proj_view = cam.get_matrix();
    for(auto vert: geo_mesh.vertices){
        int random_number = rand() % 100;
        if(random_number>96){
        glm::mat4 transformation = glm::mat4(1.0f);     
        transformation = glm::translate(transformation, vert.position);
        instance_mats.push_back( transformation);}  
    }
    int a = instance_mats.size();
    Mesh blade_mesh = obj.load_obj_from_file(blade_obj, false, false, true,  instance_mats.size(), instance_mats);
    
    //enable depth buffer
    glEnable(GL_DEPTH_TEST);
    

    // texture
    Texture geo_texture = Texture(geo_texture_img, geo_shader.ID, "geo_texture");
    Texture grass_texture = Texture(blade_texture_img, blade_shader.ID, "grass_texture");
    
//////////////////////////////////////////////////////////////////////////////////////////////////////    

    while(!glfwWindowShouldClose(window)){
        // Specify the color of the background
        glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        // Clean the back buffer and assign the new color to it
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        
        // every assigning stuff go after activate
        glm::mat4 model_orientation = glm::mat4(1.0f);
        model_orientation = glm::rotate(model_orientation, glm::radians(rotation), glm::vec3(1.0f, 0.0f, 0.0f));
        geo_mesh.draw(geo_shader,cam, model_orientation, geo_texture);
        // blade_mesh.draw(blade_shader, cam, model_orientation, grass_texture);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }


/////////////////////////////////////////////////////////////////////////////////////////////////////////

    // delete everything
    geo_texture.remove();
    grass_texture.remove();
    geo_shader.remove();
    blade_shader.remove();
    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}

最近的输出显示正在显示网格,但顶点没有移位。所以我怀疑应该是纹理的设置有问题,或者是渲染顺序有问题?

c++ opengl glsl vertex-shader
1个回答
0
投票

正如我在评论中所说,你真的应该学习如何使用 RenderDoc 来调试这些东西。但通过检查代码,我看到了这些问题:

(1) 你使用

glActiveTexture
错误,它的参数应该像
GL_TEXTURE0
,
GL_TEXTURE1
, ... 等等

(2) 最重要的是 - 您不使用

glGetUniformLocation
的返回值,并且不将纹理附加到纹理单元,并且不将纹理单元指定为着色器统一

// shader initialization
GLint uniformLocation = glGetUniformLocation(shader_program_id, uniformName);
GLint textureUnit = 0; // can be arbitrary
glUseProgram(shader_program_id);
glUniform1i(uniformLocation, textureUnit);
glUseProgram(0);

// before every render
glActiveTexture(GL_TEXTURE0 + textureUnit);
glBindTexture(GL_TEXTURE_2D, texture);
© www.soinside.com 2019 - 2024. All rights reserved.