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_viewerCMakeLists.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


