基本 OpenGL 纹理四边形中的三角形之一中的伪影

Del*_*fin 3 c opengl glsl glfw

我试图以纯粹的方式制作https://learnopengl.com/Getting-started/TexturesC示例(讨厌C++),并在我的四边形中发现了这个奇怪的问题,其中一个一致的三角形渲染得很好,而另一个看起来像垂直的纹理坐标已被固定,同时水平方向也完美无缺。 例子

meson.build:

project('snake', 'c',
  version : '0.1',
  default_options : ['warning_level=3'])

cc = meson.get_compiler('c')
m_dep = cc.find_library('m', required : true)
openGl = dependency('gl')
glfw3 = dependency('glfw3')

executable('snake',
           'src/main.c',
           'src/shaders.c',
           'src/stb_image.c',
           dependencies : [ m_dep, openGl, glfw3 ],
           install : true)
Run Code Online (Sandbox Code Playgroud)

src/main.h:

#include <stdlib.h>
#include <stdio.h>
#include <GLFW/glfw3.h>
#include <sys/stat.h>
#include "shaders.h"
#include "stb_image.h"

// https://learnopengl.com/Getting-started/Transformations

static void error_callback(int error, const char* description) {
  fprintf(stderr, "ERROR: Beschreibung: %s und Code: %i\n", description, error);
}

static void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
  glViewport(0, 0, width, height);
}

static void processInput(GLFWwindow *window) {
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
        glfwSetWindowShouldClose(window, 1);
    }
}

int main(int argc, char **args) {
  GLFWwindow* window;
  glfwSetErrorCallback(error_callback);

  if (!glfwInit()) {
    return EXIT_FAILURE;
  }

  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

  // sk_init();
  window = glfwCreateWindow(1024, 720, "SNAKE", NULL, NULL);

  if (!window) {
    perror("Failed to create GLFW\n");
    glfwTerminate();
    return EXIT_FAILURE;
  }

  printf("Ein GLFW Fenster habt geschaffen\n");

  glfwMakeContextCurrent(window);
  glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

  glViewport(0, 0, 1024, 702);

  GLint shaderProgram;
  shader_from_path("../shaders/ve1.glsl", "../shaders/fr1.glsl", &shaderProgram);

  float vertices[] = {
    // positions          // colors           // texture coords
         0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f, // top right
         0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f, // bottom right
        -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // bottom left
        -0.5f,  0.5f, 0.0f,   0.0f, 1.0f, 1.0f,   0.0f, 1.0f  // top left
  };

  unsigned int indices[] = {  // note that we start from 3!
    3, 2, 0,
    2, 1, 0,
  };

  unsigned int VBO, EBO, VAO;
  glGenVertexArrays(1, &VAO);
  glGenBuffers(1, &VBO);
  glGenBuffers(1, &EBO);

  glBindVertexArray(VAO);

  glBindBuffer(GL_ARRAY_BUFFER, VBO);
  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

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

  glBindBuffer(GL_ARRAY_BUFFER, 0);
  glBindVertexArray(0);

  GLuint texture;
  glGenTextures(1, &texture);
  glActiveTexture(GL_TEXTURE0); // activate the texture unit first before binding texture
  glBindTexture(GL_TEXTURE_2D, texture);

  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

  int width, height, nrChannels;

  unsigned char *data = stbi_load("wall.jpg", &width, &height, &nrChannels, 0);

  if (data) {
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, width, height);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);
    //glGenerateMipmap(GL_TEXTURE_2D);
  } else {
    fprintf(stderr, "Failed to load texture\n");
  }

  stbi_image_free(data);

  glMatrixMode(GL_PROJECTION);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  //glfwSetKeyCallback(window, onKey);

  while (!glfwWindowShouldClose(window)) {
    processInput(window);

    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glUseProgram(shaderProgram);
    glBindTexture(GL_TEXTURE_2D, texture);
    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

    glfwPollEvents();
    glfwSwapBuffers(window);
  }

  glDeleteVertexArrays(1, &VAO);
  glDeleteBuffers(1, &VBO);
  glDeleteBuffers(1, &EBO);
  glDeleteProgram(shaderProgram);

  glfwTerminate();
  return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

src/shaders.h:

#ifndef SHADERS_H_
#define SHADERS_H_

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <GLFW/glfw3.h>

void shader_from_path(const char* vertexPath, const char* fragmentPath, GLuint* ID);

