我是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;
}
最近的输出显示正在显示网格,但顶点没有移位。所以我怀疑应该是纹理的设置有问题,或者是渲染顺序有问题?
正如我在评论中所说,你真的应该学习如何使用 RenderDoc 来调试这些东西。但通过检查代码,我看到了这些问题:
glActiveTexture
错误,它的参数应该像 GL_TEXTURE0
, GL_TEXTURE1
, ... 等等
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);