I am trying to make the https://learnopengl.com/Getting-started/Textures example in pure C (hate C++) and found this weird problem in my quadrilateral when one of their conforming triangles is being rendered well and the other looks like the vertical texture coordinate has been fixed meanwhile the horizontal is perfectly well. Example

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)

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;
}

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_

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);
  }
}

src/stb_image.c:

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

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);
}

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;
}

推荐答案

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

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

需要替换为

glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6* sizeof(float)));

还请通过拨打glGetError()或设置调试回调来判断OpenGL错误.由于您使用的是3.3核心配置文件,因此不推荐使用像glMatrixMode这样的方法,并且应该会导致GL_INVALID_OPERATION错误.

C++相关问答推荐

为什么在传输 Big Data 时共享内存段的运行时间比管道更长?

在C中使用JMP_buf数组进行线程化(在xv6中测试)

__VA_OPT__(,)是否可以检测后面没有任何内容的尾随逗号?

减法运算结果的平方的最快方法?

在列表中插入Int指针(C)

X86/x64上的SIGSEGV,由于原始内存访问和C中的DS寄存器之间的冲突,在Linux上用TCC编译为JIT引擎

在我的代码中,我需要在哪里编写输出函数?

每次除以或乘以整数都会得到0.0000

将返回的char*设置为S在函数中定义的字符串文字可能会产生什么问题?

为什么Fread()函数会读取内容,然后光标会跳到随机位置?

错误...的多个定义(&Q)首先在这里定义&

仅从限制指针参数声明推断非混叠

我在C程序的Flex/Bison中遇到语法错误

C标准关于外部常量的说明

如何在C宏定义中包含双引号?

UpDown控制与预期相反

我正在使用 klib 库 我可以使用 (khash) KHASH_SET_INIT_INT64() 负值作为键.因为我在头文件中看到它使用 unsigned long int

传递参数:C 和 C++ 中 array 与 *&array 和 &array[0] 的区别

在 C/C++ 中原子按位与字节的最佳方法?

C 预处理器中的标记分隔符列表