1
\$\begingroup\$

I'm trying to create a tessellated terrain, for this purposes I'm following the LearnOpenGL tutorial: https://learnopengl.com/Guest-Articles/2021/Tessellation/Tessellation

However, when I set the number of vertices per patch, with glPatchParameteri(GL_PATCH_VERTICES, 4), I have an acces violation exception. I use GLAD and I have created a Terrain class to set the terrain data to send to the GPU. Here the code of terrain class:

#include "TerrainGeneration.h"
TerrainGeneration::TerrainGeneration(int numberOfPatches) : 
numberOfPatches{numberOfPatches}
{
  const int newSize = 4 * numberOfPatches * numberOfPatches;
  vertices.reserve(newSize);
  GenerateTerrainPatches();
  SetupDataBuffers();
}

void TerrainGeneration::GenerateTerrainPatches()
{
  float FnumberOfPatch = static_cast<float>(numberOfPatches);
  for(int i = 0; i < numberOfPatches; i++)
  {
    
    for (int j = 0; j < numberOfPatches; j++)
    {
        float Fi = static_cast<float>(i);
        float Fj = static_cast<float>(j);
        TerrainVertex FirstVertex;

        FirstVertex.Position = glm::vec3
        {
            -TERRAIN_DIM / 2.0f + TERRAIN_DIM * Fi / FnumberOfPatch,
            0.0f,
            -TERRAIN_DIM / 2.0f + TERRAIN_DIM * Fj / FnumberOfPatch
        };

        FirstVertex.UVCoord = glm::vec2
        {
            Fi / FnumberOfPatch,
            Fj / FnumberOfPatch
        };

        FirstVertex.Normal = glm::vec3
        {
            0.0f,
            1.0f,
            0.0f
        };


        TerrainVertex SecondVertex;

        SecondVertex.Position = glm::vec3
        {
            -TERRAIN_DIM / 2.0f + TERRAIN_DIM * (Fi + 1.0f) / FnumberOfPatch,
            0.0f,
            -TERRAIN_DIM / 2.0f + TERRAIN_DIM * Fj / FnumberOfPatch
        };

        SecondVertex.UVCoord = glm::vec2
        {
            (Fi + 1.0f) / FnumberOfPatch,
            Fj / FnumberOfPatch
        };

        SecondVertex.Normal = glm::vec3
        {
            0.0f,
            1.0f,
            0.0f
        };


        TerrainVertex ThirdVertex;

        ThirdVertex.Position = glm::vec3
        {
            -TERRAIN_DIM / 2.0f + TERRAIN_DIM * Fi / FnumberOfPatch,
            0.0f,
            -TERRAIN_DIM / 2.0f + TERRAIN_DIM * (Fj + 1.0f) / FnumberOfPatch
        };

        ThirdVertex.UVCoord = glm::vec2
        {
            Fi  / FnumberOfPatch,
            (Fj + 1.0f) / FnumberOfPatch
        };

        ThirdVertex.Normal = glm::vec3
        {
            0.0f,
            1.0f,
            0.0f
        };

        TerrainVertex FourthVertex;

        FourthVertex.Position = glm::vec3
        {
            -TERRAIN_DIM / 2.0f + TERRAIN_DIM * (Fi + 1.0f) / FnumberOfPatch,
            0.0f,
            -TERRAIN_DIM / 2.0f + TERRAIN_DIM * (Fj + 1.0f) / FnumberOfPatch
        };

        FourthVertex.UVCoord = glm::vec2
        {
            (Fi + 1.0f) / FnumberOfPatch,
            (Fj + 1.0f) / FnumberOfPatch
        };

        FourthVertex.Normal = glm::vec3
        {
            0.0f,
            1.0f,
            0.0f
        };
        vertices.emplace_back(FirstVertex);
        vertices.emplace_back(SecondVertex);
        vertices.emplace_back(ThirdVertex);
        vertices.emplace_back(FourthVertex);
    }
 }
}


void TerrainGeneration::SetupDataBuffers()
{
  glGenVertexArrays(1, &VAO);
  glGenBuffers(1, &VBO);

  glBindVertexArray(VAO);
  glBindBuffer(GL_ARRAY_BUFFER, VBO);


  glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(TerrainVertex), 
  vertices.data(), GL_STATIC_DRAW);

  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(TerrainVertex), (void*)0);
  glEnableVertexAttribArray(0);

  glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(TerrainVertex), (void*)(3 * 
  sizeof(float)));
  glEnableVertexAttribArray(1);

  glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(TerrainVertex), (void*)(5 * 
  sizeof(float)));
  glEnableVertexAttribArray(2);

  //---Here the exception occurs!---
  glPatchParameteri(GL_PATCH_VERTICES, 4);

}

void TerrainGeneration::DrawTerrain()
{
  glDrawArrays(GL_PATCHES, 0, 4 * numberOfPatches * numberOfPatches);
}

void TerrainGeneration::DeleteBuffers()
{
  glDeleteBuffers(1, &VBO);
  glDeleteVertexArrays(1, &VAO);
}

Thanks everyone.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I have solved the problem. I post the solution for the future. I have chanced the Application.cpp code from:

// glfw: initialize and configure
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

To:

// glfw: initialize and configure
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

The tessellation shader is only available starting by OpenGL 4.0.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .