更新: 我通过将类对象Mesh和ShaderLoader创建为指针并将其初始化为new ShaderLoader();来解决了该问题。 我不明白为什么有人可以告诉我那有帮助吗?
我已经开始学习OpenGL,并决定看看我学到了什么。 因此,我创建了此代码,使其可以仅在屏幕上显示三角形。
这是我的顶点着色器:
#version 330
layout (location = 0) in vec3 pos;
out vec4 vCol;
uniform mat4 model;
uniform mat4 projection;
uniform mat4 view;
void main()
{
gl_Position = vec4(pos, 1.0);
vCol = vec4(clamp(pos, 0.0f, 1.0f), 1.0);
}
这是我的片段着色器:
#version 330
in vec4 vCol;
out vec4 colour;
void main()
{
colour = vCol;
}
这是负责加载名为ShaderLoader的着色器的代码
#pragma once
#include <iostream>
#include <GL/glew.h>
#include <fstream>
#include <cstring>
using namespace std;
class ShaderLoader {
public:
char *code; // test public variable
ShaderLoader();
~ShaderLoader();
void clear();
ShaderLoader(const char *vertexPath, const char *fragmentPath);
void AddShaders(GLuint referenceProgram, const char *sourceCode, GLenum referenceEnum);
char* readFile(const char* fileLocation);
void useProgram();
GLuint getProjection() { return uniformProjection; }
GLuint getModel() { return uniformModel; }
GLuint getView() { return uniformView; }
private:
GLuint program, uniformModel, uniformProjection, uniformView;
};
#include "ShaderLoader.h"
ShaderLoader::ShaderLoader()
{
program = 0;
uniformModel = 0;
uniformProjection = 0;
uniformView = 0;
code = nullptr;
}
void ShaderLoader::clear()
{
if (program != 0)
{
glDeleteProgram(program);
program = 0;
}
uniformModel = 0;
uniformProjection = 0;
uniformView = 0;
}
ShaderLoader::~ShaderLoader()
{
clear();
}
char* ShaderLoader::readFile(const char* fileLocation)
{
bool firstCopy = true;
char *continuation = new char[1024];
code = new char[10000];
ifstream file(fileLocation, ios::in);
if (!file.is_open())
{
cout << "Cannot open " << fileLocation << endl;
file.close();
return nullptr;
}
while (!file.eof())
{
char *line = new char[1024];
file.getline(line, strlen(line) - 1);
if (!firstCopy)
{
strcat_s(code, 10000, "\n");
strcat_s(code, 10000, line);
}
if (firstCopy)
{
strcpy_s(code, 10000, line);
firstCopy = false;
}
delete[] line;
}
file.close();
delete[] continuation;
return code;
}
void ShaderLoader::AddShaders(GLuint referenceProgram, const char *sourceCode, GLenum referenceEnum)
{
GLuint shader = glCreateShader(referenceEnum);
if (!shader)
{
cout << " Could not create shader." << endl;
return;
}
const GLchar *src[1];
src[0] = sourceCode;
GLint size[1];
size[0] = strlen(sourceCode);
GLchar log[1024] = { 0 };
int success = 0;
glShaderSource(shader, 1, src, size);
glCompileShader(shader);
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(shader, sizeof(log), nullptr, log);
cout << "Shader compilation failed: " << log <<endl;
return;
}
glAttachShader(program, shader);
}
ShaderLoader::ShaderLoader(const char *vertexPath, const char *fragmentPath)
{
char *vertexSource = readFile(vertexPath);
char *fragmentSource = readFile(fragmentPath);
cout << vertexSource << endl;
cout << fragmentSource << endl;
program = glCreateProgram();
if (!program)
{
std::cout << "Could not create program" << std::endl;
}
AddShaders(program, vertexSource, GL_VERTEX_SHADER);
AddShaders(program, fragmentSource, GL_FRAGMENT_SHADER);
GLchar log[1024] = { 0 };
int success = 0;
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(program, sizeof(log), nullptr, log);
cout << "Program linking failed: " << log << endl;
return;
}
glValidateProgram(program);
glGetProgramiv(program, GL_VALIDATE_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(program, sizeof(log), nullptr, log);
cout << "Program validation failed: " << log << endl;
return;
}
delete[] code;
//uniformModel = glGetUniformLocation(program, "model");
//uniformProjection = glGetUniformLocation(program, "projection");
//uniformView = glGetUniformLocation(program, "view");
}
void ShaderLoader::useProgram()
{
glUseProgram(program);
}
现在,代码用于加载和显示名为 Mesh 的三角形之类的网格:
#pragma once
#include <GL/glew.h>
#include <iostream>
using namespace std;
class Mesh
{
public:
Mesh();
~Mesh();
void createMesh(GLfloat *vertices, unsigned int *indices, unsigned int numOfVertices, unsigned int numOfIndices);
void clearMesh();
void displayMesh();
private:
GLuint VAO, VBO, IBO;
GLsizei indexCount;
};
#include "Mesh.h"
Mesh::Mesh()
{
VAO = 0;
VBO = 0;
IBO = 0;
indexCount = 0;
}
Mesh::~Mesh()
{
clearMesh();
}
void Mesh::createMesh(GLfloat *vertices, unsigned int *indices, unsigned int numOfVertices, unsigned int numOfIndices)
{
indexCount = numOfIndices;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * numOfVertices, vertices, GL_STATIC_DRAW);
glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0]) * numOfIndices, indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void Mesh::displayMesh()
{
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void Mesh::clearMesh()
{
if (VAO != 0)
{
glDeleteVertexArrays(1, &VAO);
VAO = 0;
}
if (VBO != 0)
{
glDeleteBuffers(1, &VBO);
VBO = 0;
}
if (IBO != 0)
{
glDeleteBuffers(1, &IBO);
IBO = 0;
}
indexCount = 0;
}
最后是MAIN:
#include <iostream>
#include "ShaderLoader.h"
#include "Mesh.h"
#include "GLFW/glfw3.h"
#include <GL/glew.h>
#include <glm.hpp>
#include <gtc/matrix_transform.hpp>
#include <gtc/type_ptr.hpp>
const int SCREEN_WIDTH = 800, SCREEN_HEIGHT = 600;
int screenWidth, screenHeight;
Mesh triangle1;
Mesh triangle2;
ShaderLoader shader;
const char* vertexPath = "resources/shaders/shader.vs";
const char* fragmentPath = "resources/shaders/shader.fs";
void createObjects()
{
unsigned int indices[] = {
0, 3, 1,
1, 3, 2,
2, 3, 0,
0, 1, 2
};
GLfloat vertices[] = {
-1.0f, -1.0f, 0.0f,
0.0f, -1.0f, 1.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f
};
triangle1 = Mesh();
triangle1.createMesh(vertices, indices, 12, 12);
triangle2 = Mesh();
triangle2.createMesh(vertices, indices, 12, 12);
cout << "Objects created" << endl;
}
void enableShaders()
{
shader = ShaderLoader(vertexPath, fragmentPath);
cout << "Shaders enabled" << endl;
}
int main()
{
if (!glfwInit())
{
cout << "Could not initialize glfw." << endl;
glfwTerminate();
return 1;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
GLFWwindow *window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "GoldSpark Engine Test", nullptr, nullptr);
glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
if (window == nullptr)
{
cout << "Window could not be created." << endl;
glfwDestroyWindow(window);
glfwTerminate();
}
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK)
{
cout << "Could not initialize GLEW";
glfwDestroyWindow(window);
glfwTerminate();
return 1;
}
glewExperimental = true;
glEnable(GL_DEPTH_TEST);
enableShaders();
createObjects();
glViewport(0, 0, screenWidth, screenHeight);
while(!glfwWindowShouldClose(window))
{
glfwPollEvents();
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shader.useProgram();
triangle1.displayMesh();
glUseProgram(0);
glfwSwapBuffers(window);
}
triangle1.clearMesh();
triangle2.clearMesh();
shader.clear();
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
我试图在这里找到为什么我的三角形没有变色而我不能。我尝试将片段着色器中的变量 color 初始化为 vec4(1.0f,0.0f,0.0f,1.0f) >但它仍然没有画出来。三角形仍然是黑色。我在这里想念什么,谁能告诉我?
如果您发现这很复杂,请阅读github代码,以便您可以复制/粘贴并查看出了什么问题: