着色器已成功链接,但未在屏幕上显示

sbtkgmzw  于 2022-09-26  发布在  其他
关注(0)|答案(1)|浏览(156)

我已经实现了一个系统,从理论上讲,它可以遍历活动实体的列表,并绘制与每个实体相关联的着色器(假设它有一个)。然而,无论我尝试了什么,都没有显示在屏幕上。

我已经确认每个组件都被正确地创建/加载,并且数据确实在那里,我不仅仅是指向空。

这是我的Sprite渲染系统(还没有实现纹理)和:


# include "../ECS.h"

# define XTILES 64

# define YTILES 36

void renderSprites(ECS* ecs, int width, int height) {
  if (!ecs)
    return;

  for (Entity entity = 0; entity < (ecs -> entities -> count); entity++) {
    if (isLiving(ecs, entity)) {
      Shader* shader = (Shader*) getComponent(ecs, entity, SHADER);
      Texture* texture = (Texture*) getComponent(ecs, entity, TEXTURE);
      Transform* transform = (Transform*) getComponent(ecs, entity, TRANSFORM);

      if (!shader || !transform)
        continue;

      if (!(shader -> generated)) {
        glGenVertexArrays(1, &(shader -> VAO));
        glGenBuffers(1, &(shader -> VBO));
        glGenBuffers(1, &(shader -> EBO));
        glBindVertexArray(shader -> VAO);
        shader -> generated = 1;
      }

      // Make it changeable for textures
      float vertices[] = {
        (((transform -> position)[0] + 0.5f) / (XTILES / 2)), (((transform -> position)[1] + 0.5f) / (YTILES / 2)), 0.0f,   1.0f, 0.0f, 0.0f,
        (((transform -> position)[0] + 0.5f) / (XTILES / 2)), (((transform -> position)[1] - 0.5f) / (YTILES / 2)), 0.0f,   1.0f, 1.0f, 0.0f,
        (((transform -> position)[0] - 0.5f) / (XTILES / 2)), (((transform -> position)[1] - 0.5f) / (YTILES / 2)), 0.0f,   0.0f, 1.0f, 0.0f,
        (((transform -> position)[0] - 0.5f) / (XTILES / 2)), (((transform -> position)[1] + 0.5f) / (YTILES / 2)), 0.0f,   0.0f, 0.0f, 1.0f,
      };

      unsigned int indices[] = {
        0, 1, 3,
        1, 2, 3
      };

      glBindBuffer(GL_ARRAY_BUFFER, shader -> VBO);
      glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, shader -> EBO);
      glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

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

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

      if (texture)
        glBindTexture(GL_TEXTURE_2D, texture -> data);

      glClear(GL_COLOR_BUFFER_BIT);
      glUseProgram(shader -> data);
      glBindVertexArray(shader -> VAO);
      glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    }
  }
}

我如何调用主循环中的方法:

//...
last = time();
while (!app.quit) {
  resetInput();

  now = time();
  delta = now - last;

  if (delta > (1000 / app.fps)) {
    last = now;
    inputProc(&app);

    frame();
    renderSprites(app.ecs, app.width, app.height);
    SDL_GL_SwapWindow(app -> window);
    SDL_Delay(1);
  }
}
//...

我试图仅使用我的着色器代码创建一个最小的可重复使用的示例,但我创建的示例代码实际上起作用了,并在屏幕上呈现了一个正方形:


# define WIDTH 600

# define HEIGHT 600

# define XTILES 24

# define YTILES 24

# define GLEW_STATIC

# define NO_SDL_GLEXT

# include <GL/glew.h>

# include <SDL2/SDL.h>

# include <SDL2/SDL_opengl.h>

# include <stdio.h>

# include <stdlib.h>

# include <string.h>

# define BUFFSIZE 1024

# define MAXSIZE 1048576

typedef struct Shader {
  int generated;
  unsigned int data;
  unsigned int VBO, VAO, EBO;
} Shader;

char* loadshader(char*);
Shader* createShader(char* vertexfile, char* fragmentfile) {
  const char* vertexcode = loadshader(vertexfile);
  unsigned int vertex = glCreateShader(GL_VERTEX_SHADER);
  glShaderSource(vertex, 1, &vertexcode, NULL);
  glCompileShader(vertex);

  {
    char log[1024]; int success; glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
    if (!success) {
      glGetShaderInfoLog(vertex, 1024, NULL, log);
      printf("Vertex Shader Failed to Compile!n> OpenGL Error: %sn", log);
    }
  }

  const char* fragmentcode = loadshader(fragmentfile);
  unsigned int fragment = glCreateShader(GL_FRAGMENT_SHADER);
  glShaderSource(fragment, 1, &fragmentcode, NULL);
  glCompileShader(fragment);

  {
    char log[1024]; int success; glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
    if (!success) {
      glGetShaderInfoLog(fragment, 1024, NULL, log);
      printf("Fragment Shader Failed to Compile!n> OpenGL Error: %sn", log);
    }
  }

  unsigned int data = glCreateProgram();
  glAttachShader(data, vertex);
  glAttachShader(data, fragment);
  glLinkProgram(data);

  {
    char log[1024]; int success; glGetProgramiv(data, GL_LINK_STATUS, &success);
    if (!success) {
      glGetProgramInfoLog(data, 1024, NULL, log);
      printf("Shader Failed to Link!n> OpenGL Error: %s", log);
    }
  }

  glDeleteShader(vertex);
  glDeleteShader(fragment);
  free((void*) vertexcode);
  free((void*) fragmentcode);

  Shader* shader = (Shader*) malloc(sizeof(Shader));
  shader -> data = data;
  shader -> generated = 0;
  return shader;
}

