Search code examples
c++openglglslsdlfragment-shader

GLSL Fragment Shader not modifying output colour


The shaders compile (I have confirmed this by purposefully making the GLSL code error). In addition, the program is created and linked correctly, as I have checked by printing the value of program and it was non-zero.

However, I am still faced with a blue window (from glClearColor), and not a red one, as I would expect due to the fragment shader I have created.

Code is below:

#include <iostream>

#include <GL/glew.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>

GLuint compile_shader(const char *shader, GLenum type)
{
  GLuint shader_id = glCreateShader(type);

  glShaderSource(shader_id, 1, &shader, NULL);
  glCompileShader(shader_id);
  GLint compiled;

  glGetShaderiv(shader_id, GL_COMPILE_STATUS, &compiled);

  if (!compiled) {
    int length;

    glGetShaderiv(shader_id, GL_INFO_LOG_LENGTH, &length);
    char* message = new char[length];
    glGetShaderInfoLog(shader_id, length, &length, message);

    std::cerr << "Error compiling shader: " << message << std::endl;;
    delete[] message;
    glDeleteShader(shader_id);

    return 0;
  }

  return shader_id;
}

GLuint link_program(GLuint vertex_shader, GLuint frag_shader)
{
  GLuint program = glCreateProgram();

  if (vertex_shader != 0)
    glAttachShader(program, vertex_shader);

  if (frag_shader != 0)
    glAttachShader(program, frag_shader);

  glLinkProgram(program);
  GLint linked;

  glGetProgramiv(program, GL_LINK_STATUS, &linked);

  if (!linked) {
    std::cerr << "Error linking program." << std::endl;
    glDetachShader(program, vertex_shader);
    glDetachShader(program, frag_shader);
    glDeleteProgram(program);

    return 0;
  }

  return program;
}

int main(void)
{
  SDL_Init(SDL_INIT_VIDEO);

  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
  SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

  SDL_Window *window = SDL_CreateWindow("Title", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_OPENGL);

  SDL_GLContext context = SDL_GL_CreateContext(window);
  (void) context;

  glewInit();

 // const char *vert_shader_src = R"GLSL(
 //   #version 430
 //   in vec3 pos;
 //   void main() {
 //     gl_Position = vec4(pos, 1);
 //   }
 //   )GLSL";

  const char *frag_shader_src = R"GLSL(
    #version 130
    void main() {
      gl_FragColor = vec4(1, 0, 0, 1);
    }
  )GLSL";

  glClearColor(.0f, .3f, .7f, 1.f);

  GLuint frag_shader = compile_shader(frag_shader_src, GL_FRAGMENT_SHADER);
  GLuint program = link_program(0, frag_shader);

  SDL_Event event;
  int quit = 0;

  glUseProgram(program);

  while (!quit) {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    while (SDL_PollEvent(&event)) {
      switch (event.type) {
        case SDL_QUIT:
          quit = 1;
          break;
      }
    }

    SDL_GL_SwapWindow(window);
  }

  SDL_DestroyWindow(window);
  SDL_Quit();

  return 0;
}

Here is also my Makefile, in case this has something to do with the compilation process:

CPPFLAGS=-Wall -Wextra -Werror -pedantic -g -std=c++20 $(shell pkg-config --cflags sdl2 glew)
LIBS=$(shell pkg-config --libs sdl2 glew)

sdl_noise: sdl_noise.cpp
    clang++ $(CPPFLAGS) -o sdl_noise sdl_noise.cpp $(LIBS)

Solution

  • You are not rendering anything in the code..

    You just linked a shader, cleared the framebuffer and that is it.

    The shader will only apply to stuff you actually render. Clearing the framebuffer does not count as rendering.