画像をテクスチャとして立方体の面にマップして表示したいだけです。私の画像が入っている代わりに、立方体は完全に黒です。私の画像は両方とも 64x64 jpg です。
私のアプリケーションコードは以下です。もともとは、2 つのチェッカーボード テクスチャを生成し、キューブのすべての面に一度に 1 つずつ表示し、ユーザーがそれらを切り替えることができるプログラムでした。すべての面に市松模様の代わりに、画像が必要です。私は彼らのテクスチャ生成とテクスチャ読み込みコードをコメントアウトし、最も重要な ilutGLLoadImage() (DevIL から) に置き換えました。ほとんどの画像テクスチャ読み込み鳥を一石で殺すはずです。これは init() で発生します。唯一のコンソール出力は "1,2" (私の cout から) であり、これは画像が読み込まれ、有効なテクスチャ ID が与えられたことを意味します。立方体が黒いのはなぜですか?
アプリケーション コード (init() は、探し始めるのに適した場所です):
#include "Angel.h"
#include <IL\config.h>
#include <IL\ilut_config.h>
#include <IL\il.h>
#include <IL\ilu.h>
#include <IL\ilut.h>
#include <iostream>
using namespace std;
const int NumTriangles = 12; // (6 faces)(2 triangles/face)
const int NumVertices = 3 * NumTriangles;
const int TextureSize = 64;
typedef Angel::vec4 point4;
typedef Angel::vec4 color4;
// Texture objects and storage for texture image
//GLuint textures[2];
GLuint tex1;
GLuint tex2;
//GLubyte image[TextureSize][TextureSize][3];
//GLubyte image2[TextureSize][TextureSize][3];
// Vertex data arrays
point4 points[NumVertices];
//color4 quad_colors[NumVertices];
vec2 tex_coords[NumVertices];
// Array of rotation angles (in degrees) for each coordinate axis
enum { Xaxis = 0, Yaxis = 1, Zaxis = 2, NumAxes = 3 };
int Axis = Xaxis;
GLfloat Theta[NumAxes] = { 0.0, 0.0, 0.0 };
GLuint theta;
//----------------------------------------------------------------------------
int Index = 0;
void
quad( int a, int b, int c, int d )
{
point4 vertices[8] = {
point4( -0.5, -0.5, 0.5, 1.0 ),
point4( -0.5, 0.5, 0.5, 1.0 ),
point4( 0.5, 0.5, 0.5, 1.0 ),
point4( 0.5, -0.5, 0.5, 1.0 ),
point4( -0.5, -0.5, -0.5, 1.0 ),
point4( -0.5, 0.5, -0.5, 1.0 ),
point4( 0.5, 0.5, -0.5, 1.0 ),
point4( 0.5, -0.5, -0.5, 1.0 )
};
color4 colors[8] = {
color4( 0.0, 0.0, 0.0, 1.0 ), // black
color4( 1.0, 0.0, 0.0, 1.0 ), // red
color4( 1.0, 1.0, 0.0, 1.0 ), // yellow
color4( 0.0, 1.0, 0.0, 1.0 ), // green
color4( 0.0, 0.0, 1.0, 1.0 ), // blue
color4( 1.0, 0.0, 1.0, 1.0 ), // magenta
color4( 0.0, 1.0, 1.0, 1.0 ), // white
color4( 1.0, 1.0, 1.0, 1.0 ) // cyan
};
// bottom-left texture coord
// quad_colors[Index] = colors[a];
points[Index] = vertices[a];
tex_coords[Index] = vec2( 0.0, 0.0 );
Index++;
// top-left texture coord
// quad_colors[Index] = colors[a];
points[Index] = vertices[b];
tex_coords[Index] = vec2( 0.0, 1.0 );
Index++;
// top-right
// quad_colors[Index] = colors[a];
points[Index] = vertices[c];
tex_coords[Index] = vec2( 1.0, 1.0 );
Index++;
// bottom-left
// quad_colors[Index] = colors[a];
points[Index] = vertices[a];
tex_coords[Index] = vec2( 0.0, 0.0 );
Index++;
// top-right
// quad_colors[Index] = colors[a];
points[Index] = vertices[c];
tex_coords[Index] = vec2( 1.0, 1.0 );
Index++;
// bottom-right
// quad_colors[Index] = colors[a];
points[Index] = vertices[d];
tex_coords[Index] = vec2( 1.0, 0.0 );
Index++;
}
//----------------------------------------------------------------------------
void
colorcube()
{
quad( 1, 0, 3, 2 );
quad( 2, 3, 7, 6 );
quad( 3, 0, 4, 7 );
quad( 6, 5, 1, 2 );
quad( 4, 5, 6, 7 );
quad( 5, 4, 0, 1 );
}
//----------------------------------------------------------------------------
void
init()
{
colorcube();
ILuint devilError;
ilInit();
iluInit();
ilutInit();
devilError = ilGetError();
if (devilError != IL_NO_ERROR) {
printf ("Devil Error (ilInit: %s\n", iluErrorString(devilError));
exit (2);
}
ilutRenderer(ILUT_OPENGL);
GLuint openglID, openglError;
tex1 = ilutGLLoadImage("test1.jpg");
tex2 = ilutGLLoadImage("test2.jpg");
cout << tex1 << "," << tex2 << endl;
devilError = ilGetError();
if (devilError != IL_NO_ERROR) {
printf ("Error: %s\n", iluGetString (devilError));
exit (2);
}
if (openglError != GL_NO_ERROR) {
printf ("Opengl Error (ilutGLBindTexImage): %s\n", gluGetString (openglError));
exit (2);
}
// // Create a checkerboard pattern
// for ( int i = 0; i < 64; i++ ) {
// for ( int j = 0; j < 64; j++ ) {
// GLubyte c = (((i & 0x8) == 0) ^ ((j & 0x8) == 0)) * 255;
// image[i][j][0] = c;
// image[i][j][1] = c;
// image[i][j][2] = c;
// image2[i][j][0] = c;
// image2[i][j][1] = 0;
// image2[i][j][2] = c;
// }
// }
//
// // Initialize texture objects
//
// // Get unused texture identifiers
// glGenTextures( 2, textures );
//
glBindTexture( GL_TEXTURE_2D, tex1 );
//
// // Specify that 'image' is to be used as a two-dimensional texture
// glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, TextureSize, TextureSize, 0,
// GL_RGB, GL_UNSIGNED_BYTE, image );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST );
// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
//
glBindTexture( GL_TEXTURE_2D, tex2 );
// glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, TextureSize, TextureSize, 0,
// GL_RGB, GL_UNSIGNED_BYTE, image2 );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST );
// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glActiveTexture( GL_TEXTURE0 );
// Set the current texture object
glBindTexture( GL_TEXTURE_2D, tex1 );
// Create a vertex array object
GLuint vao;
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
// Create and initialize a buffer object
GLuint buffer;
glGenBuffers( 1, &buffer );
glBindBuffer( GL_ARRAY_BUFFER, buffer );
// glBufferData( GL_ARRAY_BUFFER,
// sizeof(points) + sizeof(quad_colors) + sizeof(tex_coords),
// NULL, GL_STATIC_DRAW );
glBufferData( GL_ARRAY_BUFFER,
sizeof(points) + sizeof(tex_coords),
NULL, GL_STATIC_DRAW );
// Specify an offset to keep track of where we're placing data in our
// vertex array buffer. We'll use the same technique when we
// associate the offsets with vertex attribute pointers.
GLintptr offset = 0;
glBufferSubData( GL_ARRAY_BUFFER, offset, sizeof(points), points );
offset += sizeof(points);
// glBufferSubData( GL_ARRAY_BUFFER, offset,
// sizeof(quad_colors), quad_colors );
// offset += sizeof(quad_colors);
glBufferSubData( GL_ARRAY_BUFFER, offset, sizeof(tex_coords), tex_coords );
// Load shaders and use the resulting shader program
GLuint program = InitShader( "vshader71.glsl", "fshader71.glsl" );
glUseProgram( program );
// set up vertex arrays
offset = 0;
GLuint vPosition = glGetAttribLocation( program, "vPosition" );
glEnableVertexAttribArray( vPosition );
glVertexAttribPointer( vPosition, 4, GL_FLOAT, GL_FALSE, 0,
BUFFER_OFFSET(offset) );
offset += sizeof(points);
// GLuint vColor = glGetAttribLocation( program, "vColor" );
// glEnableVertexAttribArray( vColor );
// glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0,
// BUFFER_OFFSET(offset) );
// offset += sizeof(quad_colors);
// Pass the texture coordinates as a vertex attribute with the identifier 'vTextCoord'
GLuint vTexCoord = glGetAttribLocation( program, "vTexCoord" );
glEnableVertexAttribArray( vTexCoord );
glVertexAttribPointer( vTexCoord, 2, GL_FLOAT, GL_FALSE, 0,
BUFFER_OFFSET(offset) );
// Set the value of the fragment shader texture sampler variable
// ("texture") to the the appropriate texture unit. In this case,
// zero, for GL_TEXTURE0 which was previously set by calling
// glActiveTexture().
glUniform1i( glGetUniformLocation(program, "texture"), 0 );
theta = glGetUniformLocation( program, "theta" );
glEnable( GL_DEPTH_TEST );
glClearColor( 1.0, 1.0, 1.0, 1.0 );
}
void
display( void )
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glUniform3fv( theta, 1, Theta );
glDrawArrays( GL_TRIANGLES, 0, NumVertices );
glutSwapBuffers();
}
//----------------------------------------------------------------------------
void
mouse( int button, int state, int x, int y )
{
if ( state == GLUT_DOWN ) {
switch( button ) {
case GLUT_LEFT_BUTTON: Axis = Xaxis; break;
case GLUT_MIDDLE_BUTTON: Axis = Yaxis; break;
case GLUT_RIGHT_BUTTON: Axis = Zaxis; break;
}
}
}
//----------------------------------------------------------------------------
void
idle( void )
{
Theta[Axis] += 0.01;
if ( Theta[Axis] > 360.0 ) {
Theta[Axis] -= 360.0;
}
glutPostRedisplay();
}
//----------------------------------------------------------------------------
void
keyboard( unsigned char key, int mousex, int mousey )
{
switch( key ) {
case 033: // Escape Key
case 'q': case 'Q':
exit( EXIT_SUCCESS );
break;
case '1':
glBindTexture( GL_TEXTURE_2D, tex1 );
break;
case '2':
glBindTexture( GL_TEXTURE_2D, tex2 );
break;
}
glutPostRedisplay();
}
//----------------------------------------------------------------------------
int
main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );
glutInitWindowSize( 512, 512 );
glutInitContextVersion( 3, 2 );
glutInitContextProfile( GLUT_CORE_PROFILE );
glutCreateWindow( "Texture Cube" );
glewExperimental = GL_TRUE;
glewInit();
init();
glutDisplayFunc( display );
glutKeyboardFunc( keyboard );
glutMouseFunc( mouse );
glutIdleFunc( idle );
glutMainLoop();
return 0;
}
頂点シェーダー:
#version 150
in vec4 vPosition;
in vec2 vTexCoord;
out vec4 color;
out vec2 texCoord;
uniform vec3 theta;
void main()
{
const float DegreesToRadians = 3.14159265 / 180.0;
vec3 c = cos( DegreesToRadians * theta );
vec3 s = sin( DegreesToRadians * theta );
mat4 rx = mat4( 1.0, 0.0, 0.0, 0.0,
0.0, c.x, -s.x, 0.0,
0.0, s.x, c.x, 0.0,
0.0, 0.0, 0.0, 1.0);
mat4 ry = mat4( c.y, 0.0, s.y, 0.0,
0.0, 1.0, 0.0, 0.0,
-s.y, 0.0, c.y, 0.0,
0.0, 0.0, 0.0, 1.0 );
// Workaround for bug in ATI driver
ry[1][0] = 0.0;
ry[1][1] = 1.0;
mat4 rz = mat4( c.z, -s.z, 0.0, 0.0,
s.z, c.z, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0 );
// Workaround for bug in ATI driver
rz[2][2] = 1.0;
texCoord = vTexCoord;
gl_Position = rz * ry * rx * vPosition;
}
フラグメント シェーダー:
#version 150
in vec2 texCoord;
out vec4 fColor;
uniform sampler2D texture;
void main()
{
fColor = texture2D( texture, texCoord );
}