void renderSprite(SDL_Window*, Shader*, float*);
int WinMain(int argc, char const *argv[]) {
  SDL_Init(SDL_INIT_VIDEO);
  SDL_Window* window = SDL_CreateWindow("Basic Window", 960, 170, WIDTH, HEIGHT, SDL_WINDOW_OPENGL);
  SDL_GLContext context = SDL_GL_CreateContext(window);
  glewInit();

  Shader* shader = createShader("data/02.vs", "data/02.fs");
  float position[] = {0.0f, 0.0f};
  renderSprite(window, shader, position);
  SDL_Delay(2500);

  position[0] = 0.75f + (XTILES / 3); position[1] = 0.75f + (YTILES / 3);
  renderSprite(window, shader, position);
  SDL_Delay(1250);

  position[0] = 0.75f + (XTILES / 3); position[1] = -0.75f - (YTILES / 3);
  renderSprite(window, shader, position);
  SDL_Delay(1250);

  position[0] = -0.75f - (XTILES / 3); position[1] = -0.75f - (YTILES / 3);
  renderSprite(window, shader, position);
  SDL_Delay(1250);

  position[0] = -0.75f - (XTILES / 3); position[1] = 0.75f + (YTILES / 3);
  renderSprite(window, shader, position);
  SDL_Delay(1250);

  position[0] = 0.0f; position[1] = 0.0f;
  renderSprite(window, shader, position);
  SDL_Delay(2500);
  return 0;
}

void renderSprite(SDL_Window* window, Shader* shader, float position[2]) {
  if (!shader)
    return;

  if (!(shader -> generated)) {
    printf("%sn", "Generating Shader Buffers");
    glGenVertexArrays(1, &(shader -> VAO));
    glGenBuffers(1, &(shader -> VBO));
    glGenBuffers(1, &(shader -> EBO));
    glBindVertexArray(shader -> VAO);
    shader -> generated = 1;
  }

  float vertices[] = {
    ((position[0] + 0.5f) / (XTILES / 2)), ((position[1] + 0.5f) / (YTILES / 2)), 0.0f,   1.0f, 0.0f, 0.0f,
    ((position[0] + 0.5f) / (XTILES / 2)), ((position[1] - 0.5f) / (YTILES / 2)), 0.0f,   1.0f, 1.0f, 0.0f,
    ((position[0] - 0.5f) / (XTILES / 2)), ((position[1] - 0.5f) / (YTILES / 2)), 0.0f,   0.0f, 1.0f, 0.0f,
    ((position[0] - 0.5f) / (XTILES / 2)), ((position[1] + 0.5f) / (YTILES / 2)), 0.0f,   0.0f, 0.0f, 1.0f,
  };

  unsigned int indices[] = {
    0, 1, 3,
    1, 2, 3
  };

  glBindBuffer(GL_ARRAY_BUFFER, shader -> VBO);
  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, shader -> EBO);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

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

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

  glClear(GL_COLOR_BUFFER_BIT);
  glUseProgram(shader -> data);
  glBindVertexArray(shader -> VAO);
  glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
  SDL_GL_SwapWindow(window);
  SDL_Delay(1);
}

char* loadshader(char* filename) {
  FILE* file = fopen(filename, "r");
  if (!file)
    return NULL;

  int flag = 0;
  char* shader = (char*) malloc(MAXSIZE);
  char* buffer = (char*) malloc(BUFFSIZE);
  while (fgets(buffer, BUFFSIZE, file) != NULL)
    strcat(shader, buffer);

  free(buffer);
  fclose(file);
  return shader;
}

解决方案:显然,错误不在我的渲染代码中,而在我的着色器中。我已经更改了顶点和碎片着色器中变量的名称,OpenGL不喜欢这样。在我将其改回默认名称后,一切都开始正常工作。

zmeyuzjn

zmeyuzjn1#

解决方案:显然,错误不在我的渲染代码中,而在我的着色器中。我已经更改了顶点和碎片着色器中变量的名称,OpenGL不喜欢这样。在我将其改回默认名称后,一切都开始正常工作。

相关问题