Code::Blocksをダークテーマにする(Ubuntu 20.04)
Code::Blocksを完全なダークテーマにすることは出来ないと思い込んでいたがそうでもなかった。
全部ダークにならないんだ・・・
環境
Ubuntu 20.04 LTS
Code::Blocks 20.03
手順
「codeblocks darktheme」などで検索していると大抵以下のような手順が紹介されている。指示に従うと冒頭のようにエディタ部分だけがダークになって余計目につらい。
解説動画やサイトでダークテーマ用の設定ファイルをダウンロードする
defaultファイルを上書きすることになるので予め/home/[ユーザー名]/.config/codeblocks
隠しフォルダ内にあるdefault.confを別名でコピーしておいた方がいいかもしれない。Code::Blocksを終了して以下のコマンドで設定プログラムを起動
cb_share_config
左のソース側へダウンロードしてきたファイル、右側へdefault.confを指定する
チェックボックスを全て選択して
Transfer>>
をクリックして保存
Code::Blocksを起動してdefaultテーマがダークに上書きされていることを確認
この段階で冒頭のようになる
デスクトップ自体をダークテーマにする
Code::BlocksがGTKで動作している環境であればデスクトップ自体をダークテーマにすると残りの部分もしっかりダークになる。
- 設定->外観->ウィンドウの色 : 暗いに変更
ちなみにデスクトップの設定だけではCode::Blocksのエディタ部分以外がダークになる。
C++入門者がOpenGLでハマったポイント〜ModelLoading辺り
頂点配列は正しいはずなのにキューブが崩れて表示される
前のセクションのコードを元にして次のセクションに向かうと描画が崩れる事が発生。新しく追加したコードから順に確認していくと最後にたどり着くのが頂点データの生配列だった。チュートリアルによってはポジション以外に法線、テクスチャ座標などがあったりなかったりするのが原因。
Texcoordsを使用しないのに配列に残していた場合glVertexAttribPointer
でセットした配列の解釈通りにいくとTexCoords
を想定した値が頂点座標として扱われ表示が崩れる。配列を変更しない場合はストライドを調整し3ではなく5*sizeof(float)にすれば良かったのかもしれない。
float vertices[] = { // position Texcoords -0.5f, -0.5f, -0.5f, 0.0f, 1.0f 0.5f, -0.5f, -0.5f, ..., ..., 0.5f, 0.5f, -0.5f, ..., ..., 0.5f, 0.5f, -0.5f, ..., ...,
assimpで警告発生
assimpというライブラリを使用して3Dモデルをロードする。
aptでインストールして
sudo apt-get update sudo apt-get install libassimp-dev
CMakeFileLists.txtでfind_package(assimp REQUIRED)
を試したらこんなログがでた
[cmake] CMake Warning (dev) at /usr/lib/x86_64-linux-gnu/cmake/assimp-5.0/assimpTargets.cmake:54 (if): [cmake] if given arguments: [cmake] [cmake] "ON" [cmake] [cmake] An argument named "ON" appears in a conditional statement. Policy CMP0012 [cmake] is not set: if() recognizes numbers and boolean constants. Run "cmake [cmake] --help-policy CMP0012" for policy details. Use the cmake_policy command to [cmake] set the policy and suppress this warning. [cmake] Call Stack (most recent call first): [cmake] /usr/lib/x86_64-linux-gnu/cmake/assimp-5.0/assimp-config.cmake:1 (include) [cmake] CMakeLists.txt:28 (find_package) [cmake] This warning is for project developers. Use -Wno-dev to suppress it. [cmake]
usr/lib
内のcmakeディレクトリでassimp用の.cmakeが自動生成された模様。該当する部分はこんな感じ
# Create imported target assimp::assimp if(ON) add_library(assimp::assimp SHARED IMPORTED) else() add_library(assimp::assimp STATIC IMPORTED) endif()
わからないのでWebを検索した。ubuntu20.04LTSでaptを使用してassimpをインストールした時に発生するらしい。どうにも出来ないのでスルーする。
discourse.choreonoid.org CMakeの警告に関する報告
複数のソースからstb_image.hをincludeできない
コメントにDo thisと書かれていたのでこれまで何も考えずに使用していたが、サンプルで複数のファイルにまたがってstb_image.h
を使うケースに遭遇してハマった
// Do this: // #define STB_IMAGE_IMPLEMENTATION // before you include this file in *one* C or C++ file to create the implementation.
#define STB_IMAGE_STATIC
という手段もあるらしいけど、適当な関数を作って回避した。動くけどこれが正しいのかわからない。
// model.cpp #define STB_IMAGE_IMPLEMENTATION #include "stb/stb_image.h" void set_flip_stbi(bool flag) { stbi_set_flip_vertically_on_load(flag); } // main.cpp set_flip_stbi(true);
またファイルのロードに失敗する
Makeで生成されるbuildディレクトリの実行ファイルを実行しているはずなのに。たまにロードに失敗する。原因はbuildディレクトリを削除して再生成したときに削除したbuildディレクトリに居るため../resource/xxx.obj
とか相対パスでたどり着けていない模様。
ここまでの感想
モデルをロードできると「おおっ」て何かを成し遂げた気分になるけど、まだ何もしていないという恐怖。
参考にしているWebサイト learnopengl.com
C++入門者がOpenGLでハマったポイント〜Hello Triangle辺り
開発環境を構築できたら後はチュートリアルサイトや動画の指示に従えば躓くことは無いはず。ただ理解不足で適当なことをやるとどこが悪いのかわからなくなってハマる。
1. 三角形が表示されなかった
VAOとVBOに対する理解不足でGLuint VAO, VBO;
こう一括で宣言してやるのが気に入らずこんな書き方をしてしまった。VAOは頂点データでも入っているんだろうという認識だった。だったらVBOにはUV用のデータでもいれてやれと。
// Create Vertex Array Object GLuint VAO; glGenVertexArrays(1, &VAO); glBindVertexArray(VAO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5* sizeof(float), (void*)0); glEnableVertexAttribArray(0); // Create Vertex Buffer Object -- TexCoords GLuint VBO; glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void*)(3*sizeof(float))); glEnableVertexAttribArray(1);
正しくはその時点でバインドされているVAOに対して生成したVBOに格納したデータを指すポインタglVertexAttribPointer
を渡すのでこうなる。VAOは様々な頂点データ(座標・カラー・テクスチャ座標)に対する属性を取りまとめる役割があるようだ。
// Create Vertex Array Object GLuint VAO; glGenVertexArrays(1, &VAO); glBindVertexArray(VAO); // Create Vertex Buffer Object: Pos - TexCoords GLuint VBO; glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5* sizeof(float), (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void*)(3*sizeof(float))); glEnableVertexAttribArray(1);
2. テクスチャが表示されなかった
頂点シェーダープログラムのタイプミス
TexCoordのタイプをvec3
と無意識にやってしまっていた。VSCode拡張でShader languages support for VS Codeを入れるきっかけになる。がこの手のタイプミスは防げなさそう。
#version 330 core layout (location = 0) in vec3 aPos; layout (location = 1) in vec2 aTexCoord; // vec3にしていたら当然動かなかった
コピペミス
エラーは出ていないのにtexture1,2がビルド直後は表示されても次のlaunchでは表示されない
imageloaderの不具合を疑ってfilepathを相対から絶対アドレスに変更したりしても徒労に終わった
GDBを使おうと思ってCMakeLists.txtへtarget_compile_optionsを追加-Wall -g -O0
でビルドすると警告してくれた
warning: ‘texture2’ may be used uninitialized in this function [-Wmaybe-uninitialized]
該当する箇所は2枚目のテクスチャを生成する手前
GLuint texture2; glGenTextures(2, &texture1); <-------------ここに警告 glBindTexture(GL_TEXTURE_2D, texture2); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
見たまんまtexture2
の参照用intを使用せずにtexture1を使ってしまっていた。ただのタイプミスというかコピペミス。
3. まとめ
入門用のコードなら-Wall
付けなくてもいいかと面倒くさがっていた。というかCMakeListsでコンパイラオプションを設定するのを後回しにしていた。-Wall
がついていれば一瞬で解決するミスを数日掛けて追いかけていた。悲しい。
C++入門者がOpenGLでハマったポイント〜環境構築(Ubuntu20.04 VSCode+GLFW+GLAD)
Webページや動画で紹介されているのはGLFWとGLADの組み合わせが多かったが初日にうまく構築出来なかったのでGLFW+GLEWの環境に逃げた。
1.GLFW + GLEWでもはまる
必要なパッケージはapt installで全部揃えることができた
sudo apt install libx11-dev sudo apt install xorg-dev sudo apt install libglu1-mesa libglu1-mesa-dev libgl1-mesa-glx libgl1-mesa-dev sudo apt install libglfw3 libglfw3-dev sudo apt install libglew-dev
makefile
makefileでglewを指定する際に小文字の-lglew
では/usr/bin/ld: -lglew
がみつかりませんとエラーになった。ファイル名が大文字だったので試しに-GLEW
にしたら通った
CXXFLAGS = -g -Wall -std=c++17 LDLIBS = -lGL -lglfw -lGLEW OBJECTS = $(patsubst %.cpp,%.o,$(wildcard *.cpp)) TARGET = sample .PHONY: clean $(TARGET): $(OBJECTS) $(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ clean: -$(RM) $(TARGET) $(OBJECTS) *~ .*~ core
2.GLADではまる
GLAD1とGLAD2の違いを知らなかった
参考にしている解説のヘッダーがglad/glad.h
ならGLAD1、glad/gl.h
ならGLAD2でダウンロードページが異なり更に初期化の記述も異なる。ヘッダーオンリーではうまく行かなかったので以下のオプションのものを使用した
Options:
- ALIAS = False
- DEBUG = False
- HEADER_ONLY = False
- LOADER = True
- MX = False
- ON_DEMAND = False
CMakeLists.txtでプロジェクトへの追加ができなかった
GLADのgithubページに書かれたCMakeLists.txtではpython定義した関数が使用されていて理解の範疇を超えていたのでダメ元でライブラリとしてコンパイルするだけの記述をしたが動いている。message(STATUS "${変数}"
で地道に確認しながら作業を進めた。
gladがコンパイルされなかった
CMakeLists.txtの冒頭部分でproject(LearnOpenGL C CXX)
とCを追加していなかったためコンパイルされなかった。気がつくのに時間がかかった。
GLAD2(glad/gl.h)の初期化方法
GLAD2のgithubページで解説されている
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
これはGLAD1側の初期化法int version = gladLoadGL(glfwGetProcAddress);
こっちが正解
GLMが追加できなかった
チュートリアルが進むとGLMを使用してMatrixを扱うようになる。apt でインストールできるがCMakeLists.txtでglm
では認識されなかった。stackoverflowだったかがヒットしてglm::glm
で使えるようになった。なぜそうなのか?はわからない。
ディレクトリ構成
LearnOpenGL ├── CMakeLists.txt # main ├── glad │ ├── CMakeLists.txt # sub │ ├── include │ │ ├── KHR │ │ │ └── khrplatform.h │ │ └── glad │ │ └── gl.h │ └── src │ └── gl.c ├── include └── src └── main.cpp
mainのCMakeFileList.txt
cmake_minimum_required(VERSION 3.14) project(LearnOpenGL C CXX) set(PROJECT_VERSION 1.0.0) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED on) set(CMAKE_CXX_EXTENSIONS off) find_package(OpenGL REQUIRED) find_package(glfw3 REQUIRED) find_package(glm REQUIRED) add_subdirectory(glad) set(project_src src/main.cpp src/test.cpp src/shader.cpp ) set(project_headers ${CMAKE_CURRENT_SOURCE_DIR}/include/shader.hpp ${CMAKE_CURRENT_SOURCE_DIR}/include/test.hpp ) set(all_libs OpenGL glad glfw glm::glm X11 Xrandr pthread Xi dl ) add_executable(main ${project_src}) target_compile_options(main PUBLIC -Wall ) target_include_directories(main PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/ ) target_link_libraries(main ${all_libs}) message(STATUS "CMAKE_DL_LIBS: ${CMAKE_DL_LIBS}")
sub側のCMakeLists.txt
file(GLOB SOURCES "src/*.c") add_library(glad STATIC ${SOURCES}) target_include_directories(glad PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ) message(STATUS "GLAD: SRCDIR - ${CMAKE_CURRENT_SOURCE_DIR}") message(STATUS "GLAD: SOURCES - ${SOURCES}")
3.まとめ
誰かの教えに従えばつまづきようのない環境構築でおよそ3日は悩まされた。今の所GLEWとGLADの違いがわからない。無理にGLAD使う必要もないような気がする。
C++入門者がOpenGLを試した感想
動機
UE5の学習を開始して1年が経過し、そろそろ自由にゲームを作り始めようかと思い立ったがGame Ability SystemやGame Featuresなどの存在が気になり始めた。C++を勉強してそれらを使いこなせたら今後のゲーム開発に役立つかも?と思い始めたのがまず1つ目の動機。
2つ目の動機はメインマシンを置く部屋にエアコンが無い。この夏は特に暑く昼間は38度、夜になっても32度程度という生命の危機を感じるありさま。夏はエアコンのある部屋で省エネなノートPCでポチポチエディタをいじりたかった。
基本文法を終えた時点でUnreal C++へ挑戦しようとしたが一向に涼しくなる気配はなく興味がある分野ということでOpenGLの学習を選択した。
得られたもの
C++の基本へ入門してからOpenGLでカメラ(view)をマウスとキーボードでWSAD移動させるところまで(約一ヶ月)時点での収穫
- MakefileやCMakeListを用いたプロジェクトの作成方法
- 行列計算の基本の実践
- ベクトル計算の実践
- 結局ライブラリ頼みに気付く
現時点であまり収穫は無いが最後の結局ライブラリ頼みに気づいたのが大きい。
アンリアルクエスト4にオンライン参加した(中級編)
二日間にわたって開催されたアンリアルクエスト4、その期間内でなんとか中級クエストまでは完了できたのかな?と思っている。2番だけは勘違いして扉自身に弾を当てると開く仕組みを作ってしまったけど
やる気の出るイベントを開催してくださったHistoriaさんと、攻略法をDiscordで紹介してくださった方に感謝
中級クエスト
踏んだらジャンプするジャンプパッドを作成せよ
的に弾を当てると扉が開く仕組みを作成せよ
秒数をUIで表示せよ
ゲーム開始までのカウントダウンをUIで表示せよ
ゴール演出を追加せよ
スライディングを追加せよ
1.ジャンプパッド
プレイヤーの落下velocityを取得して適当な係数を乗算したものをLaunchCharacter
へ渡した。
後日見直しがてらちょっと手を加えた
- 横に伸びたBPは見づらいので
Sequence
化 - velocityの計算に
ABS
を使用 - LaunchするのはBPインターフェースでPlayerBPに任せて、ジャンプパッドはLaunchするvelocityだけ渡す
2. 弾が当たると開く扉
Animation中に再度イベント発火したときの制御がうまくいかなかったのでDoOnece
でフローを改善させた。
3. 秒数をUIで表示せよ
UIとプレイヤーとコントローラーの関係をどうするか未だに整理しきれていない
- GameModeがプレーヤーにタイマーUIを与える
- タイマーUIとプレーヤーはインターフェースで通信
- プレーヤーは一定の間隔でインターフェースで現在時間を送る
といった具合に落ち着いた
4.ゲーム開始までのカウントダウンをUIで表示せよ
ゲーム開始の合図はGameModeの仕事にした
5.ゴール演出を追加せよ
凝ったことをする時間も技術もないので、Niagaraとサウンドで済ませた
- Niagaraのエフェクトを作成
- GoalBPにNiagaraコンポーネント追加、初期状態では無効にしておく
- Playerがゴールに到達した時にイベント発生
- PlayerのBPインターフェースにゴール処理を任せる
6.スライディング
検索したところABPからAnimationMontageを手軽に呼び出せるらしい
- Animation SequenceからMontageの作成
- ABPでMontage呼び出しと終了処理の設定(プレイヤーのEventDispacherにバインド)
- プロジェクトセッティングでInputActionEvent追加してからプレイヤーBPで一連の処理を作成
最初に思い付いたのがWalkSpeedを変化させる方法だった。後でDiscordで紹介されていた方法もためしてこんな感じになっている
感想
イベントの二日間で作業した時間よりも記録用にいろいろ整理する時間の方が長いような。
整理しているうちに気が付いた事
- よく使うSet〇〇や演算ノード、Booleanノードの配置パターンを決めた方がよさげ
- 横に伸ばすと見づらいのでSequenceで縦に伸ばす
アンリアルクエスト4にオンライン参加した(初級編)
先日開催されたアンリアルクエスト4「アンリアルエンジンを使って1日で作品を作ろう!」というイベントに参加した記録と感想
初級クエスト
的を壊せ
- 弾のBPに
Projectile
タグをつける - 的のBPで
On Component Hit
イベントを使用、Actor has Tag
で分岐 - 弾が当たった時には
DestroyActor
- 弾のBPに
的を動かせ
SetActorLocationを使用してランダム指定したLocationにむけてEventTick毎にDirectionをNormalizeして変数MoveSpeedで移動する妙な方法しか思いつかなかった。後でInterpToMovement
コンポーネントという便利な存在を知る- Detailから
Control Points
を複数設定可能 Behaiviour Type
をPingPongにする
- Detailから
ゴールを作成せよ
エディタ内のモデリングツールで外枠のリングと内側のエリアを作成した- 内側のメッシュのコリジョンを
OverlapAllDynamic
にしてGenerateOverlapEvents
をチェック OnComponentBeginOverlap
イベントでActorHasTag
でPlayerを検出- Delay使ってGoalEvent発火
- 内側のメッシュのコリジョンを
秒数が増える仕組みを作成せよ
EventTick
でDeltaSeconds
を加算していく
ステージを作成せよ
エディタ内のモデリングツールを初めて使った。ワールド内に配置された既存のメッシュを選択して取り返しのつかない変更をしてしまう。メッシュに変な穴があいた当たると死ぬ棘を作成せよ
モデリングツールを使用して棘を作る。簡単そうだがメッシュが気のせいレベルで動いてまともに使えな・・・原因はマテリアルスロットになぜか入れてしまったvertex animationのあるAdvancedFlagだった- モデリングツールで作成したものをStatickMesh化、editorの最上部のActorメニューから
Convert [xxx] to StaticMesh
OnComponentHit
イベントでPlayerタグを検出してプレイヤーをcastして死亡イベントを発火させた。(インターフェースでやった方がいいのかな)- プレイヤーBPで死亡イベントは
SetCollisionEnabled
とSetAllbodies SimulatePhysics
を使うといいらしい
- モデリングツールで作成したものをStatickMesh化、editorの最上部のActorメニューから
感想
「これはこうやるんだよ」といった情報があれば1日でこなせる設定で、それらの情報を知らなかったら苦労するのを実感した。制限時間内に終わらせるには知らない事を一人考えこむより公式ドキュメント読んで検索するか他の人に聞いてどうにかするのが正解なんだろう。目の前の得体のしれないパラメータ総当たりして時間を浪費してしまう癖は直さないとなぁ