I attempted asking this on reddit however I did not get any solutions so I’d as nicely strive right here
So I am making a program to generate some terrain and it is not giving me the outcomes I anticipated. It is drawing black pillars. A lot of code arising btw.
That is the article that I am utilizing https://learnopengl.com/Visitor-Articles/2021/Tessellation/Tessellation
Despite the fact that it is written in C++ I rewrote it in C, the language I am utilizing.
That is the vertex shader
#model 410 core
format (location = 0) in vec3 pos;
format (location = 1) in vec2 tex;
out vec2 tex_coord;
void primary()
{
// set place and units texture (uv) coordinates
gl_Position = vec4(pos, 1.0);
tex_coord = tex;
}
That is the fragment shader
#model 410 core
in float top;
out vec4 shade;
void primary()
{
float h = (top+16)/64.0f;
shade = vec4(h,h,h,1.0);
}
That is the tessellation management shader
#model 410 core
format(vertices=4) out;
uniform mat4 mannequin;
uniform mat4 view;
in vec2 tex_coord[];
out vec2 texture_coord[];
void primary()
{
// primarily units render distance
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
texture_coord[gl_InvocationID] = tex_coord[gl_InvocationID];
if(gl_InvocationID == 0)
{
const int MIN_TESS_LEVEL = 4;
const int MAX_TESS_LEVEL = 64;
const float MIN_DISTANCE = 20;
const float MAX_DISTANCE = 800;
vec4 eye_space_pos_00 = view * mannequin * gl_in[0].gl_Position;
vec4 eye_space_pos_01 = view * mannequin * gl_in[1].gl_Position;
vec4 eye_space_pos_10 = view * mannequin * gl_in[2].gl_Position;
vec4 eye_space_pos_11 = view * mannequin * gl_in[3].gl_Position;
// "distance" from digicam scaled between 0 and 1
float distance_00 = clamp( (abs(eye_space_pos_00.z) - MIN_DISTANCE) / (MAX_DISTANCE-MIN_DISTANCE), 0.0, 1.0 );
float distance_01 = clamp( (abs(eye_space_pos_01.z) - MIN_DISTANCE) / (MAX_DISTANCE-MIN_DISTANCE), 0.0, 1.0 );
float distance_10 = clamp( (abs(eye_space_pos_10.z) - MIN_DISTANCE) / (MAX_DISTANCE-MIN_DISTANCE), 0.0, 1.0 );
float distance_11 = clamp( (abs(eye_space_pos_11.z) - MIN_DISTANCE) / (MAX_DISTANCE-MIN_DISTANCE), 0.0, 1.0 );
float tess_level_0 = combine( MAX_TESS_LEVEL, MIN_TESS_LEVEL, min(distance_10, distance_00) );
float tess_level_1 = combine( MAX_TESS_LEVEL, MIN_TESS_LEVEL, min(distance_00, distance_01) );
float tess_level_2 = combine( MAX_TESS_LEVEL, MIN_TESS_LEVEL, min(distance_01, distance_11) );
float tess_level_3 = combine( MAX_TESS_LEVEL, MIN_TESS_LEVEL, min(distance_11, distance_10) );
gl_TessLevelOuter[0] = tess_level_0;
gl_TessLevelOuter[1] = tess_level_1;
gl_TessLevelOuter[2] = tess_level_2;
gl_TessLevelOuter[3] = tess_level_3;
gl_TessLevelInner[0] = max(tess_level_1, tess_level_3);
gl_TessLevelInner[1] = max(tess_level_0, tess_level_2);
}
}
That is the tessellation analysis shader
#model 410 core
format(quads, fractional_odd_spacing, ccw) in;
uniform sampler2D height_map;
uniform mat4 mannequin;
uniform mat4 view;
uniform mat4 projection;
in vec2 texture_coord[];
out float top;
void primary()
{
// get the feel coordinate of level (x, y, z) within the terrain
float u = gl_TessCoord.x;
float v = gl_TessCoord.y;
vec2 t_00 = texture_coord[0];
vec2 t_01 = texture_coord[1];
vec2 t_10 = texture_coord[2];
vec2 t_11 = texture_coord[3];
vec2 t_0 = (t_01 - t_00) * u + t_00;
vec2 t_1 = (t_11 - t_10) * u + t_10;
vec2 tex_coord = (t_1 - t_0) * v + t_0;
top = texture(height_map, tex_coord).g * 64.0 - 16.0;
vec4 p_00 = gl_in[0].gl_Position;
vec4 p_01 = gl_in[1].gl_Position;
vec4 p_10 = gl_in[2].gl_Position;
vec4 p_11 = gl_in[3].gl_Position;
vec4 u_vec = p_01 - p_00;
vec4 v_vec = p_10 - p_00;
vec4 regular = normalize( vec4(cross(v_vec.xyz, u_vec.xyz), 0) );
vec4 p_0 = (p_01 - p_00) * u + p_00;
vec4 p_1 = (p_11 - p_10) * u + p_10;
vec4 p = (p_1 - p_0) * v + p_0 + regular * top;
gl_Position = projection * view * mannequin * p;
}
That is the initialization for GLFW
// init glfw
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif // __APPLE__
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// test to see if glfw was initialized
if(!glfwInit())
{
printf("GLFW isn't okay.n");
}
That is the place I loaded the peak map
// top map
unsigned int texture;
glGenTextures(1, &texture);
glActiveTexture(GL_TEXTURE0);
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);
// load the picture
int width, top, nr_components;
brief unsigned int* information = stbi_load_16("textures/river_heightmap.png", &width, &top, &nr_components, 0);
if(information)
{
// bind texture and specify its information and the best way to handle it
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16, width, top, 0, GL_RED, GL_UNSIGNED_SHORT, information);
// set the peak map
set_int(shader_program, "height_map", 0);
printf("Loaded a top map of %i x %in", width, top);
}
else
{
printf("Didn't load top mapn");
}
stbi_image_free(information);
That is the place I uploaded the terrain information to the GPU
float vertices[1000];
unsigned rez = 20;
for(unsigned i = 0; i <= rez-1; i++)
{
for(unsigned j = 0; j <= rez-1; j++)
{
push_back_float(-width/2.0f + width*i/(float)rez, vertices); // v.x
push_back_float(0.0f, vertices); // v.y
push_back_float(-height/2.0f + top*j/(float)rez, vertices); // v.z
push_back_float(i / (float)rez, vertices); // u
push_back_float(j / (float)rez, vertices); // v
push_back_float(-width/2.0f + width*(i+1)/(float)rez, vertices); // v.x
push_back_float(0.0f, vertices); // v.y
push_back_float(-height/2.0f + top*j/(float)rez, vertices); // v.z
push_back_float((i+1) / (float)rez, vertices); // u
push_back_float(j / (float)rez, vertices); // v
push_back_float(-width/2.0f + width*i/(float)rez, vertices); // v.x
push_back_float(0.0f, vertices); // v.y
push_back_float(-height/2.0f + top*(j+1)/(float)rez, vertices); // v.z
push_back_float(i / (float)rez, vertices); // u
push_back_float((j+1) / (float)rez, vertices); // v
push_back_float(-width/2.0f + width*(i+1)/(float)rez, vertices); // v.x
push_back_float(0.0f, vertices); // v.y
push_back_float(-height/2.0f + top*(j+1)/(float)rez, vertices); // v.z
push_back_float((i+1) / (float)rez, vertices); // u
push_back_float((j+1) / (float)rez, vertices); // v
}
}
printf("Loaded %i patches of 4 management factors eachn", rez*rez);
printf("Processing %i vertices in vertex shadern", rez*rez*4);
That is the place I arrange the VAO and VBO
unsigned int vao, vbo;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, (float)(sizeof(vertices)/sizeof(vertices[0])) * sizeof(float), &vertices[0], GL_STATIC_DRAW);
// place attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// texture attribute
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(sizeof(float) * 3));
glEnableVertexAttribArray(1);
glPatchParameteri(GL_PATCH_VERTICES, NUM_PATCH_PTS);
That is the primary loop and the buffer deletion
// sport loop
whereas (!glfwWindowShouldClose(window))
GL_DEPTH_BUFFER_BIT);
// shader
use_shader(shader_program);
// view/projection transformations
mat4 projection = GLM_MAT4_IDENTITY_INIT;
glm_perspective(glm_rad(ccamera->zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f, projection);
mat4 view = GLM_MAT4_IDENTITY_INIT;
camera_get_view_matrix(view);
set_mat_4(shader_program, "projection", projection);
set_mat_4(shader_program, "view", view);
// world transformation
mat4 mannequin = GLM_MAT4_IDENTITY_INIT;
set_mat_4(shader_program, "mannequin", mannequin);
// render terrain
glBindVertexArray(vao);
glDrawArrays(GL_PATCHES, 0, NUM_PATCH_PTS*rez*rez);
// glfw: swap buffers and ballot IO occasions
glfwSwapBuffers(window);
glfwPollEvents();
// deallocate assets that outlived their function
shader_clean_up(shader_program);
// clear up glfw
glfwTerminate();
return 0;
These are the screenshots of the RenderDoc report

When you want any extra data inform me so I can add extra screenshots and code if wanted.
Edit:
The shader loader, the unique code is from right here should you wanna take a look at that: https://github.com/CraftingInC/LearnOpenGLInC/blob/grasp/consists of/learnopengl/shader.h
Word: I did change a couple of issues round from the unique so right here is my model
#ifndef SHADER_H_INCLUDED
#outline SHADER_H_INCLUDED
#embrace <GL/glew.h>
#embrace <string.h>
#embrace <stdlib.h>
#embrace <stdio.h>
#embrace <stdbool.h>
#embrace <CGLM/cglm.h>
// hundreds the shader then copies the info right into a char variable and returns the shader id
int load_shader_file(const char* shader_file_name, int shader_type)
{
FILE* shader_file = fopen(shader_file_name, "rb");
if(shader_file != NULL)
{
char* shader_char;
fseek(shader_file, 0, SEEK_END);
size_t total_size = ftell(shader_file);
rewind(shader_file);
shader_char = (char*)malloc(total_size + 1);
fread(shader_char, 1, total_size, shader_file);
shader_char[total_size] = 0;
fclose(shader_file);
GLuint shader_id = 0;
shader_id = glCreateShader(shader_type);
glShaderSource(shader_id, 1, (const char**)&shader_char, NULL);
glCompileShader(shader_id);
GLint shader_compiled;
glGetShaderiv(shader_id, GL_COMPILE_STATUS, &shader_compiled);
if(shader_compiled != GL_TRUE)
{
GLsizei log_length;
GLchar log[1024];
glGetShaderInfoLog(shader_id, sizeof(log), &log_length, log);
printf("Error in %s: %sn", shader_file_name, log);
}
else
{
return shader_id;
}
}
else
{
printf("Unable to open file %sn", shader_file_name);
}
return -1;
}
// checks for shader program errors
void check_for_errors(int shader_program)
{
int labored;
char info_log[1024];
glGetProgramiv(shader_program, GL_LINK_STATUS, &labored);
if(!labored)
{
glGetShaderInfoLog(shader_program, 1024, NULL, info_log);
printf("Program linking failed: %sn", info_log);
}
}
// takes the already loaded shaders and attaches them to the shader program then deletes them (debugs if vital) and at last returns the shader program
unsigned int load_glsl_shaders(const char* frag_shader_path, const char* vert_shader_path,
const char* tess_control_path, const char* tess_eval_path)
{
unsigned int fragment, vertex, tess_control, tess_eval, program;
fragment = load_shader_file(frag_shader_path, GL_FRAGMENT_SHADER);
vertex = load_shader_file(vert_shader_path, GL_VERTEX_SHADER);
tess_control = load_shader_file(tess_control_path, GL_TESS_CONTROL_SHADER);
tess_eval = load_shader_file(tess_eval_path, GL_TESS_EVALUATION_SHADER);
program = glCreateProgram();
glAttachShader(program, fragment);
glAttachShader(program, vertex);
glAttachShader(program, tess_control);
glAttachShader(program, tess_eval);
glLinkProgram(program);
check_for_errors(program);
glDeleteShader(fragment);
glDeleteShader(vertex);
glDeleteShader(tess_control);
glDeleteShader(tess_eval);
return program;
}
// compiles the shaders and shader program (additionally debugs if vital) then returns the shader program
unsigned int load_embedded_shaders(const char* vertex_shader_text, const char* fragment_shader_text,
const char* tess_control_text, const char* tess_eval_text)
{
GLchar vertex_shader, fragment_shader, tess_control_shader, tess_eval_shader, shader_program;
int compiled;
char info_log[512];
// compile fragment shader
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL);
glCompileShader(fragment_shader);
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &compiled);
if(!compiled)
{
glGetShaderInfoLog(fragment_shader, 512, NULL, info_log);
printf("Fragment shader failed: %sn", info_log);
}
// compile vertex shader
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL);
glCompileShader(vertex_shader);
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &compiled);
if(!compiled)
{
glGetShaderInfoLog(vertex_shader, 512, NULL, info_log);
printf("Vertex shader failed: %sn", info_log);
}
// compile tessellation management shader
tess_control_shader = glCreateShader(GL_TESS_CONTROL_SHADER);
glShaderSource(tess_control_shader, 1, &tess_control_text, NULL);
glCompileShader(tess_control_shader);
glGetShaderiv(tess_control_shader, GL_COMPILE_STATUS, &compiled);
if(!compiled)
{
glGetShaderInfoLog(tess_control_shader, 512, NULL, info_log);
printf("Tessellation management shader failed: %sn", info_log);
}
// compile tessellation analysis shader
tess_eval_shader = glCreateShader(GL_TESS_EVALUATION_SHADER);
glShaderSource(tess_eval_shader, 1, &tess_eval_text, NULL);
glCompileShader(tess_eval_shader);
glGetShaderiv(tess_eval_shader, GL_COMPILE_STATUS, &compiled);
if(!compiled)
{
glGetShaderInfoLog(tess_eval_shader, 512, NULL, info_log);
printf("Tessellation analysis shader failed: %sn", info_log);
}
// compile the shader program
shader_program = glCreateProgram();
glAttachShader(shader_program, fragment_shader);
glAttachShader(shader_program, vertex_shader);
glAttachShader(shader_program, tess_control_shader);
glAttachShader(shader_program, tess_eval_shader);
glLinkProgram(shader_program);
check_for_errors(shader_program);
// deletes the shaders
glDeleteShader(fragment_shader);
glDeleteShader(vertex_shader);
glDeleteShader(tess_control_shader);
glDeleteShader(tess_eval_shader);
// return shader program
return shader_program;
}
// deletes the shader program
void shader_clean_up(unsigned int shader_program)
{
glDeleteProgram(shader_program);
}
// makes use of the shader program
void use_shader(unsigned int shader_program)
{
glUseProgram(shader_program);
}
// units boolean values within the shader program / shader(s) which are linked to it
void set_bool(unsigned int shader_program, const char* title, bool worth)
{
glUniform1i(glGetUniformLocation(shader_program, title), (int)worth);
}
// units integer values within the shader program / shader(s) which are linked to it
void set_int(unsigned int shader_program, const char* title, int worth)
{
glUniform1i(glGetUniformLocation(shader_program, title), worth);
}
// units floating level values within the shader program / shader(s) which are linked to it
void set_float(unsigned int shader_program, const char* title, float worth)
{
glUniform1f(glGetUniformLocation(shader_program, title), worth);
}
// units 2 dimensional matrices within the shader program / shader(s) which are linked to it
void set_mat_2(unsigned int shader_program, const char* title, const mat2 mat)
{
glUniformMatrix2fv(glGetUniformLocation(shader_program, title), 1, GL_FALSE, &mat[0][0]);
}
// units 3 dimensional matrices within the shader program / shader(s) which are linked to it
void set_mat_3(unsigned int shader_program, const char* title, const mat3 mat)
{
glUniformMatrix3fv(glGetUniformLocation(shader_program, title), 1, GL_FALSE, &mat[0][0]);
}
// units 4 dimensional matrices within the shader program / shader(s) which are linked to it
void set_mat_4(unsigned int shader_program, const char* title, const mat4 mat)
{
glUniformMatrix4fv(glGetUniformLocation(shader_program, title), 1, GL_FALSE, &mat[0][0]);
}
// units 2 dimensional vectors within the shader program / shader(s) which are linked to it
void set_vec_2(unsigned int shader_program, const char* title, const vec2 worth)
{
glUniform2fv(glGetUniformLocation(shader_program, title), 1, &worth[0]);
}
// units 2 dimensional vectors with 3d area instructions within the shader program / shader(s) which are linked to it
void set_vec_2_xyz(unsigned int shader_program, const char* title, float x, float y)
{
glUniform2f(glGetUniformLocation(shader_program, title), x, y);
}
// units 3 dimensional vectors within the shader program / shader(s) which are linked to it
void set_vec_3(unsigned int shader_program, const char* title, const vec3 worth)
{
glUniform3fv(glGetUniformLocation(shader_program, title), 1, &worth[0]);
}
// units 3 dimensional vectors with 3d area instructions within the shader program / shader(s) which are linked to it
void set_vec_3_xyz(unsigned int shader_program, const char* title, float x, float y, float z)
{
glUniform3f(glGetUniformLocation(shader_program, title), x, y, z);
}
// units 4 dimensional vectors within the shader program / shader(s) which are linked to it
void set_vec_4(unsigned int shader_program, const char* title, const vec4 worth)
{
glUniform4fv(glGetUniformLocation(shader_program, title), 1, &worth[0]);
}
// units 4 dimensional vectors with 3d area instructions that embrace the w (the element that scales the opposite dimensions) within the shader program / shader(s) which are linked to it
void set_vec_4_wyzx(unsigned int shader_program, const char* title, float x, float y, float z, float w)
{
glUniform4f(glGetUniformLocation(shader_program, title), x, y, z, w);
}
#endif // SHADER_H_INCLUDED
Edit 2:
Shaders getting loaded
unsigned int shader_program = load_glsl_shaders("frag.vert", "vert.vert", "gpu_tcs.vert", "gpu_tes.vert");





