MSYS2のMINGW64 → pacman やOpenGL関連ライブラリがインストール可能 な環境でGLSLを描画できた。 FBX Viewerを作る Vol.1

memo.txt

fbx_viewer/
├── main.cpp
├── shader.h
├── vertex.glsl
├── fragment.glsl
├── model.fbx
└── CMakeLists.txt

pacman -S mingw-w64-x86_64-assimp


cd fbx_viewer
mkdir build && cd build
cmake -G "MinGW Makefiles" ..
mingw32-make
./fbx_viewer

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(fbx_viewer)

set(CMAKE_CXX_STANDARD 17)

find_package(OpenGL REQUIRED)
find_package(GLEW REQUIRED)
find_package(GLFW3 REQUIRED)
find_package(assimp REQUIRED)

include_directories(
    ${OPENGL_INCLUDE_DIRS}
    ${GLEW_INCLUDE_DIRS}
    ${GLFW3_INCLUDE_DIRS}
    ${ASSIMP_INCLUDE_DIRS}
)

add_executable(fbx_viewer main.cpp shader.h)

target_link_libraries(fbx_viewer
    ${OPENGL_LIBRARIES}
    GLEW::GLEW
    glfw
    assimp
)

main.cpp

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#include <iostream>
#include <vector>
#include "shader.h"

struct Vertex {
    float position[3];
    float normal[3];
};

std::vector<Vertex> vertices;
std::vector<unsigned int> indices;

void processMesh(aiMesh* mesh) {
    for (unsigned int i = 0; i < mesh->mNumVertices; i++) {
        Vertex v;
        memcpy(v.position, &mesh->mVertices[i], sizeof(float) * 3);
        memcpy(v.normal, &mesh->mNormals[i], sizeof(float) * 3);
        vertices.push_back(v);
    }
    for (unsigned int i = 0; i < mesh->mNumFaces; i++) {
        aiFace face = mesh->mFaces[i];
        for (unsigned int j = 0; j < face.mNumIndices; j++) {
            indices.push_back(face.mIndices[j]);
        }
    }
}

int main() {
    if (!glfwInit()) return -1;
    GLFWwindow* window = glfwCreateWindow(800, 600, "FBX Viewer", nullptr, nullptr);
    if (!window) return -1;
    glfwMakeContextCurrent(window);
    glewInit();

    Shader shader("../vertex.glsl", "../fragment.glsl");

    Assimp::Importer importer;
    const aiScene* scene = importer.ReadFile("../model.fbx",
        aiProcess_Triangulate |
        aiProcess_GenSmoothNormals |
        aiProcess_JoinIdenticalVertices |
        aiProcess_FlipUVs);

    if (!scene || !scene->HasMeshes()) {
        std::cerr << "Failed to load model: " << importer.GetErrorString() << std::endl;
        return -1;
    }

    processMesh(scene->mMeshes[0]);

    GLuint VAO, VBO, EBO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);

    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), vertices.data(), GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(float) * 3));
    glEnableVertexAttribArray(1);

    glEnable(GL_DEPTH_TEST);

    while (!glfwWindowShouldClose(window)) {
        glClearColor(0.1f, 0.1f, 0.2f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        shader.use();

        glm::mat4 model = glm::mat4(1.0f);
        glm::mat4 view = glm::lookAt(glm::vec3(0.0f, 1.0f, 3.0f),
                                     glm::vec3(0.0f, 0.0f, 0.0f),
                                     glm::vec3(0.0f, 1.0f, 0.0f));
        glm::mat4 projection = glm::perspective(glm::radians(45.0f),
                                                800.0f / 600.0f, 0.1f, 100.0f);

        glUniformMatrix4fv(glGetUniformLocation(shader.ID, "model"), 1, GL_FALSE, glm::value_ptr(model));
        glUniformMatrix4fv(glGetUniformLocation(shader.ID, "view"), 1, GL_FALSE, glm::value_ptr(view));
        glUniformMatrix4fv(glGetUniformLocation(shader.ID, "projection"), 1, GL_FALSE, glm::value_ptr(projection));

        glBindVertexArray(VAO);
        glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

shader.h

#ifndef SHADER_H
#define SHADER_H

#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <GL/glew.h>

class Shader {
public:
    GLuint ID;
    Shader(const char* vertexPath, const char* fragmentPath) {
        std::string vCode, fCode;
        std::ifstream vFile(vertexPath), fFile(fragmentPath);
        std::stringstream vStream, fStream;
        vStream << vFile.rdbuf();
        fStream << fFile.rdbuf();
        vCode = vStream.str();
        fCode = fStream.str();
        const char* vShaderCode = vCode.c_str();
        const char* fShaderCode = fCode.c_str();

        GLuint vertex = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertex, 1, &vShaderCode, NULL);
        glCompileShader(vertex);

        GLuint fragment = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragment, 1, &fShaderCode, NULL);
        glCompileShader(fragment);

        ID = glCreateProgram();
        glAttachShader(ID, vertex);
        glAttachShader(ID, fragment);
        glLinkProgram(ID);

        glDeleteShader(vertex);
        glDeleteShader(fragment);
    }
    void use() { glUseProgram(ID); }
};

