// OpenGLDemo.cpp: 定义控制台应用程序的入口点。
#include "stdafx.h"
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);
char* readTheFile(string strSource);
const char* vertexShaderSource = readTheFile("vertexShaderSource.vert");
const char* fragmentShaderSource[2] = {
readTheFile("fragmentShaderSource.frag"),
readTheFile("fragmentShaderSource2.frag")
};
class MyTriangle {
public:
float verticesFirst[18] = {
//第一个三角形
0.0f,.5f,0.0f, 1.0f,0.0f,0.0f, //顶部
-.5f,-.5f,.0f, 0.0f,1.0f,0.0f, //左
.5f,-.5f,.0f, 0.0f,0.0f,1.0f//右
};
//生成顶点缓冲对象 ID:VBO
unsigned int VBOs[1];
//生成顶点数组对象 ID:VAO
unsigned int VAOs[1];
//储存 顶点着色器
unsigned int vertexShader;
//储存 片段着色器
unsigned int fragmentShader[1];
//存储 着色器程序
unsigned int shaderProgram[1];
void drawMyGraph(){
vertexShaderInit();
FragmentShaderInit();
shaderProgramLinker();
vertexInput();
}
private:
void vertexInput() {
glGenBuffers(1, VBOs);
glGenVertexArrays(1, VAOs);
// 1. 绑定VAO , VBO
glBindVertexArray(VAOs[0]);
// 2. 复制顶点数组到缓冲中供OpenGL使用
//将缓冲对象 绑定到GL_ARRAY_BUFFER目标
glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);
//定义顶点数据复制到缓冲内存
glBufferData(GL_ARRAY_BUFFER, sizeof(verticesFirst), verticesFirst, 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);
}
void vertexShaderInit() {
//创建一个顶点着色器对象
vertexShader = glCreateShader(GL_VERTEX_SHADER);
//着色器源码附着到着色器对象上
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
//编译着色器对象
glCompileShader(vertexShader);
//检测着色编译是否成功
int success;
char infoLog[22];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
}
void FragmentShaderInit() {
int success;
char infoLog[22];
int len = sizeof(fragmentShader) / sizeof(unsigned int);
for (int i = 0; i < len;i++) {
fragmentShader[i] = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader[i], 1, &fragmentShaderSource[i], NULL);
glCompileShader(fragmentShader[i]);
glGetShaderiv(fragmentShader[i], GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragmentShader[i], 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
}
}
void shaderProgramLinker() {
int len = sizeof(shaderProgram) / sizeof(unsigned int);
for (int i = 0;i < len;i++) {
//创建着色器程序对象
shaderProgram[i] = glCreateProgram();
//附加着色器到着色器程序
glAttachShader(shaderProgram[i], vertexShader);
glAttachShader(shaderProgram[i], fragmentShader[i]);
glLinkProgram(shaderProgram[i]);
int success;
char infoLog[22];
glGetProgramiv(shaderProgram[i], GL_LINK_STATUS,&success);
if (!success) {
glGetProgramInfoLog(shaderProgram[i], 512, NULL, infoLog);
std::cout << "ERROR::SHADER::LINKE_PROGRAM::COMPILATION_FAILED\n" << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader[i]);
}
}
};
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(800, 600, "Oh!I see you!", NULL, NULL);
if (window == NULL) {
std::cout << "Failed to create the windows" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
MyTriangle myTriangle;
myTriangle.drawMyGraph();
glUseProgram(myTriangle.shaderProgram[0]);
while (!glfwWindowShouldClose(window)) {
//输入处理
processInput(window);
//渲染指令
glClearColor(0.2f,0.3f,0.3f,1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(myTriangle.VAOs[0]);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(2, myTriangle.VAOs);
glDeleteBuffers(2, myTriangle.VBOs);
glfwTerminate();
return 0;
}
void framebuffer_size_callback(GLFWwindow* windows, int width, int height) {
glViewport(0, 0, width, height);
}
void processInput(GLFWwindow* window) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
}
//.frag .vert文件读取
char* readTheFile(string strSource) {
std::ifstream myfile(strSource);
std::string str((std::istreambuf_iterator(myfile)),
std::istreambuf_iterator());
//str数组长度一定要 +1,
/*原因: https://blog.csdn.net/ShiQW5696/article/details/80676290 */
int len = str.length();
char* result = new char[len];
strcpy_s(result, len + 1, str.c_str());
return result;
}