1

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)
genpfault
  • 51,148
  • 11
  • 85
  • 139
Basil
  • 488
  • 1
  • 15
  • 2
    Where is the vertex shader located? A shader program consists of a vertex shader and a fragment shader. – Rabbid76 Mar 15 '23 at 16:44
  • 1
    The clear color can be changed with [`glClearColor`](https://registry.khronos.org/OpenGL-Refpages/gl4/html/glClearColor.xhtml), which must be called before `glClear` – Rabbid76 Mar 15 '23 at 16:47
  • 1
    And agreed, at the very least there also needs to be a vertex shader – AnalyticaL Mar 15 '23 at 16:48
  • 1
    I suggest reading a good tutorial. e.g.: https://learnopengl.com/ – Rabbid76 Mar 15 '23 at 16:48
  • @AnalyticaL Ah I see, I was under the impression that I could have a fragment shader without a vertex shader, since in this case I just wanted to apply it to every pixel on the screen rather than specific vertices of a mesh etc. Thanks! – Basil Mar 15 '23 at 16:52

1 Answers1

2

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.

AnalyticaL
  • 501
  • 2
  • 9