使用两个纹理:输出窗口不保留在屏幕上
Posted
技术标签:
【中文标题】使用两个纹理:输出窗口不保留在屏幕上【英文标题】:Using Two Textures: Output Window Doesn't Retain On Screen 【发布时间】:2013-05-12 04:49:55 【问题描述】:此代码最初使用一种纹理。我复制了一些函数来使用两个纹理。似乎没有任何错误,但是当我运行时,我只看到黑色的命令窗口一会儿然后它就关闭了。我应该添加任何其他行吗?
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "support.h"
using namespace std;
/* GLUT callback Handlers */
MYPOINT*ptsW,*ptsR;
MYFACE *faceW,*faceR;
GLuint *images;
GLubyte *image;
GLuint texture;
void loadImage(int n, int m, char *fName);
GLuint LoadTexture(int width, int height);
int n=200,m=200;
void constructBox();
void constructTri();
void init();
void showPictureW();
void showPictureR();
float rX=0, rY=0, rZ=0;
float tX=0, tY=0, tZ=-3.5;
float nr = -5.0;
float fr = -4.0;
float tpx = 1.0, tpy = 1.0;
float btx = -1.0, bty = -1.0;
float dZ =-2.0;
void init()
constructBox();
loadImage(n,m,"wall.ppm");
constructTri();
loadImage(n,m,"roof.ppm");
void showPictureW()
/* clear all pixels */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
texture = LoadTexture(n,m);
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, texture );
glColor3d(1,1,1);
//face 1
glBegin( GL_POLYGON );
glTexCoord2d(1.0,1.0); glVertex3d(-1.0,1.0,-2.0);
glTexCoord2d(1.0,0.0); glVertex3d(-1,-1.0,-2.0); //1 -1
glTexCoord2d(0.0,0.0); glVertex3d(1.0,-1.0,-2.0); //-1 -1
glEnd();
//face 2
glBegin( GL_POLYGON );
glTexCoord2d(0.0,0.0); glVertex3d(1.0,-1.0,-2.0);
glTexCoord2d(0.0,1.0); glVertex3d(1.0,1.0,-2.0);
glTexCoord2d(1.0,1.0); glVertex3d(-1.0,1.0,-2.0); //1 -1
glEnd();
void showPictureR()
/* clear all pixels */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
texture = LoadTexture(n,m);
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, texture );
glColor3d(1,1,1);
//face 1
glBegin( GL_POLYGON );
glTexCoord2d(1.0,1.0); glVertex3d(-1.0,1.0,-2.0);
glTexCoord2d(1.0,0.0); glVertex3d(-1,-1.0,-2.0); //1 -1
glTexCoord2d(0.0,0.0); glVertex3d(1.0,-1.0,-2.0); //-1 -1
glEnd();
//face 2
glBegin( GL_POLYGON );
glTexCoord2d(0.0,0.0); glVertex3d(1.0,-1.0,0.0);
glTexCoord2d(0.0,1.0); glVertex3d(1.0,3.0,-2.0);
glTexCoord2d(1.0,1.0); glVertex3d(-1.0,3.0,-2.0); //1 -1
glEnd();
static void
resize(int width, int height)
const float ar = (float) width / (float) height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-ar, ar, -1.0, 1.0, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity() ;
init();
static void
display(void)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3d(1,0,0);
glPushMatrix();
glTranslated(0,0,0);
glRotated(rX,0,0,1);
glRotated(rY,0,1,0);
glRotated(rZ,1,0,0);
showPictureW();
glPopMatrix();
glPushMatrix();
glTranslated(0,0,0);
glRotated(rX,0,0,1);
glRotated(rY,1,1,0);
glRotated(rZ,1,0,0);
showPictureR();
glPopMatrix();
glutSwapBuffers();
void constructBox()
int nPtsW = 8;
int nFaceW = 12;
ptsW = new MYPOINT[nPtsW];
faceW = new MYFACE[nFaceW];
getPoints(ptsW,"myVertWall.txt");
getFace(faceW,"myFaceWall.txt");
void constructTri()
int nPtsR = 6;
int nFaceR = 8;
ptsR = new MYPOINT[nPtsR];
faceR = new MYFACE[nFaceR];
getPoints(ptsR,"myVertRoof.txt");
getFace(faceR,"myFaceRoof.txt");
static void
key(unsigned char key, int x, int y)
switch (key)
case 27 :
case 'q':
exit(0);
break;
case '+':
break;
case 'x':
rX= rX + 0.5;
break;
case 'X':
rX= rX - 0.5;
break;
case 'y':
rY= rY + 0.5;
break;
case 'Y':
rY= rY - 0.5;
break;
case 'z':
rZ= rZ + 0.5;
break;
case 'Z':
rZ= rZ - 0.5;
break;
case 'd':
dZ = dZ+100.0;// horizontal movement to the left
printf("Nilai dZ=%.2f\n",dZ);
break;
case 'D':
dZ = dZ-100.0;// horizontal movement to the right
printf("Nilai dZ=%.2f\n",dZ);
break;
glutPostRedisplay();
static void
idle(void)
glutPostRedisplay();
const GLfloat light_ambient[] = 0.0f, 0.0f, 0.0f, 1.0f ;
const GLfloat light_diffuse[] = 1.0f, 1.0f, 1.0f, 1.0f ;
const GLfloat light_specular[] = 1.0f, 1.0f, 1.0f, 1.0f ;
const GLfloat light_position[] = 2.0f, 5.0f, 5.0f, 0.0f ;
const GLfloat mat_ambient[] = 0.7f, 0.7f, 0.7f, 1.0f ;
const GLfloat mat_diffuse[] = 0.8f, 0.8f, 0.8f, 1.0f ;
const GLfloat mat_specular[] = 1.0f, 1.0f, 1.0f, 1.0f ;
const GLfloat high_shininess[] = 100.0f ;
/* Program entry point */
int main(int argc, char *argv[])
glutInit(&argc, argv);
glutInitWindowSize(640,480);
glutInitWindowPosition(10,10);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("FreeGLUT Shapes");
glutReshapeFunc(resize);
glutDisplayFunc(display);
glutKeyboardFunc(key);
glutIdleFunc(idle);
glClearColor(1,1,1,1);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
glutMainLoop();
return EXIT_SUCCESS;
GLuint LoadTexture(int width, int height)
image = new BYTE[width*height*3*sizeof(BYTE)];
int nm = width*height;
for(int i=0;i<nm*3;i++)//copy each value 3 times
image[i] = (GLubyte)images[i];
image[i] = (GLubyte)images[i];
image[i] = (GLubyte)images[i];
bool wrap = true;
glGenTextures( 1, &texture );
// select our current texture
glBindTexture( GL_TEXTURE_2D, texture );
// select modulate to mix texture with color for shading
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
// when texture area is small, bilinear filter the closest mipmap
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
// when texture area is large, bilinear filter the first mipmap
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
// if wrap is true, the texture wraps over at the edges (repeat)
// ... false, the texture ends at the edges (clamp)
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap ? GL_REPEAT : GL_CLAMP );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,wrap ? GL_REPEAT : GL_CLAMP );
// build our texture mipmaps
gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height,
GL_RGB, GL_UNSIGNED_BYTE, image );
// free buffer
//free( data );
return texture;
void loadImage(int n, int m, char *fName)
FILE *fd;
int k, nm;
int i;
char bc[71];
float s;
unsigned int red, green, blue;
char c;
fd = fopen(fName,"r");
fscanf(fd,"%[^\n]",bc); // reads data from stream
printf("Nilai %s \n\n",bc);
if(bc[0]!='P'|| bc[1]!='3')
printf("%s Not a PPM file\n",bc);
exit(0);
printf("%s is a PPM file\n",bc);
fscanf(fd,"%s",bc);
printf("line 1 %s \n",bc);
fscanf(fd,"%s",bc);
printf("line 2 %s \n",bc);
fscanf(fd,"%s",bc);
printf("line 3 %s \n",bc);
fscanf(fd,"%s",bc);
printf("line 4 %s \n",bc);
fscanf(fd,"%c",&c);
ungetc(c,fd);
fscanf(fd,"%d %d %d", &n,&m,&k);
// printf("%d rows %d columns max value = %d\n",n,m,k);
nm = n*m;
images = new GLuint[3*sizeof(GLuint)*nm];
//s = 255./k;
for (i=0;i<nm;i++)
fscanf(fd,"%u %u %u", &red, &green, &blue);
images[3*nm-3*i-3] = red;
images[3*nm-3*i-2] = green;
images[3*nm-3*i-1] = blue;
int totSize = 3*nm;
int tot=0;
for(i=0;i<nm;i++)
// fprintf(stderr,"(%d,%d,%d) ", images[3*nm-3*i-3], images[3*nm-3*i-2], images[3*nm-3*i-1]);
tot++;
// printf("%d \n",tot);
坐标还在。我只是在尝试这两种纹理是否正常。
【问题讨论】:
为什么texture
是全球性的?
按原样获取此代码。不能是全球性的吗?很抱歉没有更好的答案。
【参考方案1】:
试试这个:
#include <GL/glut.h>
#include <vector>
float rX=0, rY=0, rZ=0;
float dZ =-2.0;
static void key(unsigned char key, int x, int y)
switch (key)
case 27 :
case 'q':
exit(0);
break;
case '+':
break;
case 'x':
rX= rX + 0.5;
break;
case 'X':
rX= rX - 0.5;
break;
case 'y':
rY= rY + 0.5;
break;
case 'Y':
rY= rY - 0.5;
break;
case 'z':
rZ= rZ + 0.5;
break;
case 'Z':
rZ= rZ - 0.5;
break;
case 'd':
dZ = dZ+100.0;// horizontal movement to the left
break;
case 'D':
dZ = dZ-100.0;// horizontal movement to the right
break;
void showPictureW()
//face 1
glBegin( GL_TRIANGLES );
glTexCoord2d(1.0,1.0); glVertex3d(-1.0,1.0,-2.0);
glTexCoord2d(1.0,0.0); glVertex3d(-1,-1.0,-2.0); //1 -1
glTexCoord2d(0.0,0.0); glVertex3d(1.0,-1.0,-2.0); //-1 -1
//face 2
glTexCoord2d(0.0,0.0); glVertex3d(1.0,-1.0,-2.0);
glTexCoord2d(0.0,1.0); glVertex3d(1.0,1.0,-2.0);
glTexCoord2d(1.0,1.0); glVertex3d(-1.0,1.0,-2.0); //1 -1
glEnd();
void showPictureR()
//face 1
glBegin( GL_TRIANGLES );
glTexCoord2d(1.0,1.0); glVertex3d(-1.0,1.0,-2.0);
glTexCoord2d(1.0,0.0); glVertex3d(-1,-1.0,-2.0); //1 -1
glTexCoord2d(0.0,0.0); glVertex3d(1.0,-1.0,-2.0); //-1 -1
//face 2
glTexCoord2d(0.0,0.0); glVertex3d(1.0,-1.0,0.0);
glTexCoord2d(0.0,1.0); glVertex3d(1.0,3.0,-2.0);
glTexCoord2d(1.0,1.0); glVertex3d(-1.0,3.0,-2.0); //1 -1
glEnd();
GLuint texture1 = 0;
GLuint texture2 = 0;
static void display(void)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
double ar = w / h;
glFrustum(-ar, ar, -1.0, 1.0, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity() ;
glEnable( GL_TEXTURE_2D );
glColor3ub(255,255,255);
glBindTexture( GL_TEXTURE_2D, texture1 );
glPushMatrix();
glTranslated(0,0,0);
glRotated(rX,0,0,1);
glRotated(rY,0,1,0);
glRotated(rZ,1,0,0);
showPictureW();
glPopMatrix();
glBindTexture( GL_TEXTURE_2D, texture2 );
glPushMatrix();
glTranslated(0,0,0);
glRotated(rX,0,0,1);
glRotated(rY,1,1,0);
glRotated(rZ,1,0,0);
showPictureR();
glPopMatrix();
glutSwapBuffers();
static void idle(void)
glutPostRedisplay();
GLuint LoadTexture(int width, int height, unsigned int component )
std::vector< unsigned char > image( width*height*3 );
for(int i=0;i< width*height*3; i += 3)
image[i+0] = 0;
image[i+1] = 0;
image[i+2] = 0;
image[i+component] = rand() % 255;
bool wrap = true;
GLuint texture = 0;
glGenTextures( 1, &texture );
// select our current texture
glBindTexture( GL_TEXTURE_2D, texture );
// select modulate to mix texture with color for shading
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
// when texture area is small, bilinear filter the closest mipmap
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
// when texture area is large, bilinear filter the first mipmap
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
// if wrap is true, the texture wraps over at the edges (repeat)
// ... false, the texture ends at the edges (clamp)
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap ? GL_REPEAT : GL_CLAMP );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,wrap ? GL_REPEAT : GL_CLAMP );
// build our texture mipmaps
gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, width, height, GL_RGB, GL_UNSIGNED_BYTE, &image[0] );
return texture;
int main(int argc, char *argv[])
glutInit(&argc, argv);
glutInitWindowSize(640,480);
glutInitWindowPosition(10,10);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("FreeGLUT Shapes");
glutDisplayFunc(display);
glutKeyboardFunc(key);
glutIdleFunc(idle);
glClearColor(1,1,1,1);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
const GLfloat light_ambient[] = 0.0f, 0.0f, 0.0f, 1.0f ;
const GLfloat light_diffuse[] = 1.0f, 1.0f, 1.0f, 1.0f ;
const GLfloat light_specular[] = 1.0f, 1.0f, 1.0f, 1.0f ;
const GLfloat light_position[] = 2.0f, 5.0f, 5.0f, 0.0f ;
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
const GLfloat mat_ambient[] = 0.7f, 0.7f, 0.7f, 1.0f ;
const GLfloat mat_diffuse[] = 0.8f, 0.8f, 0.8f, 1.0f ;
const GLfloat mat_specular[] = 1.0f, 1.0f, 1.0f, 1.0f ;
const GLfloat high_shininess[] = 100.0f ;
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
srand( 0 );
texture1 = LoadTexture( 256, 256, 0 );
texture2 = LoadTexture( 256, 256, 1 );
glutMainLoop();
return EXIT_SUCCESS;
【讨论】:
输出是一个带有颗粒状红色纹理的正方形,我认为这是因为texture1 = LoadTexture( 256, 256, 0 );
和texture2 = LoadTexture( 256, 256, 1 );
。是对的吗?如果我要使用 .ppm 图像,我在哪里指定呢?我的任务是建造一所房子,因此是盒子(墙)和三角形(屋顶)。我希望这反映在我发布的代码中。
修改 LoadTexture()
以加载 PPM。重要的部分是使用两个纹理对象,每个纹理一个。并且不生成/重新加载纹理每一帧。
我已经从我的原始代码修改了LoadTexture()
,它运行良好。将其合并到您的代码中。谢谢:)以上是关于使用两个纹理:输出窗口不保留在屏幕上的主要内容,如果未能解决你的问题,请参考以下文章