"hello triangle"未显示。是否有某些功能未正确使用?

The "hello triangle" is not showing. Is there some function not correctly used?

本文关键字:功能 triangle hello 显示 是否      更新时间:2023-10-16

我的目标是达到这个视频的最终结果:https://www.youtube.com/watch?v=ZpAeH0SpR5Y&list=PL6xSOsbVA1eYSZTKBxnoXYboy7wc4yg-Z&index=13。但是,每当我运行此代码时,它只会给我一个黑屏,即使它没有给出错误。

我尝试使用从 4.4 到 4.6 的所有版本,但都不起作用。VAO、VBO 和 EBO 都是定义的,更改每个函数的细节是行不通的。我唯一的线索是core_program和VAO分别只有3和1,这是可疑的,因为它们应该包含更多数据(在第224行(。 当我下载GLFW时,教程指出从zip使用的文件的方式比您正在使用的Visual Studio版本低一个版本,但是我看到了一个glfw2019文件夹,所以我使用了它。也许这会改变一些东西?顺便说一下,我使用了 GLAD 而不是教程中使用的 GLEW。 另外,很抱歉这里的代码量,但我无法充分隔离问题。(我也做奇怪的名字(

libs.h:

#pragma once
#include <iostream>
#include <glad.h>
#include <glfw3.h>
#include <glm.hpp>
#include <vec2.hpp>
#include <vec3.hpp>
#include <vec4.hpp>
#include <mat4x4.hpp>
#include <gtc/matrix_transform.hpp>
#include <gtc/type_ptr.hpp>
struct Vertex
{
glm::vec3 position;
glm::vec3 color;
glm::vec2 texcoord;
};

Vertexium.glsl:

#version 450
layout (location = 0) in vec3 vertex_position;
layout (location = 1) in vec3 vertex_color;
layout (location = 2) in vec2 vertex_texcoord;
out vec3 vs_position;
out vec3 vs_color;
out vec2 vs_texcoord;
void main()
{
vs_position = vertex_position;
vs_color = vertex_color;
vs_texcoord = vec2(vertex_texcoord.x, vertex_texcoord.y * -1.f);
gl_Position = vec4(vertex_position, 1.f);
}

Fragmentium.glsl:

#version 450
in vec3 vs_position;
in vec3 vs_color;
in vec2 vs_texcoord;
out vec4 fs_color;
void main()
{
fs_color = vec4(vs_color, 1.f);
}

最后,主要.cpp:

#include "libs.h"
#include <fstream>
#include <string>
#include <vector>

//makes window size known
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
//loads shaders, obviously
bool loadShaders(GLuint& program)
{
bool didItWork = true;
char infoLog[512];
GLint success;
std::string temp = "";
std::string src = "";
std::ifstream in_file;
//Vertexium, Activate!
in_file.open("vertexium.glsl");
if (in_file.is_open())
{
while (std::getline(in_file, temp))
src += temp + "n";
}
else
{
std::cout << "The program could not open the vertexium.";
didItWork = false;
}
in_file.close();
//replace with unsigned int if needed
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
const GLchar* vertSrc = src.c_str();
glShaderSource(vertexShader, 1, &vertSrc, NULL);
glCompileShader(vertexShader);
//make sure it's good
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "The vertexium was not successfully compiled." << "n";
std::cout << infoLog << "n";
didItWork = false;
}

//Fragmentium, Activate!
temp = "";
src = "";
in_file.open("fragmentium.glsl");
if (in_file.is_open())
{
while (std::getline(in_file, temp))
src += temp + "n";
}
else
{
std::cout << "The program could not open the fragmentium.";
didItWork = false;
}
in_file.close();
//replace with unsigned int if needed
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
const GLchar* fragSrc = src.c_str();
glShaderSource(fragmentShader, 1, &fragSrc, NULL);
glCompileShader(fragmentShader);
//make sure it's good
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "The fragmentium was not successfully compiled." << "n";
std::cout << infoLog << "n";
didItWork = false;
}
//program thingio
program = glCreateProgram();
//attach
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
//make sure
glGetProgramiv(program, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(program, 512, NULL, infoLog);
std::cout << "The omega program was not successfully linked." << "n";
std::cout << infoLog << "n";
didItWork = false;
}
//end
//start usin'
glUseProgram(0);
//yeetus deletus: we didn't need you
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
return didItWork;
}
//for escaping the system
void processInput(GLFWwindow* window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, GLFW_TRUE);
}
//triangle
Vertex vertices[] = 
{
glm::vec3(0.0f, 0.5f, 0.f),         glm::vec3(1.f, 0.f, 0.f),       glm::vec2(0.f, 1.f),
glm::vec3(-0.5f, -0.5f, 0.f),       glm::vec3(0.f, 1.f, 0.f),       glm::vec2(0.f, 0.f),
glm::vec3(-0.5f, 0.5f, 0.f),        glm::vec3(0.f, 0.f, 1.f),       glm::vec2(1.f, 0.f)
};
//number = nr
unsigned nrOfVertices = sizeof(vertices) / sizeof(Vertex);
GLuint indices[] =
{
0, 1, 2
};
unsigned nrOfIndices = sizeof(indices) / sizeof(GLuint);
//inputs
int main()
{
//instantiation for window (is my favorite word)
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
//time for windows bois

GLFWwindow* window = glfwCreateWindow(800, 600, "yoyleoscopy", NULL, NULL);
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cout << "Failed to initialise GLAD" << std::endl;
}
//make look good and stable sizing
glViewport(0, 0, 800, 600);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
//stock options
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
//here is a program
GLuint core_program;
//load things
if (!loadShaders(core_program))
{
glfwTerminate();
}
//model
//VAO and binding
GLuint VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
//VBO and binding
GLuint VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//EBO and binding
GLuint EBO;
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
//vertexattribpointers and enabling extras (INPUT ASSEMBLY)
//position
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, position));
glEnableVertexAttribArray(0);
//color
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, color));
glEnableVertexAttribArray(1);
//texcoord
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, texcoord));
glEnableVertexAttribArray(2);
//bind VAO 0
if (core_program)
{
std::cout << nrOfIndices;
}
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//VERY IMPORTANT
//THIS IS THE RENDER LOPP
//LOPP IS A MISSPELLING (but i don't care, this makes it more noticeable)
while (!glfwWindowShouldClose(window))
{
//input and stuff
processInput(window);
//RENDER STUFF
//nice color there, chartreuse
glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
//programme
glUseProgram(core_program);
//bind vertex array object
glBindVertexArray(VAO);
//draw
//glDrawElements(GL_TRIANGLES, nrOfIndices, GL_UNSIGNED_INT, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);

//gl background stuff i don't care about
glfwSwapBuffers(window);
glfwPollEvents();
}
//we're over it
glfwDestroyWindow(window);
glfwTerminate();
//delete program
glDeleteProgram(core_program);
return 0;
}

