我想在我的场景中添加多个纹理我有一个纹理工作,但我不知道如何包含其他纹理.
#include <windows.h>
#include <gl\gl.h>
#include <gl\glut.h>
#include <stdlib.h>
#include <iostream>
void init(void);
void display(void);
void keyboard(unsigned char, int, int);
void resize(int, int);
void drawcube(float, float, float, float, float, float, int);
int is_depth;
#define ROAD 0
struct Image
{
unsigned long size_x;
unsigned long size_y;
char *data;
};
typedef struct Image Image;
const int textureCount = 1;
Image myTextureData[textureCount];
GLuint theTexture[textureCount];
char* textureFilenames[textureCount] = {"road.bmp"};
int main (int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(600, 600);
glutInitWindowPosition(40, 40);
glutCreateWindow("3D World");
init();
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glEnable(GL_TEXTURE_2D);
glutReshapeFunc(resize);
glutMainLoop();
return 0;
}
int imageLoader(const char *filename, Image *image)
{
FILE *file;
unsigned long size;
unsigned long i;
unsigned short int planes;
unsigned short int bpp;
char temp;
char finalName[80];
glTexCoord2f(1.0, 0.0);
strcpy(finalName, "" );
strcat(finalName, filename);
if ((file = fopen(finalName, "rb"))==NULL)
{
printf("File Not Found : %s\n",finalName);
return 0;
}
fseek(file, 18, SEEK_CUR);
glTexCoord2f(1.0, 0.0);
if ((i = fread(&image->size_x, 4, 1, file)) != 1)
{
printf("Error reading width from %s.\n", finalName);
return 0;
}
if ((i = fread(&image->size_y, 4, 1, file)) != 1)
{
printf("Error reading height from %s.\n", finalName);
return 0;
}
size = image->size_x * image->size_y * 3;
if ((fread(&planes, 2, 1, file)) != 1)
{
printf("Error reading planes from %s.\n", finalName);
return 0;
}
if (planes != 1)
{
printf("Planes from %s is not 1: %u\n", finalName, planes);
return 0;
}
if ((i = fread(&bpp, 2, 1, file)) != 1)
{
printf("Error reading bpp from %s.\n", finalName);
return 0;
}
if (bpp != 24)
{
printf("Bpp from %s is not 24: %u\n", finalName, bpp);
return 0;
}
fseek(file, 24, SEEK_CUR);
image->data = (char *) malloc(size);
if (image->data == NULL)
{
printf("Error allocating memory for color-corrected image data");
return 0;
}
if ((i = fread(image->data, size, 1, file)) != 1)
{
printf("Error reading image data from %s.\n", finalName);
return 0;
}
for (i=0;i<size;i+=3)
{
temp = image->data[i];
image->data[i] = image->data[i+2];
image->data[i+2] = temp;
}
return 1;
}
void textureLoader()
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
for(int k=0; k < textureCount; k++)
{
if(!imageLoader(textureFilenames[k], &myTextureData[k]))
exit(1);
glGenTextures(1, &theTexture[k]);
glBindTexture(GL_TEXTURE_2D, theTexture[k]);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, myTextureData[k].size_x, myTextureData[k].size_y, GL_RGB, GL_UNSIGNED_BYTE, myTextureData[k].data);
}
}
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
is_depth = 1;
}
void display(void)
{
if (is_depth)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
else
glClear(GL_COLOR_BUFFER_BIT);
textureLoader();
glBegin(GL_QUADS);
glTexCoord2f(0.0,0.0);
glVertex3f(-75.0, 0.0, -400.0);
glTexCoord2f(0.0,1.0);
glVertex3f(-75.0, 0.0, 100.0);
glTexCoord2f(1.0,0.0);
glVertex3f(75.0, 0.0, 100.0);
glTexCoord2f(1.0,1.0);
glVertex3f(75.0, 0.0, -400.0);
drawcube(-70,15,72,8,15,28,4);
drawcube(-70,10,10,8,10,28,0);
drawcube(-70,15,-45,8,15,18,0);
drawcube(-70,15,-85,8,15,18,0);
drawcube(-70,35,-125,8,35,12,0);
drawcube(-70,9,-170,8,9,28,0);
drawcube(-70,15,-220,8,15,18,0);
drawcube(-70,15,-265,8,15,28,0);
drawcube(-70,15,-330,8,15,28,0);
drawcube(67,15,72,8,15,28,0);
drawcube(67,10,10,8,10,28,0);
drawcube(67,15,-45,8,15,18,0);
drawcube(67,15,-85,8,15,18,0);
drawcube(67,35,-125,8,35,12,0);
drawcube(67,9,-170,8,9,28,0);
drawcube(67,15,-220,8,15,18,0);
drawcube(67,15,-265,8,15,28,0);
drawcube(67,15,-330,8,15,28,0);
drawcube(-33,18,-364,25,18,10,0);
drawcube(25,28,-364,30,28,10,0);
drawcube(25,28,90,30,28,10,0);
drawcube(-33,18,90,25,18,10,0);
drawcube(0,60,-125,18,60,22,0);
drawcube(0,25,-225,8,25,28,0);
drawcube(0,25,0,8,25,28,0);
glEnd();
glutSwapBuffers();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 'a':
glTranslatef(5.0, 0.0, 0.0);
break;
case 'd':
glTranslatef(-5.0, 0.0, 0.0);
break;
case 'w':
glTranslatef(0.0, 0.0, 5.0);
break;
case 's':
glTranslatef(0.0, 0.0, -5.0);
break;
}
display();
}
void resize(int width, int height)
{
if (height == 0) height = 1;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, width / height, 1.0, 400.0);
glTranslatef(0.0, -5.0, -150.0);
glMatrixMode(GL_MODELVIEW);
}
void drawcube(float xc, float yc, float zc, float x_offset, float y_offset, float z_offset, int color)
{
switch(color)
{
case 1:
glColor3f(1.0,0.0,0.0);
break;
case 2:
glColor3f(0.0,1.0,0.0);
break;
case 3:
glColor3f(0.0,0.0,1.0);
break;
}
glBegin(GL_QUADS);
glVertex3f(xc - x_offset,yc - y_offset,zc - z_offset);
glVertex3f(xc + x_offset,yc - y_offset,zc - z_offset);
glVertex3f(xc + x_offset,yc + y_offset,zc - z_offset);
glVertex3f(xc - x_offset,yc + y_offset,zc - z_offset);
glVertex3f(xc + x_offset,yc + y_offset,zc - z_offset);
glVertex3f(xc + x_offset,yc + y_offset,zc + z_offset);
glVertex3f(xc + x_offset,yc - y_offset,zc + z_offset);
glVertex3f(xc + x_offset,yc - y_offset,zc - z_offset);
glVertex3f(xc - x_offset,yc - y_offset,zc + z_offset);
glVertex3f(xc - x_offset,yc - y_offset,zc - z_offset);
glVertex3f(xc - x_offset,yc + y_offset,zc - z_offset);
glVertex3f(xc - x_offset,yc + y_offset,zc + z_offset);
glVertex3f(xc + x_offset,yc + y_offset,zc - z_offset);
glVertex3f(xc - x_offset,yc + y_offset,zc - z_offset);
glVertex3f(xc - x_offset,yc + y_offset,zc + z_offset);
glVertex3f(xc + x_offset,yc + y_offset,zc + z_offset);
glVertex3f(xc - x_offset,yc - y_offset,zc + z_offset);
glVertex3f(xc + x_offset,yc - y_offset,zc + z_offset);
glVertex3f(xc + x_offset,yc - y_offset,zc - z_offset);
glVertex3f(xc - x_offset,yc - y_offset,zc - z_offset);
glVertex3f(xc + x_offset,yc + y_offset,zc + z_offset);
glVertex3f(xc - x_offset,yc + y_offset,zc + z_offset);
glVertex3f(xc - x_offset,yc - y_offset,zc + z_offset);
glVertex3f(xc + x_offset,yc - y_offset,zc + z_offset);
glEnd();
}
Run Code Online (Sandbox Code Playgroud)
dat*_*olf 18
我只会评论你的代码
#include <windows.h>
#include <gl\gl.h>
#include <gl\glut.h>
#include <stdlib.h>
#include <iostream>
void init(void);
void display(void);
void keyboard(unsigned char, int, int);
void resize(int, int);
void drawcube(float, float, float, float, float, float, int);
int is_depth;
#define ROAD 0
struct Image
{
unsigned long size_x;
unsigned long size_y;
char *data;
};
typedef struct Image Image;
const int textureCount = 1;
Run Code Online (Sandbox Code Playgroud)
你正在使用const int数组大小.这告诉我,你使用的是C++,为什么不使用STL std :: vector或std :: list呢?
Image myTextureData[textureCount];
GLuint theTexture[textureCount];
char* textureFilenames[textureCount] = {"road.bmp"};
int main (int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(600, 600);
glutInitWindowPosition(40, 40);
glutCreateWindow("3D World");
init();
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glEnable(GL_TEXTURE_2D);
Run Code Online (Sandbox Code Playgroud)
OpenGL状态是按需设置的.那个glEnable在这里毫无意义.
glutReshapeFunc(resize);
glutMainLoop();
return 0;
}
int imageLoader(const char *filename, Image *image)
{
FILE *file;
unsigned long size;
unsigned long i;
unsigned short int planes;
unsigned short int bpp;
char temp;
char finalName[80];
glTexCoord2f(1.0, 0.0);
Run Code Online (Sandbox Code Playgroud)
WTF?你glTexCoord在纹理加载器中调用什么?这是一个绘图命令.
strcpy(finalName, "" );
strcat(finalName, filename);
Run Code Online (Sandbox Code Playgroud)
WTF?你要复制filename什么?另外80个字符可能还不够.
if ((file = fopen(finalName, "rb"))==NULL)
{
Run Code Online (Sandbox Code Playgroud)
未正确打开的文件可能比错误的路径有更多的原因.
printf("File Not Found : %s\n",finalName);
return 0;
}
fseek(file, 18, SEEK_CUR);
Run Code Online (Sandbox Code Playgroud)
假设它是您所期望的,您不应该盲目地尝试读取文件.二进制文件,比如你在这里尝试阅读的DIB有一个原因的标题,所以你一定要阅读和解析这个标题!
glTexCoord2f(1.0, 0.0);
Run Code Online (Sandbox Code Playgroud)
再次?!
if ((i = fread(&image->size_x, 4, 1, file)) != 1)
{
printf("Error reading width from %s.\n", finalName);
return 0;
}
if ((i = fread(&image->size_y, 4, 1, file)) != 1)
{
printf("Error reading height from %s.\n", finalName);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
假设您的系统的字节顺序和对齐规则与文件格式匹配,您是否正在读取文件中的值?你必须有钢球!
size = image->size_x * image->size_y * 3;
Run Code Online (Sandbox Code Playgroud)
整数溢出,是的!你刚刚使你的程序可以利用.
if ((fread(&planes, 2, 1, file)) != 1)
{
printf("Error reading planes from %s.\n", finalName);
return 0;
}
if (planes != 1)
{
printf("Planes from %s is not 1: %u\n", finalName, planes);
return 0;
}
if ((i = fread(&bpp, 2, 1, file)) != 1)
{
printf("Error reading bpp from %s.\n", finalName);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
再次读取二进制值没有适当关心endianess和alignment ...
if (bpp != 24)
{
printf("Bpp from %s is not 24: %u\n", finalName, bpp);
return 0;
}
fseek(file, 24, SEEK_CUR);
Run Code Online (Sandbox Code Playgroud)
你为什么要在这里进行相对寻求?BITMAPFILEHEADER(你知道你之前忽略了那18个字节)告诉你pixeldata的确切位置.
image->data = (char *) malloc(size);
if (image->data == NULL)
{
printf("Error allocating memory for color-corrected image data");
return 0;
}
if ((i = fread(image->data, size, 1, file)) != 1)
{
printf("Error reading image data from %s.\n", finalName);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句:如果中止,你应该关闭文件.
for (i=0;i<size;i+=3)
{
temp = image->data[i];
image->data[i] = image->data[i+2];
image->data[i+2] = temp;
}
Run Code Online (Sandbox Code Playgroud)
这不是做颜色校正,它只是交换元素.较新的OpenGL直接支持DIB文件的BGR对齐.
return 1;
Run Code Online (Sandbox Code Playgroud)
还没关闭文件......
}
void textureLoader()
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
for(int k=0; k < textureCount; k++)
{
if(!imageLoader(textureFilenames[k], &myTextureData[k]))
exit(1);
Run Code Online (Sandbox Code Playgroud)
好吧,好吧,通过这些全局数组完成这项工作.但严重的是:textureLoader应该返回加载纹理的纹理ID.
glGenTextures(1, &theTexture[k]);
glBindTexture(GL_TEXTURE_2D, theTexture[k]);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, myTextureData[k].size_x, myTextureData[k].size_y, GL_RGB, GL_UNSIGNED_BYTE, myTextureData[k].data);
}
}
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
is_depth = 1;
}
Run Code Online (Sandbox Code Playgroud)
你在这里"初始化"属于显示功能.
void display(void)
{
if (is_depth)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
else
glClear(GL_COLOR_BUFFER_BIT);
Run Code Online (Sandbox Code Playgroud)
WTF是这个吗?你觉得这有什么影响?是的,只有部分清除帧缓冲的多通道技术,但你没有这样做.摆脱is_depth.
textureLoader();
Run Code Online (Sandbox Code Playgroud)
textureLoader属于init; 加载纹理和顶点缓冲区对象是OpenGL"初始化程序"无论如何都可以做的唯一有用的东西.有了更多的经验,你也可以从显示路由开始做这些事情,实现交错纹理加载等功能,这样你就可以在不加载延迟的情况下导航大型场景.
这里缺少一些重要的东西:你没有设置你的矩阵.无论是投影和模型视图变换矩阵应该在渲染功能进行设置.
所以你想绘制纹理四边形.那么你为什么不:
glEnable(GL_TEXTURE_2D);glBindTexture(GL_TEXTURE_2D, theTexture[0]); 或者你想在这里使用哪个ID?
glBegin(GL_QUADS);
glTexCoord2f(0.0,0.0);
glVertex3f(-75.0, 0.0, -400.0);
glTexCoord2f(0.0,1.0);
glVertex3f(-75.0, 0.0, 100.0);
glTexCoord2f(1.0,0.0);
glVertex3f(75.0, 0.0, 100.0);
glTexCoord2f(1.0,1.0);
glVertex3f(75.0, 0.0, -400.0);
Run Code Online (Sandbox Code Playgroud)到目前为止看起来很好,除了你不提供法线.你需要那些照明.
但是WTF是这样的:
drawcube(-70,15,72,8,15,28,4);
drawcube(-70,10,10,8,10,28,0);
drawcube(-70,15,-45,8,15,18,0);
drawcube(-70,15,-85,8,15,18,0);
drawcube(-70,35,-125,8,35,12,0);
drawcube(-70,9,-170,8,9,28,0);
drawcube(-70,15,-220,8,15,18,0);
drawcube(-70,15,-265,8,15,28,0);
drawcube(-70,15,-330,8,15,28,0);
drawcube(67,15,72,8,15,28,0);
drawcube(67,10,10,8,10,28,0);
drawcube(67,15,-45,8,15,18,0);
drawcube(67,15,-85,8,15,18,0);
drawcube(67,35,-125,8,35,12,0);
drawcube(67,9,-170,8,9,28,0);
drawcube(67,15,-220,8,15,18,0);
drawcube(67,15,-265,8,15,28,0);
drawcube(67,15,-330,8,15,28,0);
drawcube(-33,18,-364,25,18,10,0);
drawcube(25,28,-364,30,28,10,0);
drawcube(25,28,90,30,28,10,0);
drawcube(-33,18,90,25,18,10,0);
drawcube(0,60,-125,18,60,22,0);
drawcube(0,25,-225,8,25,28,0);
drawcube(0,25,0,8,25,28,0);
Run Code Online (Sandbox Code Playgroud)
你在glBegin(…)...glEnd()这里一块,所以唯一有效的OpenGL调用是glColor,glNormal,glTexCoord,glVertexAttrix,glVertex和glEnd.那么让我们看看当时有什么drawcube......
glEnd();
glutSwapBuffers();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 'a':
glTranslatef(5.0, 0.0, 0.0);
break;
case 'd':
glTranslatef(-5.0, 0.0, 0.0);
break;
case 'w':
glTranslatef(0.0, 0.0, 5.0);
break;
case 's':
glTranslatef(0.0, 0.0, -5.0);
break;
}
display();
}
Run Code Online (Sandbox Code Playgroud)
没有!没有!没有!这不是OpenGL的工作原理.glTranslate是一个矩阵操作函数,它只适用于渲染过程的上下文.你只是在这里弄乱OpenGL状态.
void resize(int width, int height)
{
if (height == 0) height = 1;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, width / height, 1.0, 400.0);
glTranslatef(0.0, -5.0, -150.0);
glMatrixMode(GL_MODELVIEW);
Run Code Online (Sandbox Code Playgroud)
这东西属于展示.我知道,很多(大多数)教程都是这样编写的,就像你一样,但请相信我:只要你想实现类似HUD或多通道渲染设置的东西,调整大小处理程序中的投影就会咬你.
}
void drawcube(float xc, float yc, float zc, float x_offset, float y_offset, float z_offset, int color)
{
Run Code Online (Sandbox Code Playgroud)
啊,drawcube功能
switch(color)
{
case 1:
glColor3f(1.0,0.0,0.0);
break;
case 2:
glColor3f(0.0,1.0,0.0);
break;
case 3:
glColor3f(0.0,0.0,1.0);
break;
}
glBegin(GL_QUADS);
Run Code Online (Sandbox Code Playgroud)
你是drawcube在一个glBegin(…)...glEnd()街区内打电话,但是然后尝试打开另一个街区.这是一个OpenGL错误.glBegin(…)...glEnd()不要窝.
glVertex3f(xc - x_offset,yc - y_offset,zc - z_offset);
glVertex3f(xc + x_offset,yc - y_offset,zc - z_offset);
glVertex3f(xc + x_offset,yc + y_offset,zc - z_offset);
glVertex3f(xc - x_offset,yc + y_offset,zc - z_offset);
glVertex3f(xc + x_offset,yc + y_offset,zc - z_offset);
glVertex3f(xc + x_offset,yc + y_offset,zc + z_offset);
glVertex3f(xc + x_offset,yc - y_offset,zc + z_offset);
glVertex3f(xc + x_offset,yc - y_offset,zc - z_offset);
glVertex3f(xc - x_offset,yc - y_offset,zc + z_offset);
glVertex3f(xc - x_offset,yc - y_offset,zc - z_offset);
glVertex3f(xc - x_offset,yc + y_offset,zc - z_offset);
glVertex3f(xc - x_offset,yc + y_offset,zc + z_offset);
glVertex3f(xc + x_offset,yc + y_offset,zc - z_offset);
glVertex3f(xc - x_offset,yc + y_offset,zc - z_offset);
glVertex3f(xc - x_offset,yc + y_offset,zc + z_offset);
glVertex3f(xc + x_offset,yc + y_offset,zc + z_offset);
glVertex3f(xc - x_offset,yc - y_offset,zc + z_offset);
glVertex3f(xc + x_offset,yc - y_offset,zc + z_offset);
glVertex3f(xc + x_offset,yc - y_offset,zc - z_offset);
glVertex3f(xc - x_offset,yc - y_offset,zc - z_offset);
glVertex3f(xc + x_offset,yc + y_offset,zc + z_offset);
glVertex3f(xc - x_offset,yc + y_offset,zc + z_offset);
glVertex3f(xc - x_offset,yc - y_offset,zc + z_offset);
glVertex3f(xc + x_offset,yc - y_offset,zc + z_offset);
Run Code Online (Sandbox Code Playgroud)
不是你的问题如何使用纹理?我没有看到glTexCoord那里的电话......
glEnd();
}
Run Code Online (Sandbox Code Playgroud)

| 归档时间: |
|
| 查看次数: |
690 次 |
| 最近记录: |