<!--親の顔より見た光景-->

日々の発見を残していきます。

C#からC++の関数を呼ぶ 文字列が引数のとき

以下でうまくいく。
C++ソース】

extern "C"
{
    __declspec(dllexport) void Resize(const char* file_path, double fx, double fy );
    __declspec( dllexport ) void Print(const char* str);
}

C#ソース】

        [DllImport("OpenCV.dll")]
        static extern void Resize(string str, double fx, double fy);
        [DllImport("OpenCV.dll")]
        static extern void Print(string str);

        static void Main()
        {
            Print("test!");
            string file_path = "src.jpg";
            Resize(file_path, 0.5, 0.5);
            System.Console.WriteLine("end.");
        }

C++ではC形式で引数を定義。(const char*)
C#ではstringを実引数として呼べる。

Visual Studio 2017 + OpenCV(3.00)の環境構築

【成功した環境】
・OS:Windows 10
OpenCV:3.00
・VisualStudio:Visual Studio Community 2017

以下の手順を慎重に行えばOpenCVライブラリが使えるぞ!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

0.OpenCVをダウンロード

OpenCV3.2インストール方法(ビルドなし)を参考に、ダウンロード。

1.プロジェクト作成

VisualStudio2017でOpenCVアプリ用のプロジェクトを作成。(Win32コンソールアプリケーション)

2.ソリューション構成を「Release」に変更。

f:id:akagi13213:20180901233815p:plain


f:id:akagi13213:20180901234221p:plain


f:id:akagi13213:20180901234444p:plain

3.OpenCVのパスをプロジェクトに通す

以下リンクを参考に、パスを通す。
Visual StudioとOpenCVを使う | OpenCVで遊ぼう!

※libへのパスはx86を選ぶこと。
 VisualStudioプロジェクトデフォルト設定の「対象コンピュータ」がx86になってるため

4.依存ファイルを指定

プロジェクト -> 構成プロパティ -> リンカー -> 入力 -> 追加の依存ファイルに「opencv_world300.lib」を追加。(バージョンに合わせて数字は変更)
opencv_world300d.libを指定すると、「~~~.dllが見つからない」とか言うエラーが出て実行できないので注意。

f:id:akagi13213:20180901233815p:plain


f:id:akagi13213:20180901235015p:plain

5.プロジェクトをビルド。

以下のプログラムをビルド・実行。
黒い窓が現れれば成功。

#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
    Mat image = Mat::zeros(100, 100, CV_8UC3);
    imshow("", image);
    waitKey(0);
}

【three.js】ライチュウを表示

・作ったページ
http://bilibili.html.xdomain.jp/index.html
しっぽが長い……


・フリーの3Dモデルが集まってるところ
3D Models for Free - Free3D.com

参考ページ:
・three.jsの基礎
初心者でも絶対わかる、WebGLプログラミング<three.js最初の一歩> | HTML5Experts.jp

・three.jsで3Dモデル(daeファイル)を表示
Three.jsでモデルデータを読み込む - ICS MEDIA



↓これだけやれば3Dモデルが表示できる

Daeファイルの読み込み

1.ColladaLoaderインスタンスを生成
2.load関数の呼び出し、コールバックの登録
 load( 'daeファイルのパス', ロード後に呼ばれるコールバック関数 )
3.読み込んだモデルをシーンに追加
4.座標を指定

        const loader = new THREE.ColladaLoader();        // 1
        
        loader.load('./model/RaichuM.dae',  (collada) => {    // 2
            const model = collada.scene;
            self.scene.add(model);        // 3
            model.position.set(0,0,0);   // 4
        });

【app.js】

var APP = (function() {
    var self = {};

    var APP = function(canvas) {
        self.scene = new THREE.Scene();
        self.camera = new THREE.PerspectiveCamera(100, canvas.width / canvas.height, 1, 1000);
        self.renderer = new THREE.WebGLRenderer({canvas:canvas});
        self.controls = new THREE.OrbitControls(self.camera);
        self.renderer.setClearColor(0xffffff);
        self.camera.position.set(0,3.0,3.0);
        
        self.initGrid();
        self.initLight();
        self.initLoader();
        self.animate();
    }
    
    self.initGrid = function() {
        const grid = new THREE.GridHelper(100, 50);
        grid.material.color = new THREE.Color(0xffff00);
        self.scene.add(grid);
        self.renderer.render(self.scene, self.camera);
    };
    
    self.initLight = function() {
        const directionalLight = new THREE.DirectionalLight(0xffffff);
        directionalLight.position.set(0,2.0,5.0);
        self.scene.add(directionalLight);
    };

    self.initLoader = function() {
        const loader = new THREE.ColladaLoader();
        
        loader.load('./model/RaichuM.dae',  (collada) => {
            const model = collada.scene;
            self.scene.add(model);
            model.position.set(0,0,0);
        });
        
        loader.load('./model/PikachuM.dae',  (collada) => {
            const model = collada.scene;
            self.scene.add(model);
            model.position.set(2,0,0);
            console.log(collada);
        });
    };
            
    self.animate = function() {
        self.controls.update();
        self.renderer.render(self.scene, self.camera);
        
        requestAnimationFrame(self.animate);
    };
    
    return APP;
})();

【Three.js】格子を作る

Three.jsを使って、格子を表示するだけのページを作った。
three.js Test

OrbitControls.jsというライブラリのおかげで3Dプログラミングなのにめちゃくちゃ楽。
レンタルサーバーにファイル上げるのくっそ面倒。
サーバー作ってエッチページ作りてえなぁ

詳細の記述は後日気が向いたら。
WebGLRendererの引数にcanvasをそのまま渡していて、「絵が出ねえなぁ」って1時間くらい悩んでいた。

【app.js】

var APP = (function() {
    var self = {};

    var APP = function(canvas) {
        self.scene = new THREE.Scene();
        self.camera = new THREE.PerspectiveCamera(100, canvas.width / canvas.height, 1, 1000);
        self.renderer = new THREE.WebGLRenderer({canvas:canvas});
        self.controls = new THREE.OrbitControls(self.camera);

        self.camera.position.set(1.0,1.0,0.0);

        self.initGrid();
        self.animate();
    }
    
    self.initGrid = function() {
        var grid = new THREE.GridHelper(100, 50);
        self.scene.add(grid);
        self.renderer.render(self.scene, self.camera);
    };

    self.animate = function() {
        self.controls.update();
        self.renderer.render(self.scene, self.camera);
        
        requestAnimationFrame(self.animate);
    };
    return APP;
})();

【index.html】

<!DOCTYPE HTML>
<html>
    <head>
        <title>three.js Test</title>
        <meta charset="UTF-8">
    </head>
    <body>
        <canvas id="canvas"></canvas>
        <script type="text/javascript" src="three.js-master/build/three.min.js"></script>
        <script type="text/javascript" src="three.js-master/examples/js/controls/OrbitControls.js"></script>
        <script type="text/javascript" src="app.js"></script>
        <script>
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
            var app = new APP(canvas);
        </script>
    </body>
</html>