同样,打开的窗口上应该有一个彩虹状三角形,但这会显示一个空白的黑屏。但是,在编译和运行过程中没有错误消息,甚至没有警告。所以希望有人能真正看到这里搞砸了什么。

该问题是由人脸剔除引起的。

三角形的缠绕顺序是顺时针的:

Vertex vertices[] = 
{
glm::vec3(0.0f, 0.5f, 0.f),         glm::vec3(1.f, 0.f, 0.f),       glm::vec2(0.f, 1.f),
glm::vec3(-0.5f, -0.5f, 0.f),       glm::vec3(0.f, 1.f, 0.f),       glm::vec2(0.f, 0.f),
glm::vec3(-0.5f, 0.5f, 0.f),        glm::vec3(0.f, 0.f, 1.f),       glm::vec2(1.f, 0.f)
};
2      0
+----+
|   /
|  /
| /
|/
+
1

但是您已经定义了背面被剔除,正面是逆时针方向的:

glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);

有很多可能性可以解决这个问题。

1种可能性是将定义正面更改为顺时针:

glFrontFace(GL_CW);

另一种可能性是保持glFrontFace(GL_CWW),但使用索引来定义一个逆时针三角形:

GLuint indices[] = { 0, 2, 1 };

并通过索引绘制三角形:

glDrawElements(GL_TRIANGLES, nrOfIndices, GL_UNSIGNED_INT, 0);
//glDrawArrays(GL_TRIANGLES, 0, 3);