#endif

vertex.glsl

#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aNormal;

out vec3 FragPos;
out vec3 Normal;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main() {
    FragPos = vec3(model * vec4(aPos, 1.0));
    Normal = mat3(transpose(inverse(model))) * aNormal;
    gl_Position = projection * view * vec4(FragPos, 1.0);
}

fragment.glsl

#version 330 core
in vec3 FragPos;
in vec3 Normal;

out vec4 FragColor;

void main() {
    vec3 lightDir = normalize(vec3(0.5, 1.0, 0.3));
    float diff = max(dot(normalize(Normal), lightDir), 0.0);
    vec3 color = vec3(0.2, 0.3, 0.1) * diff;
    FragColor = vec4(color, 1.0);
}

cmd

furcr@furcraea_built MINGW64 ~
$ cd c:

furcr@furcraea_built MINGW64 /c
$ cd glsl_sample

furcr@furcraea_built MINGW64 /c/glsl_sample
$ cd fbx_viewer

furcr@furcraea_built MINGW64 /c/glsl_sample/fbx_viewer
$ cd build

furcr@furcraea_built MINGW64 /c/glsl_sample/fbx_viewer/build
$ cmake -G "MSYS Makefiles" ..
-- The C compiler identification is GNU 15.1.0
-- The CXX compiler identification is GNU 15.1.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/msys64/mingw64/bin/cc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/msys64/mingw64/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenGL: opengl32
-- Found GLEW: C:/msys64/mingw64/lib/cmake/glew/glew-config.cmake
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
CMake Error at CMakeLists.txt:9 (find_package):
  By not providing "Findassimp.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "assimp", but
  CMake did not find one.

  Could not find a package configuration file provided by "assimp" with any
  of the following names:

    assimpConfig.cmake
    assimp-config.cmake

  Add the installation prefix of "assimp" to CMAKE_PREFIX_PATH or set
  "assimp_DIR" to a directory containing one of the above files.  If "assimp"
  provides a separate development package or SDK, be sure it has been
  installed.


-- Configuring incomplete, errors occurred!

furcr@furcraea_built MINGW64 /c/glsl_sample/fbx_viewer/build
$ pacman -S mingw-w64-x86_64-assimp
resolving dependencies...
looking for conflicting packages...

Packages (2) mingw-w64-x86_64-minizip-1.3.1-1  mingw-w64-x86_64-assimp-6.0.2-1

Total Download Size:    3.11 MiB
Total Installed Size:  12.02 MiB

:: Proceed with installation? [Y/n]
:: Retrieving packages...
 mingw-w64-x86_64-minizip-1...    83.1 KiB  32.7 KiB/s 00:03 [###############################] 100%
 mingw-w64-x86_64-assimp-6....     3.0 MiB   960 KiB/s 00:03 [###############################] 100%
 Total (2/2)                       3.1 MiB   882 KiB/s 00:04 [###############################] 100%
(2/2) checking keys in keyring                               [###############################] 100%
(2/2) checking package integrity                             [###############################] 100%
(2/2) loading package files                                  [###############################] 100%
(2/2) checking for file conflicts                            [###############################] 100%
(2/2) checking available disk space                          [###############################] 100%
:: Processing package changes...
(1/2) installing mingw-w64-x86_64-minizip                    [###############################] 100%
(2/2) installing mingw-w64-x86_64-assimp                     [###############################] 100%

furcr@furcraea_built MINGW64 /c/glsl_sample/fbx_viewer/build
$ cmake -G "MSYS Makefiles" ..
-- The C compiler identification is GNU 15.1.0
-- The CXX compiler identification is GNU 15.1.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/msys64/mingw64/bin/cc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/msys64/mingw64/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenGL: opengl32
-- Found GLEW: C:/msys64/mingw64/lib/cmake/glew/glew-config.cmake
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
-- Configuring done (1.8s)
-- Generating done (0.0s)
-- Build files have been written to: C:/glsl_sample/fbx_viewer/build

furcr@furcraea_built MINGW64 /c/glsl_sample/fbx_viewer/build
$ mingw32-make
[ 50%] Building CXX object CMakeFiles/fbx_viewer.dir/main.cpp.obj
[100%] Linking CXX executable fbx_viewer.exe
[100%] Built target fbx_viewer

furcr@furcraea_built MINGW64 /c/glsl_sample/fbx_viewer/build
$ ./fbx_viewer

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です