#endif // SHADERS_H_
Run Code Online (Sandbox Code Playgroud)

src/shaders.c:

#include "shaders.h"
#include <sys/stat.h>

const char *vertexShaderSource = "#version 330 core\n"
    "layout (location = 0) in vec3 aPos;\n"
    "void main()\n"
    "{\n"
    "   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
    "}\0";
const char *fragmentShaderSource = "#version 330 core\n"
    "out vec4 FragColor;\n"
    "void main()\n"
    "{\n"
    "   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
    "}\n\0";


struct TextBuffer {
  char* inhalt;
  size_t size;
};

static void checkCompileErrors(const GLint handler) {
  int success;
  char infoLog[512];
  for (int i = 0; i < 512; i++) {
    infoLog[i] = 0;
  }

  glGetShaderiv(handler, GL_COMPILE_STATUS, &success);
  if (&success) {
    glGetShaderInfoLog(handler, 512, NULL, infoLog);
    fwrite(infoLog, sizeof(char), 512, stderr);
  }
}

static int openAndReadPath(const char* path, struct TextBuffer* store) {
  struct stat st;
  FILE *file = fopen(path, "r");
  if (!file) {
    printf("Konnt nicht lesen: %s\n", path);
    return 0;
  }

  stat(path, &st);
  store->size = st.st_size;

  store->inhalt = (char*) malloc(sizeof(char) * (store->size + 1));
  fread(store->inhalt, sizeof(char), store->size, file);
  fwrite(store->inhalt, sizeof(char), store->size, stdout);
  fclose(file);

  return 1;
}

void shader_from_path(const char* vertexPath, const char* fragmentPath, GLuint* ID) {
  struct TextBuffer vertexTextBuffer;
  struct TextBuffer fragmentTextBuffer;

  openAndReadPath(vertexPath, &vertexTextBuffer);
  openAndReadPath(fragmentPath, &fragmentTextBuffer);

  GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
  glShaderSource(vertexShader, 1, &vertexTextBuffer.inhalt, &vertexTextBuffer.size);
  glCompileShader(vertexShader);
  checkCompileErrors(vertexShader);

  GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  glShaderSource(fragmentShader, 1, &fragmentTextBuffer.inhalt, &fragmentTextBuffer.size);
  glCompileShader(fragmentShader);
  checkCompileErrors(fragmentShader);

  *ID = glCreateProgram();
  glAttachShader(*ID, vertexShader);
  glAttachShader(*ID, fragmentShader);
  glLinkProgram(*ID);
  checkCompileErrors(*ID);

  glDeleteShader(vertexShader);
  glDeleteShader(fragmentShader);

  if (vertexTextBuffer.inhalt) {
    free(vertexTextBuffer.inhalt);
  }
  if (fragmentTextBuffer.inhalt) {
    free(fragmentTextBuffer.inhalt);
  }
}
Run Code Online (Sandbox Code Playgroud)

src/stb_image.c:

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
Run Code Online (Sandbox Code Playgroud)

src/stb_image.h: https: //raw.githubusercontent.com/nothings/stb/master/stb_image.h shaders/fr1.glsl

#version 330 core
out vec4 FragColor;

in vec3 vertexColor;
in vec2 TexCoord;
// uniform vec4 ourColor;

uniform sampler2D ourTexture;

void main()
{
    FragColor = texture(ourTexture, TexCoord); // vec4(vertexColor, 1.0);
}
Run Code Online (Sandbox Code Playgroud)

shaders/ve1.glsl:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;

out vec3 vertexColor;
out vec2 TexCoord;

void main()
{
    gl_Position = vec4(aPos, 1.0);
    vertexColor = aColor;
    TexCoord = aTexCoord;
}
Run Code Online (Sandbox Code Playgroud)

BDL*_*BDL 6

第二个参数glVertexAttribPointer指定应读取多少个元素。由于 uv 坐标仅由两个元素组成,因此该行

glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6* sizeof(float)));
Run Code Online (Sandbox Code Playgroud)

需要替换为

glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6* sizeof(float)));
Run Code Online (Sandbox Code Playgroud)

glGetError()另请通过调用或设置调试回调来检查 OpenGL 错误。由于您使用的是 3.3 核心配置文件,因此类似的方法glMatrixMode已被弃用,并且会导致 GL_INVALID_OPERATION 错误。