OpenGL勉強中です。
サンプルコード実行のため環境作成して、
OpenGL 立方体プログラム を実行しました。
実行サンプル
立方体の表示。
左がglDrawArray関数で描いたもの。
右がglDrawElement関数で描いたもの。
上下左右キーで回転する。
実行環境
windows10
VisualStudio2019
openGL glut (visual strudio nugetよりnupengl)
関連資料
実行手順
下記URLを参考にVisual Studio 2019 でプロジェクト作成 ~ .cpp作成前準備までする。
https://tokoik.github.io/opengl/vs2019.pdf
「Visual Studio 2019 で NuGet を使ってからのプロジェクトから OpenGL をビルドできるプロジェクトを作る」
その後、ソースコードを書いて、実行ボタンで実行。
ソースコード
※ #include はコメントアウトが必要
読み込むライブラリはGL/glut.h のみにする。
//参考:http://math.hws.edu/graphicsbook/source/glut/cubes-with-vertex-arrays.c
/* Use OpenGL to draw two cubes, one using glDrawArrays,
* and one using glDrawElements. The arrow keys can be
* used to rotate both cubes.
*
* Note that this program does not use lighting.
*
* This program must be linked with the GL and GLUT libraries.
* For example, on Linus with the gcc compiler,
*
* gcc -o cubes cubes-with-vertex-arrays.c -lGL -lglut
*/
//#include <GL/gl.h>
# include <GL/glut.h>
int rotateX = 15, rotateY = -15, rotateZ = 0; // rotation amounts about axes, controlled by keyboard
/* Arrays for use with glDrawElements. This is the data for a cube with 6 different
* colors at the six vertices. (Looks kind of strange without lighting.)
*/
float vertexCoords[24] = { // Coordinates for the vertices of a cube.
1,1,1, 1,1,-1, 1,-1,-1, 1,-1,1,
-1,1,1, -1,1,-1, -1,-1,-1, -1,-1,1 };
float vertexColors[24] = { // An RGB color value for each vertex
1,1,1, 1,0,0, 1,1,0, 0,1,0,
0,0,1, 1,0,1, 0,0,0, 0,1,1 };
int elementArray[24] = { // Vertex number for the six faces.
0,1,2,3, 0,3,7,4, 0,4,5,1,
6,2,1,5, 6,5,4,7, 6,7,3,2 };
/* We will draw edges for the first cube using this array with glDrawElements.
* (It looks pretty bad without lighting if edges aren't drawn.
*/
int edgeElementArray[24] = {
0,1, 1,5, 5,4, 4,0, // edges of the top face
7,3, 3,2, 2,6, 6,7, // edges of the bottom face
1,2, 0,3, 4,7, 5,6 }; // edges connecting top face to bottom face
/* Arrays for use with glDrawArrays. The coordinate array contains four sets of vertex
* coordinates for each face. The color array must have a color for each vertex. Since
* the color of each face is solid, there is a lot of redundancy in the color array.
* There is also redundancy in the coordinate array, compared to using glDrawElements.
* But note that it is impossible to use a single call to glDrawElements to draw a cube
* with six faces where each face has a different solid color, since with glDrawElements,
* the colors are associated with the vertices, not the faces.
*/
float cubeCoords[72] = {
1,1,1, -1,1,1, -1,-1,1, 1,-1,1, // face #1
1,1,1, 1,-1,1, 1,-1,-1, 1,1,-1, // face #2
1,1,1, 1,1,-1, -1,1,-1, -1,1,1, // face #3
-1,-1,-1, -1,1,-1, 1,1,-1, 1,-1,-1, // face #4
-1,-1,-1, -1,-1,1, -1,1,1, -1,1,-1, // face #5
-1,-1,-1, 1,-1,-1, 1,-1,1, -1,-1,1 }; // face #6
float cubeFaceColors[72] = {
1,0,0, 1,0,0, 1,0,0, 1,0,0, // face #1 is red
0,1,0, 0,1,0, 0,1,0, 0,1,0, // face #2 is green
0,0,1, 0,0,1, 0,0,1, 0,0,1, // face #3 is blue
1,1,0, 1,1,0, 1,1,0, 1,1,0, // face #4 is yellow
0,1,1, 0,1,1, 0,1,1, 0,1,1, // face #5 is cyan
1,0,1, 1,0,1, 1,0,1, 1,0,1, }; // face #6 is red
//----------------------------------------------------
// 関数プロトタイプ(後に呼び出す関数名と引数の宣言)
//----------------------------------------------------
void display();
void specialKeyFunction(int key, int x, int y);
void initGL();
//----------------------------------------------------
// メイン関数
//----------------------------------------------------
// ----------------------------------------------------------------------
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(600, 300);
glutInitWindowPosition(100, 100);
glutCreateWindow("USE ARROW KEYS TO ROTATE; HOME KEY RESETS");
initGL();
glutDisplayFunc(display);
glutSpecialFunc(specialKeyFunction);
glutMainLoop();
return 0;
}
void display() {
// called when the display needs to be drawn
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity(); // Set up modelview transform, first cube.
glTranslatef(-2, 0, 0); // Move cube to left half of window.
glRotatef(rotateZ, 0, 0, 1); // Apply rotations.
glRotatef(rotateY, 0, 1, 0);
glRotatef(rotateX, 1, 0, 0);
glVertexPointer(3, GL_FLOAT, 0, cubeCoords); // Set data type and location, first cube.
glColorPointer(3, GL_FLOAT, 0, cubeFaceColors);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glDrawArrays(GL_QUADS, 0, 24); // Draw the first cube!
// Second cube, using glDrawElements. Also draw the cube edges, and enable polygon offset
// while the faces of the cube are being drawn.
glLoadIdentity(); // Set up modelview transform, first cube.
glTranslatef(2, 0, 0); // Move cube to right half of window.
glRotatef(rotateZ, 0, 0, 1); // Apply rotations.
glRotatef(rotateY, 0, 1, 0);
glRotatef(rotateX, 1, 0, 0);
glVertexPointer(3, GL_FLOAT, 0, vertexCoords); // Set data type and location, second cube.
glColorPointer(3, GL_FLOAT, 0, vertexColors);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(1, 1);
glDrawElements(GL_QUADS, 24, GL_UNSIGNED_INT, elementArray); // Draw the second cube!
glDisable(GL_POLYGON_OFFSET_FILL);
glDisableClientState(GL_COLOR_ARRAY); // Don't use color array for the edges.
glColor3f(0, 0, 0); // The edges will be black.
glLineWidth(2);
glDrawElements(GL_LINES, 24, GL_UNSIGNED_INT, edgeElementArray); // Draw the edges!
glutSwapBuffers();
}
void specialKeyFunction(int key, int x, int y) {
// called when a special key is pressed
if (key == GLUT_KEY_LEFT)
rotateY -= 15;
else if (key == GLUT_KEY_RIGHT)
rotateY += 15;
else if (key == GLUT_KEY_DOWN)
rotateX += 15;
else if (key == GLUT_KEY_UP)
rotateX -= 15;
else if (key == GLUT_KEY_PAGE_UP)
rotateZ += 15;
else if (key == GLUT_KEY_PAGE_DOWN)
rotateZ -= 15;
else if (key == GLUT_KEY_HOME)
rotateX = rotateY = rotateZ = 0;
glutPostRedisplay();
}
void initGL() {
// called by main() to do initialization for this program.
glMatrixMode(GL_PROJECTION);
glOrtho(-4, 4, -2, 2, -2, 2); // simple orthographic projection
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
glClearColor(0.5, 0.5, 0.5, 1);
}
実行
補足
手順の前に、環境整備として、glutのインストールとして下記もした。
(多分以下は不要でも動作するはずだが補足まで。)
Windows 32bit向けのファイルをNate Robins氏のサイトからダウンロードする。
READMEに従って次のようにコピーする。
| ファイル | コピー先 |
| ---- | ---- | ---- |
| glut.h | C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\XX.XX.XXXXX\include\GL\ | include フォルダ内にGLフォルダを作成 |
| glut32.lib | C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\XX.XX.XXXXX\lib\x86\ | _ |
| glut32.dll | C:\Windows\System\ | コンパイル済ファイルの実行に必要 |