質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

607閲覧

構造体について

miiichat

総合スコア72

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/02/12 15:37

編集2019/02/12 15:51
class Object { public: struct Vertex { GLfloat position[3]; GLfloat normal[3]; }; };
constexpr Object::Vertex solidCubeVertex[] = { // 左 { -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f }, { -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f }, { -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f }, { -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f }, { -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f }, { -1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f }, // 裏 { 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f },               ・               ・               ・

このように初期化した場合最初の3つがpositionにはいってあとの3つがnormalに入るんですか?
あと{ 1.0f, -1.0f, -1.0f)のように3つだけ書いたらどうなりますか?

#pragma once #include <GL/glew.h> class Object { GLuint vao; GLuint vbo; GLuint ibo; public: struct Vertex { GLfloat position[3]; GLfloat normal[3]; }; Object(GLint size, GLsizei vertexcount, const Vertex *vertex, GLsizei indexcount = 0, const GLuint *index = NULL) { glGenVertexArrays(1, &vao); glBindVertexArray(vao); glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, vertexcount * sizeof(Vertex), vertex, GL_STATIC_DRAW); glVertexAttribPointer(0, size, GL_FLOAT, GL_FALSE, sizeof (Vertex), static_cast<Vertex *>(0)->position); glEnableVertexAttribArray(0); glVertexAttribPointer(1, size, GL_FLOAT, GL_FALSE, sizeof(Vertex), static_cast<Vertex *>(0)->normal); glEnableVertexAttribArray(1); glGenBuffers(1, &ibo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexcount * sizeof(GLuint), index, GL_STATIC_DRAW); } void bind() const { glBindVertexArray(vao); } virtual ~Object() { glDeleteBuffers(1, &vao); glDeleteBuffers(1, &vbo); glDeleteBuffers(1, &ibo); } private: //コピーコンストラクタの禁止 Object(const Object &o); //代入によるコピーの禁止 Object &operator=(const Object &o); };
#include <cstdlib> #include <iostream> #include <fstream> #include <vector> #include <memory> #include <GL/glew.h> #include <GLFW/glfw3.h> #include "Window.h" #include "Matrix.h" #include "Shape.h" #include "ShapeIndex.h" #include "SolidShapeIndex.h" #include "SolidShape.h" GLboolean printShaderInfoLog(GLuint shader, const char *str) { GLint status; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if (status == GL_FALSE) std::cerr << "Compile Error in" << str << std::endl; GLsizei bufSize; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &bufSize); if (bufSize > 1) { std::vector<GLchar> infoLog(bufSize); GLsizei length; glGetShaderInfoLog(shader, bufSize, &length, &infoLog[0]); std::cerr << &infoLog[0] << std::endl; } return static_cast<GLboolean>(status); } // プログラムオブジェクトのリンク結果を表示する // program: プログラムオブジェクト名 GLboolean printProgramInfoLog(GLuint program) { // リンク結果を取得する GLint status; glGetProgramiv(program, GL_LINK_STATUS, &status); if (status == GL_FALSE) std::cerr << "Link Error." << std::endl; // シェーダのリンク時のログの長さを取得する GLsizei bufSize; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufSize); if (bufSize > 1) { // シェーダのリンク時のログの内容を取得する std::vector<GLchar> infoLog(bufSize); GLsizei length; glGetProgramInfoLog(program, bufSize, &length, &infoLog[0]); std::cerr << &infoLog[0] << std::endl; } return static_cast<GLboolean>(status); } //プログラムオブジェクト作成 // vsrc: バーテックシェーダ // fsrc: フラグメントシェーダ GLuint createProgram(const char *vsrc, const char *fsrc) { const GLuint program(glCreateProgram()); if (vsrc != NULL) { const GLuint vobj(glCreateShader(GL_VERTEX_SHADER)); glShaderSource(vobj, 1, &vsrc, NULL); glCompileShader(vobj); if (printShaderInfoLog(vobj, "vertex shader")) glAttachShader(program, vobj); glDeleteShader(vobj); } if (fsrc != NULL) { const GLuint fobj(glCreateShader(GL_FRAGMENT_SHADER)); glShaderSource(fobj, 1, &fsrc, NULL); glCompileShader(fobj); if (printShaderInfoLog(fobj, "fragment shader")) glAttachShader(program, fobj); glDeleteShader(fobj); } glBindAttribLocation(program, 0, "position"); glBindAttribLocation(program, 1, "normal"); glBindFragDataLocation(program, 0, "fragment"); glLinkProgram(program); if (printProgramInfoLog(program)) return program; glDeleteProgram(program); return program; } bool readShaderSource(const char *name, std::vector<GLchar> &buffer) { if (name == NULL) return false; std::ifstream file(name, std::ios::binary); if (file.fail()) { std::cerr << "Error: Can't open source file:" << name << std::endl; return false; } file.seekg(0L, std::ios::end); GLsizei length = static_cast<GLsizei>(file.tellg()); buffer.resize(length + 1); file.seekg(0L, std::ios::beg); file.read(buffer.data(), length); buffer[length] = '\0'; if (file.fail()) { std::cerr << "Error: Could not read source file:" << name << std::endl; file.close(); return false; } } GLuint loadProgram(const char *vert, const char *frag) { // シェーダのソースファイルを読み込む std::vector<GLchar> vsrc; const bool vstat(readShaderSource(vert, vsrc)); std::vector<GLchar> fsrc; const bool fstat(readShaderSource(frag, fsrc)); // プログラムオブジェクトを作成する return vstat && fstat ? createProgram(vsrc.data(), fsrc.data()) : 0; } constexpr Object::Vertex solidCubeVertex[] = { // 左 { -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f }, { -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f }, { -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f }, { -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f }, { -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f }, { -1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f }, // 裏 { 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f }, { -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f }, { -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f }, { 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f }, { -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f }, { 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f }, // 下 { -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f }, { 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f }, { 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f }, { -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f }, { 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f }, { -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f }, // 右 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f }, { 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f }, { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f }, // 上 { -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f }, { -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f }, { -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f }, { 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f }, // 前 { -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f }, { -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f }, { -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f } }; constexpr GLuint solidCubeIndex[] = { 0, 1, 2, 3, 4, 5, // 左 6, 7, 8, 9, 10, 11, // 裏 12, 13, 14, 15, 16, 17, // 下 18, 19, 20, 21, 22, 23, // 右 24, 25, 26, 27, 28, 29, // 上 30, 31, 32, 33, 34, 35 // 前 }; Object::Vertex tri_vertex[] = { {-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f}, {1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f }, {0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f } }; int main () { if (glfwInit() == GL_FALSE) { std::cerr << "Can't initialize GLFW" << std::endl; return 1; } atexit(glfwTerminate); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); Window window; glClearColor(1.0f, 1.0f, 1.0f, 0.0f); glFrontFace(GL_CCW); //CCW = 反時計回り(デフォルト); CW = 時計回り glCullFace(GL_BACK); //削除 front(デフォルト) or back? glEnable(GL_CULL_FACE); //背面カリング有効 glClearDepth(1.0); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); const GLuint program(loadProgram("point.vert", "point.frag")); const GLint modelviewLoc(glGetUniformLocation(program, "modelview")); const GLint projectionLoc(glGetUniformLocation(program, "projection")); std::unique_ptr<const Shape> shape(new SolidShapeIndex(3, 36, solidCubeVertex, 36, solidCubeIndex)); glfwSetTime(0.0); while (window.shouldClose() == GL_FALSE) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(program); const GLfloat *const size(window.getSize()); const GLfloat fovy(window.getScale() * 0.01f); const GLfloat aspect(size[0] / size[1]); const Matrix projection(Matrix::perspective(fovy, aspect, 1.0f, 10.0f)); const GLfloat *const location(window.getLocation()); const Matrix r(Matrix::rotate(static_cast<GLfloat>(glfwGetTime()), 0.0f, 1.0f, 0.0f)); const Matrix model(Matrix::translate(location[0], location[1], 0.0f) * r); const Matrix view(Matrix::lookat(3.0f, 4.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f)); const Matrix modelview(view * model); glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, projection.data()); glUniformMatrix4fv(modelviewLoc, 1, GL_FALSE, modelview.data()); shape->draw(); const Matrix modelview1(modelview * Matrix::translate(0.0f, 0.0f, 3.0f)); glUniformMatrix4fv(modelviewLoc, 1, GL_FALSE, modelview1.data()); shape->draw(); window.swapBuffers(); } };

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2019/02/12 15:44

C++の話なので、Cとは関係ないですね。タグを削除しましょう。
ttyp03

2019/02/13 01:02

どうなるかやってみればいいのに。
guest

回答1

0

ベストアンサー

このように初期化した場合最初の3つがpositionにはいってあとの3つがnormalに入るんですか?

はい。

あと{ 1.0f, -1.0f, -1.0f)のように3つだけ書いたらどうなりますか?

後半3つは既定の値(GLfloat知らないけど多分0)が入ります。

規格に近いものは、普通に落ちてるのだと、
https://cpprefjp.github.io/lang/cpp11/initializer_lists.html

処理系のマニュアルだと
(Visual C++)
https://docs.microsoft.com/ja-jp/cpp/cpp/initializers?view=vs-2017

gccで試した結果だと

C++

1struct Vertex 2{ 3 float position[3]; 4 float normal[3]; 5}; 6 7Vertex a[] = { 8 {{1,2,3},{4,5,6}}, // 普通 9 {{2,3},{5,6}}, // 少ない 10 //{{2,3,4},{5,6,7,8}}, 多い。これはgcc 8.2.0だとエラー 11 {2,3,4,5,6,7}, // 古い書き方(普通) 12 {2,3,4,5,6}, // 古い書き方(少ない) 13 //{2,3,4,5,6,7,8} 古い書き方(多い)。これはgcc 8.2.0だとエラー 14}; 15

text

1user@lubuntu:~/cpp$ cat test.cpp 2struct Vertex 3{ 4 float position[3]; 5 float normal[3]; 6}; 7 8Vertex a[] = { 9 {{1,2,3},{4,5,6}}, // 普通 10 {{2,3},{5,6}}, // 少ない 11 //{{2,3,4},{5,6,7}}, 多い。これはgcc 8.2.0だとエラー 12 {2,3,4,5,6,7}, // 古い書き方(普通) 13 {2,3,4,5,6}, // 古い書き方(少ない) 14 //{2,3,4,5,6,7,8} 古い書き方(多い)。これはgcc 8.2.0だとエラー 15}; 16int main() {return 0;} 17user@lubuntu:~/cpp$ g++ -g test.cpp -o test 18user@lubuntu:~/cpp$ gdb test 19GNU gdb (Ubuntu 8.2-0ubuntu1) 8.2 20Copyright (C) 2018 Free Software Foundation, Inc. 21License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 22This is free software: you are free to change and redistribute it. 23There is NO WARRANTY, to the extent permitted by law. 24Type "show copying" and "show warranty" for details. 25This GDB was configured as "x86_64-linux-gnu". 26Type "show configuration" for configuration details. 27For bug reporting instructions, please see: 28<http://www.gnu.org/software/gdb/bugs/>. 29Find the GDB manual and other documentation resources online at: 30 <http://www.gnu.org/software/gdb/documentation/>. 31 32For help, type "help". 33Type "apropos word" to search for commands related to "word"... 34Reading symbols from test...done. 35(gdb) break main 36Breakpoint 1 at 0x1129: file test.cpp, line 16. 37(gdb) run 38Starting program: /home/user/cpp/test 39 40Breakpoint 1, main () at test.cpp:16 4116 int main() {return 0;} 42(gdb) display a 431: a = {{position = {1, 2, 3}, normal = {4, 5, 6}}, {position = {2, 3, 0}, normal = {5, 6, 0}}, { 44 position = {2, 3, 4}, normal = {5, 6, 7}}, {position = {2, 3, 4}, normal = {5, 6, 0}}} 45(gdb)

多くてエラーになるケース(1)

text

1user@lubuntu:~/cpp$ cat test.cpp 2struct Vertex 3{ 4 float position[3]; 5 float normal[3]; 6}; 7 8Vertex a[] = { 9 {{1,2,3},{4,5,6}}, // 普通 10 {{2,3},{5,6}}, // 少ない 11 {{2,3,4},{5,6,7,8}},// 多い。これはgcc 8.2.0だとエラー 12 {2,3,4,5,6,7}, // 古い書き方(普通) 13 {2,3,4,5,6}, // 古い書き方(少ない) 14 //{2,3,4,5,6,7,8} // 古い書き方(多い)。これはgcc 8.2.0だとエラー 15}; 16 17int main() {return 0;} 18user@lubuntu:~/cpp$ g++ -g test.cpp -o test 19test.cpp:14:1: error: too many initializers for ‘float [3]’ 20 }; 21 ^ 22user@lubuntu:~/cpp$

多くてエラーになるケース(2)

text

1user@lubuntu:~/cpp$ cat test.cpp 2struct Vertex 3{ 4 float position[3]; 5 float normal[3]; 6}; 7 8Vertex a[] = { 9 {{1,2,3},{4,5,6}}, // 普通 10 {{2,3},{5,6}}, // 少ない 11 //{{2,3,4},{5,6,7,8}}, 多い。これはgcc 8.2.0だとエラー 12 {2,3,4,5,6,7}, // 古い書き方(普通) 13 {2,3,4,5,6}, // 古い書き方(少ない) 14 {2,3,4,5,6,7,8} // 古い書き方(多い)。これはgcc 8.2.0だとエラー 15}; 16 17int main() {return 0;} 18user@lubuntu:~/cpp$ g++ -g test.cpp -o test 19test.cpp:14:1: error: too many initializers for ‘Vertex’ 20 }; 21 ^ 22user@lubuntu:~/cpp$

投稿2019/02/12 18:48

編集2019/02/13 09:47
wwbQzhMkhhgEmhU

総合スコア343

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

moredeep

2019/02/13 09:37

>//{{2,3,4},{5,6,7}}, 多い。これはgcc 8.2.0だとエラー 普通のパターンと違いが無いような?
wwbQzhMkhhgEmhU

2019/02/13 09:43

あ、間違ってますね 修正しておきます
miiichat

2019/02/18 10:28

とても詳しい回答ありがとうございます! 自分でもいろいろ試してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問