首先,从网上和红宝书书上找了些代码。凭自己的那点小经验改了改,希望能做一个颜色的立方体。即X、Y、Z各个轴分别代表RGB分量。
以下是没有使用自动生成纹理坐标的方式写的,效果还不错。
#define GLUT_DISABLE_ATEXIT_HACK
#include <stdlib.h>
#include <stdio.h>
#include <gl/glew.h>
#include <GL/glut.h>
#ifdef GL_VERSION_1_2
#define iWidth 16
#define iHeight 16
#define iDepth 16
static GLubyte image[iDepth][iHeight][iWidth][3];
static GLuint texName;
GLfloat angleX,angleY,angleZ;
/* Create a 16x16x16x3 array with different color values in
* each array element [r, g, b]. Values range from 0 to 255.
*/
void makeImage(void)
{
int s, t, r;
for (s = 0; s < 16; s++)
for (t = 0; t < 16; t++)
for (r = 0; r < 16; r++) {
image[r][t][s][0] = (GLubyte) (s * 17);
image[r][t][s][1] = (GLubyte) (t * 17);
image[r][t][s][2] = (GLubyte) (r * 17);
}
}
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
makeImage();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_3D, texName);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, iWidth, iHeight,
iDepth, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glEnable(GL_TEXTURE_3D);
angleX = 0.0;
angleY = 0.0;
angleZ = 0.0;
}
void display(void)
{
int i;
glPushMatrix();
glTranslatef(1.0,0.0,-1.0);
glRotatef(angleX,1.0,0.0,0.0);
glRotatef(angleY,0.0,1.0,0.0);
glRotatef(angleZ,0.0,0.0,1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_QUADS);
for(i = 0; i < 100; i ++)
{
glTexCoord3f(0.0, 0.0, (GLfloat)i * 0.01); glVertex3f(-2.25, -1.0, (GLfloat)i * 0.01);
glTexCoord3f(0.0, 1.0, (GLfloat)i * 0.01); glVertex3f(-2.25, 1.0, (GLfloat)i * 0.01);
glTexCoord3f(1.0, 1.0, (GLfloat)i * 0.01); glVertex3f(-0.25, 1.0, (GLfloat)i * 0.01);
glTexCoord3f(1.0, 0.0, (GLfloat)i * 0.01); glVertex3f(-0.25, -1.0, (GLfloat)i * 0.01);
}
glEnd();
glPopMatrix();
glFlush();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 30.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -4.0);
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 's':
case 'S':
angleX +=15.0;
glutPostRedisplay();
break;
case 'd':
case 'D':
angleY += 15.0;
glutPostRedisplay();
break;
case 'f':
case 'F':
angleZ += 15.0;
glutPostRedisplay();
break;
case 27:
exit(0);
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(250, 250);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
glewInit();
init();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutKeyboardFunc (keyboard);
glutMainLoop();
return 0;
}
#else
int main(int argc, char** argv)
{
fprintf (stderr, "This program demonstrates a feature which is not in OpenGL Version 1.0 or 1.1.\n");
fprintf (stderr, "If your implementation of OpenGL has the right extensions,\n");
fprintf (stderr, "you may be able to modify this program to make it run.\n");
return 0;
}
#endif
效果图:两个不同的角度。
然后,我想把它改成自动生成三维纹理坐标的,但是没有成功。
主要修改的代码有两处:初始化函数Init()和绘制函数Display()
程序代码如下:
#define GLUT_DISABLE_ATEXIT_HACK
#include <stdlib.h>
#include <stdio.h>
#include <gl/glew.h>
#include <GL/glut.h>
#ifdef GL_VERSION_1_2
#define iWidth 16
#define iHeight 16
#define iDepth 16
static GLubyte image[iDepth][iHeight][iWidth][3];
static GLuint texName;
GLfloat angleX,angleY,angleZ;
GLfloat xPlane[] = {1.0,0.0,0.0,0.0};
GLfloat yPlane[] = {0.0,1.0,0.0,0.0};
GLfloat zPlane[] = {0.0,0.0,1.0,0.0};
float mat[16];
/* Create a 16x16x16x3 array with different color values in
* each array element [r, g, b]. Values range from 0 to 255.
*/
void makeImage(void)
{
int s, t, r;
for (s = 0; s < 16; s++)
for (t = 0; t < 16; t++)
for (r = 0; r < 16; r++) {
image[r][t][s][0] = (GLubyte) (s * 17);
image[r][t][s][1] = (GLubyte) (t * 17);
image[r][t][s][2] = (GLubyte) (r * 17);
}
}
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
makeImage();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_3D, texName);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,
GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR);
glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
glTexGeni(GL_R,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
glTexGenfv(GL_S,GL_OBJECT_PLANE,xPlane);
glTexGenfv(GL_T,GL_OBJECT_PLANE,yPlane);
glTexGenfv(GL_R,GL_OBJECT_PLANE,zPlane);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, iWidth, iHeight,
iDepth, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
glEnable(GL_TEXTURE_3D);
glLoadIdentity();
angleX = 0.0;
angleY = 0.0;
angleZ = 0.0;
}
void display(void)
{
int i;
glPushMatrix();
glTranslatef(0.0,0.0,-1.0);
glRotatef(angleX,1.0,0.0,0.0);
glRotatef(angleY,0.0,1.0,0.0);
glRotatef(angleZ,0.0,0.0,1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for (int ii=0;ii<160;ii++){
glPushMatrix();
glTranslatef(0.0f,0.0f,-1.0f +(float)ii*2.0f/(float)(160-1));
glRectf(-1.0,-1.0,1.0,1.0);
glPopMatrix();
}
glPopMatrix();
glFlush();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 30.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -4.0);
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 's':
case 'S':
angleX +=15.0;
glutPostRedisplay();
break;
case 'd':
case 'D':
angleY += 15.0;
glutPostRedisplay();
break;
case 'f':
case 'F':
angleZ += 15.0;
glutPostRedisplay();
break;
case 27:
exit(0);
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(250, 250);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
glewInit();
init();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutKeyboardFunc (keyboard);
glutMainLoop();
return 0;
}
#else
int main(int argc, char** argv)
{
fprintf (stderr, "This program demonstrates a feature which is not in OpenGL Version 1.0 or 1.1.\n");
fprintf (stderr, "If your implementation of OpenGL has the right extensions,\n");
fprintf (stderr, "you may be able to modify this program to make it run.\n");
return 0;
}
#endif
所得到的结果: