MSYS2のMINGW64 → pacman やOpenGL関連ライブラリがインストール可能 な環境でGLSLを描画できた。その4

CMakeLists.txt

cmake_minimum_required(VERSION 3.5)
project(glsl_sample)

set(CMAKE_C_STANDARD 99)

add_executable(glsl_sample main.c)

find_package(OpenGL REQUIRED)
include_directories("C:/msys64/mingw64/include/stb") 
include_directories(${OPENGL_INCLUDE_DIRS})

# MSYS2パス用のヒント(MINGW64環境)
include_directories("C:/msys64/mingw64/include")
link_directories("C:/msys64/mingw64/lib")

target_link_libraries(glsl_sample glfw3 glew32 opengl32 gdi32)

main.c

#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>

char* load_shader_source(const char* filepath) {
    FILE* file = fopen(filepath, "rb");
    if (!file) {
        fprintf(stderr, "Failed to open %s\n", filepath);
        exit(1);
    }
    fseek(file, 0, SEEK_END);
    long len = ftell(file);
    rewind(file);
    char* buffer = (char*)malloc(len + 1);
    fread(buffer, 1, len, file);
    buffer[len] = '\0';
    fclose(file);
    return buffer;
}

GLuint compile_shader(GLenum type, const char* source) {
    GLuint shader = glCreateShader(type);
    glShaderSource(shader, 1, &source, NULL);
    glCompileShader(shader);
    GLint success;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
    if (!success) {
        char infoLog[512];
        glGetShaderInfoLog(shader, 512, NULL, infoLog);
        fprintf(stderr, "Shader compile error: %s\n", infoLog);
        exit(1);
    }
    return shader;
}

int main() {
    if (!glfwInit()) {
        fprintf(stderr, "GLFW init failed\n");
        return -1;
    }

    GLFWwindow* window = glfwCreateWindow(800, 600, "GLSL Sample", NULL, NULL);
    if (!window) {
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);
    glewInit();

    char* vertexSource = load_shader_source("../shader.vert");
    char* fragmentSource = load_shader_source("../shader.frag");

    GLuint vertexShader = compile_shader(GL_VERTEX_SHADER, vertexSource);
    GLuint fragmentShader = compile_shader(GL_FRAGMENT_SHADER, fragmentSource);

    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);

    glUseProgram(shaderProgram);

    GLint mouseLoc = glGetUniformLocation(shaderProgram, "u_mouse");
    GLint timeLoc = glGetUniformLocation(shaderProgram, "u_time");
    GLint resLoc   = glGetUniformLocation(shaderProgram, "u_resolution");
    glUniform1i(glGetUniformLocation(shaderProgram, "u_texture"), 0);

    float vertices[] = {
        // x, y, u, v
        -1.0f,  1.0f,  0.0f, 1.0f,
         1.0f,  1.0f,  1.0f, 1.0f,
         1.0f, -1.0f,  1.0f, 0.0f,
        -1.0f, -1.0f,  0.0f, 0.0f
    };
    unsigned int indices[] = {
        0, 1, 2,
        2, 3, 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, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
    glEnableVertexAttribArray(1);

    int width, height, nrChannels;
    unsigned char *data = stbi_load("../texture.png", &width, &height, &nrChannels, 0);
    if (!data) {
        fprintf(stderr, "Failed to load texture\n");
        return -1;
    }

    GLuint texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    GLenum format = (nrChannels == 4) ? GL_RGBA : GL_RGB;
    glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
    glGenerateMipmap(GL_TEXTURE_2D);
    stbi_image_free(data);

    while (!glfwWindowShouldClose(window)) {
        float timeValue = (float)glfwGetTime();
        int winW, winH;
        double mouseX, mouseY;

        glfwGetCursorPos(window, &mouseX, &mouseY);
        glfwGetWindowSize(window, &winW, &winH);
        mouseX = mouseX/winW;
		mouseY = mouseY/winH;
		
        glClearColor(0.1f, 0.1f, 0.15f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        glUseProgram(shaderProgram);
        glUniform1f(timeLoc, timeValue);
        glUniform2f(mouseLoc, (float)mouseX, (float)mouseY);
        glUniform2f(resLoc, (float)winW, (float)winH);

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture);
        glBindVertexArray(VAO);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glDeleteProgram(shaderProgram);
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    glfwTerminate();
    return 0;
}

shader.vert

#version 330 core

layout(location = 0) in vec2 aPos;
layout(location = 1) in vec2 aTexCoord;

out vec2 vTexCoord;

void main() {
    gl_Position = vec4(aPos, 0.0, 1.0);
    vTexCoord   = aTexCoord;
}

shader.frag

#version 330 core

out vec4 fragColor;

uniform vec2  u_resolution;
uniform float u_time;

// Signed Distance for Torus
float sdTorus(vec3 p, vec2 t) {
    vec2 q = vec2(length(p.xz) - t.x, p.y);
    return length(q) - t.y;
}

// シーン全体の SDF(ここではトーラスのみ)
float map(vec3 p) {
    return sdTorus(p, vec2(0.6, 0.2));
}

// 法線(数値微分)
vec3 getNormal(vec3 p) {
    float eps = 0.0005;
    return normalize(vec3(
        map(p + vec3(eps,0,0)) - map(p - vec3(eps,0,0)),
        map(p + vec3(0,eps,0)) - map(p - vec3(0,eps,0)),
        map(p + vec3(0,0,eps)) - map(p - vec3(0,0,eps))
    ));
}

// レイマーチング本体
float raymarch(vec3 ro, vec3 rd) {
    float t = 0.0;
    for (int i = 0; i < 128; i++) {
        float d = map(ro + rd * t);
        if (d < 0.001) break;
        t += d;
        if (t > 20.0) break;
    }
    return t;
}

void main() {
    // 画面座標 → 正規化デバイス空間
    vec2 uv = (gl_FragCoord.xy - 0.5 * u_resolution) / u_resolution.y;

    // カメラ設定:斜め上方から原点を見る
    vec3 ro = vec3(2.0, 1.5, 2.0);   // カメラ位置
    vec3 ta = vec3(0.0, 0.0, 0.0);   // 注視点(原点)
    vec3 up = vec3(0.0, 1.0, 0.0);   // 上方向ベクトル

    // カメラ座標系の計算
    vec3 f = normalize(ta - ro);
    vec3 r = normalize(cross(f, up));
    vec3 u = cross(r, f);
    vec3 rd = normalize(r * uv.x + u * uv.y + f);

    // レイマーチングで交差距離を取得
    float t = raymarch(ro, rd);

    vec3 col;
    if (t < 20.0) {
        // ヒット時のライティング
        vec3 p        = ro + rd * t;
        vec3 normal   = getNormal(p);
        vec3 lightDir = normalize(vec3(-0.5, 0.8, -0.3));
        float diff    = clamp(dot(normal, lightDir), 0.0, 1.0);
        col = vec3(0.8, 0.6, 0.3) * diff;  // トーラス本体の色
    }
    else {
        // 背景色
        col = vec3(0.1, 0.1, 0.15);
    }

    fragColor = vec4(col, 1.0);
}

cmd

$ cd c:

furcr@furcraea_built MINGW64 /c
$ cd glsl_sample

furcr@furcraea_built MINGW64 /c/glsl_sample
$ cd glsl_sample_201_3texture

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

furcr@furcraea_built MINGW64 /c/glsl_sample/glsl_sample_201_3texture/build
$ cmake -G "MSYS Makefiles" ..
CMake Deprecation Warning at CMakeLists.txt:1 (cmake_minimum_required):
  Compatibility with CMake < 3.10 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value.  Or, use the <min>...<max> syntax
  to tell CMake that the project requires at least <min> but has been updated
  to work with policies introduced by <max> or earlier.


-- 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
-- Configuring done (2.4s)
-- Generating done (0.0s)
-- Build files have been written to: C:/glsl_sample/glsl_sample_201_3texture/build

furcr@furcraea_built MINGW64 /c/glsl_sample/glsl_sample_201_3texture/build
$ make
[ 50%] Building C object CMakeFiles/glsl_sample.dir/main.c.obj
[100%] Linking C executable glsl_sample.exe
[100%] Built target glsl_sample

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

コメントを残す

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