OpenGL 笔记

2017-07-30  框架  ,,  303

学一下OpenGL吧。

推荐教程:

  1. Learn OpenGL
  2. Learn OpenGL的翻译版

我就在这记下笔记和代码吧~

1.4 Hello Triangle

// main.cpp
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <cstdlib>
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>

using std::cout;
using std::endl;
using std::string;

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

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

string readShader(const char* name) {
    static const int SIZE = 1024 * 10;
    static char data[SIZE];
    FILE* fio;
    string res;
    if (fopen_s(&fio, name, "r")) {
        return res;
    }
    for (int len = fread(data, sizeof(char), SIZE, fio); len; len = fread(data, sizeof(char), SIZE, fio)) {
        res.append(data, len);
    }
    return res;
}

GLuint creatShader(GLenum type, const char* name) {
    GLuint shader = glCreateShader(type);
    int success;
    string src = readShader(name);
    const char* str = src.c_str();
    glShaderSource(shader, 1, &str, NULL);
    glCompileShader(shader);
    glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
    if (!success) {
        char infoLog[512];
        glGetShaderInfoLog(shader, 512, NULL, infoLog);
        cout << "Compiling shader from \"" << name << "\" has been FAILED:\n" << infoLog << endl;
    }
    return shader;
}

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, "gl1", NULL, NULL);

    if (window == NULL) {
        cout << "failed 1" << endl;
        return -1;
    }

    glfwMakeContextCurrent(window);

    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
        cout << "failed 2" << endl;
        return -1;
    }

    glViewport(0, 0, 800, 600);

    glfwSetFramebufferSizeCallback(window, frameBufferSizeCallback);

    // === shader ===
    GLuint vertexShader = creatShader(GL_VERTEX_SHADER, "basic.vert");
    GLuint fragmentShader = creatShader(GL_FRAGMENT_SHADER, "basic.frag");
    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    glUseProgram(shaderProgram);

    // === vertex ===
    GLfloat vertices[] = {
        -0.5, -0.5, 0.0,
        0.5, -0.5, 0.0,
        0.5, 0.5, 0.0,
        -0.5, 0.5, 0.0
    };
    GLuint indices[] = {
        0, 1, 2,
        0, 2, 3
    };
    GLuint VAO, VBO, EBO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);

    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*)0);
    glEnableVertexAttribArray(0);

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

        glClearColor(0.5, 0.5, 0.5, 1);
        glClear(GL_COLOR_BUFFER_BIT);

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

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

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

    glfwTerminate();
    return 0;
}
// basic.vert
#version 330 core
layout (location = 0) in vec3 aPos;

void main() {
    gl_Position = vec4(aPos, 1.0);
}
//basic.frag
#version 330 core
out vec4 FragColor;

void main() {
    FragColor = vec4(0.5, 0.0, 0.0, 1.0);
}

1.5 Shaders

1.5.1

// main.cpp
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <cstdlib>
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>

using std::cout;
using std::endl;
using std::string;

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

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

string readShader(const char* name) {
    static const int SIZE = 1024 * 10;
    static char data[SIZE];
    FILE* fio;
    string res;
    if (fopen_s(&fio, name, "r")) {
        return res;
    }
    for (int len = fread(data, sizeof(char), SIZE, fio); len; len = fread(data, sizeof(char), SIZE, fio)) {
        res.append(data, len);
    }
    return res;
}

GLuint creatShader(GLenum type, const char* name) {
    GLuint shader = glCreateShader(type);
    int success;
    string src = readShader(name);
    const char* str = src.c_str();
    glShaderSource(shader, 1, &str, NULL);
    glCompileShader(shader);
    glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
    if (!success) {
        char infoLog[512];
        glGetShaderInfoLog(shader, 512, NULL, infoLog);
        cout << "Compiling shader from \"" << name << "\" has been FAILED:\n" << infoLog << endl;
    }
    return shader;
}

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, "gl1", NULL, NULL);

    if (window == NULL) {
        cout << "failed 1" << endl;
        return -1;
    }

    glfwMakeContextCurrent(window);

    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
        cout << "failed 2" << endl;
        return -1;
    }

    glViewport(0, 0, 800, 600);

    glfwSetFramebufferSizeCallback(window, frameBufferSizeCallback);

    // === shader ===
    GLuint vertexShader = creatShader(GL_VERTEX_SHADER, "basic.vert");
    GLuint fragmentShader = creatShader(GL_FRAGMENT_SHADER, "basic.frag");
    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    glUseProgram(shaderProgram);

    // === vertex ===
    GLfloat vertices[] = {
        -0.5, -0.5, 0.0, 1.0, 0.0, 0.0,
        0.5,  -0.5, 0.0, 0.0, 1.0, 0.0,
        0.0,  0.5,  0.0, 0.0, 0.0, 1.0
    };
    GLuint VAO, VBO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);

    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)0);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

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

        glClearColor(0.5, 0.5, 0.5, 1);
        glClear(GL_COLOR_BUFFER_BIT);

        glDrawArrays(GL_TRIANGLES, 0, 3);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

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

    glfwTerminate();
    return 0;
}
// basic.vert
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aCol;
out vec3 ourColor;

void main() {
    gl_Position = vec4(aPos, 1.0);
    ourColor = aCol;
}
// basic.frag
#version 330 core
out vec4 FragColor;
in vec3 ourColor;

void main() {
    FragColor = vec4(ourColor, 1.0);
}

1.5.2

// Shader.h
#pragma once
#include <glad/glad.h>
#include <cstdlib>
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>

class Shader {
public:
    Shader(const char* vertexShaderName, const char* fragmentShaderName);
    ~Shader();
    void use();

private:
    GLuint shaderProgram;

    std::string readShader(const char* name);
    GLuint creatShader(GLenum type, const char* name);
};
// Shader.cpp
#include "Shader.h"

Shader::Shader(const char * vertexShaderName, const char * fragmentShaderName) {
    GLuint vertexShader = creatShader(GL_VERTEX_SHADER, vertexShaderName);
    GLuint fragmentShader = creatShader(GL_FRAGMENT_SHADER, fragmentShaderName);

    shaderProgram = glCreateProgram();
    GLint success;
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if (!success) {
        char infoLog[512];
        glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
        std::cout << "Program linking FAILED:\n" << infoLog << std::endl;
    }

    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
}

Shader::~Shader() {
}

void Shader::use() {
    glUseProgram(shaderProgram);
}

std::string Shader::readShader(const char* name) {
    static const int SIZE = 1024 * 10;
    static char data[SIZE];
    FILE* fio;
    std::string res;
    if (fopen_s(&fio, name, "r")) {
        return res;
    }
    for (int len = fread(data, sizeof(char), SIZE, fio); len; len = fread(data, sizeof(char), SIZE, fio)) {
        res.append(data, len);
    }
    return res;
}

GLuint Shader::creatShader(GLenum type, const char* name) {
    GLuint shader = glCreateShader(type);
    GLint success;
    std::string src = readShader(name);
    const char* str = src.c_str();
    glShaderSource(shader, 1, &str, NULL);
    glCompileShader(shader);
    glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
    if (!success) {
        char infoLog[512];
        glGetShaderInfoLog(shader, 512, NULL, infoLog);
        std::cout << "Compiling shader from \"" << name << "\" has been FAILED:\n" << infoLog << std::endl;
    }
    return shader;
}

欢迎留言>_<

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据