Skip to content

Commit

Permalink
Added support for tessellation shaders. Resolves #73
Browse files Browse the repository at this point in the history
  • Loading branch information
JuanDiegoMontoya committed Apr 22, 2023
1 parent 3308338 commit 86551bf
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 8 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Fwog is interested in providing an abstraction of a *subset* of OpenGL. That mea

- The default uniform block (e.g., uniforms set with glUniform*)
- Alternative: uniform and storage buffers
- Geometry and tessellation control/evaluation shaders
- Geometry shaders
- Alternative: compute shaders
- Multisampled rasterization
- Multiple viewports/layered rendering
Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Caveats
Given Fwog's goals, there are a number of features that the API does not expose:

- The default uniform block (i.e., uniforms set with ``glUniform*``)
- Geometry and tessellation shaders
- Geometry shaders
- Multi-viewport/layered rendering
- Multisampled rasterization
- Transform feedback
Expand Down
4 changes: 3 additions & 1 deletion include/Fwog/BasicTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,9 @@ namespace Fwog
TRIANGLE_LIST,
TRIANGLE_STRIP,
TRIANGLE_FAN,
// TODO: add more toplogies that are deemed useful

/// @note Available only in pipelines with tessellation shaders
PATCH_LIST,
};

enum class PolygonMode : uint32_t
Expand Down
12 changes: 12 additions & 0 deletions include/Fwog/Pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ namespace Fwog
std::span<const VertexInputBindingDescription> vertexBindingDescriptions = {};
};

struct TessellationState
{
uint32_t patchControlPoints; // glPatchParameteri(GL_PATCH_VERTICES, ...)
};

// TODO: see what rasterization state can be dynamic instead
struct RasterizationState
{
Expand Down Expand Up @@ -108,8 +113,15 @@ namespace Fwog
/// @brief Optional pointer to a fragment shader
const Shader* fragmentShader = nullptr;

/// @brief Optional pointer to a tessellation control shader
const Shader* tessellationControlShader = nullptr;

/// @brief Optional pointer to a tessellation evaluation shader
const Shader* tessellationEvaluationShader = nullptr;

InputAssemblyState inputAssemblyState = {};
VertexInputState vertexInputState = {};
TessellationState tessellationState = {};
RasterizationState rasterizationState = {};
DepthState depthState = {};
StencilState stencilState = {};
Expand Down
2 changes: 2 additions & 0 deletions include/Fwog/Shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ namespace Fwog
enum class PipelineStage
{
VERTEX_SHADER,
TESSELLATION_CONTROL_SHADER,
TESSELLATION_EVALUATION_SHADER,
FRAGMENT_SHADER,
COMPUTE_SHADER
};
Expand Down
1 change: 1 addition & 0 deletions include/Fwog/detail/PipelineManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ namespace Fwog::detail
std::string name;
InputAssemblyState inputAssemblyState;
VertexInputStateOwning vertexInputState;
TessellationState tessellationState;
RasterizationState rasterizationState;
DepthState depthState;
StencilState stencilState;
Expand Down
13 changes: 10 additions & 3 deletions src/Rendering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ namespace Fwog
default: FWOG_UNREACHABLE;
}
}

if (ri.stencilAttachment)
{
switch (ri.stencilAttachment->loadOp)
Expand Down Expand Up @@ -638,8 +638,15 @@ namespace Fwog
glBindVertexArray(context->currentVao);
}

//////////////////////////////////////////////////////////////// rasterization
const auto& rs = pipelineState->rasterizationState;
//////////////////////////////////////////////////////////////// tessellation
if (!context->lastGraphicsPipeline || pipelineState->tessellationState.patchControlPoints !=
context->lastGraphicsPipeline->tessellationState.patchControlPoints)
{
glPatchParameteri(GL_PATCH_VERTICES, static_cast<GLint>(pipelineState->tessellationState.patchControlPoints));
}

//////////////////////////////////////////////////////////////// rasterization
const auto& rs = pipelineState->rasterizationState;
if (!context->lastGraphicsPipeline ||
rs.depthClampEnable != context->lastGraphicsPipeline->rasterizationState.depthClampEnable)
{
Expand Down
2 changes: 2 additions & 0 deletions src/Shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ namespace Fwog
switch (stage)
{
case PipelineStage::VERTEX_SHADER: return GL_VERTEX_SHADER;
case PipelineStage::TESSELLATION_CONTROL_SHADER: return GL_TESS_CONTROL_SHADER;
case PipelineStage::TESSELLATION_EVALUATION_SHADER: return GL_TESS_EVALUATION_SHADER;
case PipelineStage::FRAGMENT_SHADER: return GL_FRAGMENT_SHADER;
case PipelineStage::COMPUTE_SHADER: return GL_COMPUTE_SHADER;
default: FWOG_UNREACHABLE; return 0;
Expand Down
25 changes: 23 additions & 2 deletions src/detail/PipelineManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,14 @@ namespace Fwog::detail
return GraphicsPipelineInfoOwning{
.name = std::string(info.name),
.inputAssemblyState = info.inputAssemblyState,
.vertexInputState = {{info.vertexInputState.vertexBindingDescriptions.begin(),
info.vertexInputState.vertexBindingDescriptions.end()}},
.vertexInputState =
{
{
info.vertexInputState.vertexBindingDescriptions.begin(),
info.vertexInputState.vertexBindingDescriptions.end(),
},
},
.tessellationState = info.tessellationState,
.rasterizationState = info.rasterizationState,
.depthState = info.depthState,
.stencilState = info.stencilState,
Expand Down Expand Up @@ -58,13 +64,28 @@ namespace Fwog::detail
uint64_t CompileGraphicsPipelineInternal(const GraphicsPipelineInfo& info)
{
FWOG_ASSERT(info.vertexShader && "A graphics pipeline must at least have a vertex shader");
if (info.tessellationControlShader || info.tessellationEvaluationShader)
{
FWOG_ASSERT(info.tessellationControlShader && info.tessellationEvaluationShader &&
"Either both or neither tessellation shader can be present");
}
GLuint program = glCreateProgram();
glAttachShader(program, info.vertexShader->Handle());
if (info.fragmentShader)
{
glAttachShader(program, info.fragmentShader->Handle());
}

if (info.tessellationControlShader)
{
glAttachShader(program, info.tessellationControlShader->Handle());
}

if (info.tessellationEvaluationShader)
{
glAttachShader(program, info.tessellationEvaluationShader->Handle());
}

std::string infolog;
if (!LinkProgram(program, infolog))
{
Expand Down

0 comments on commit 86551bf

Please sign in to comment.