OpenGL的多张纹理

喜即时通讯想多张纹理添加到我的场景,我有一个纹理工作,但我不知道如何以包括其他的纹理,以及,任何帮助将是巨大的

#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(); }

--------------解决方案-------------

我只是评论你的代码

#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;

您使用的是const int数组sizeing。 这告诉我,你正在使用C ++,那么你为什么不使用STL的std ::向量或std ::名单呢?

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);

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);

WTF? 你叫什么glTexCoord在纹理加载器 ? 这是一个绘图命令。

strcpy(finalName, "" );
strcat(finalName, filename);

WTF? 你怎么复制filename ​​呢? 也80个字符将可能是不够的。

if ((file = fopen(finalName, "rb"))==NULL)
{

没有被正确打开一个文件可以不仅仅是一个错误的道路有更多的理由。

printf("File Not Found : %s\n",finalName);
return 0;
}

fseek(file, 18, SEEK_CUR);

你不应该盲目地尝试读取文件时,假设它是你的期望。 二进制文件,像DIB你想读到这里有是有原因的标题,所以你一定要读和解析这个头呢!

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;
}

再次读取二进制值W / O妥善照顾字节序和调整...

if (bpp != 24)
{
printf("Bpp from %s is not 24: %u\n", finalName, bpp);
return 0;
}

fseek(file, 24, SEEK_CUR);

你为什么要进行相对寻求在这里? 该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;
}

BTW:你应该放弃,如果关闭该文件。

for (i=0;i<size;i+=3)
{
temp = image->data[i];
image->data[i] = image->data[i+2];
image->data[i+2] = temp;
}

这是不是做色彩校正,它只是交换的元素。 较新的OpenGL的直接支持的DIB文件的BGR对齐。

return 1;

还没关闭文件...

}

void textureLoader()
{

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

for(int k=0; k < textureCount; k++)
{
if(!imageLoader(textureFilenames[k], &myTextureData[k]))
exit(1);

好吧,好吧,这样做通过这些全局数组做这项工作。 但严重的是: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;
}

什么你“初始化”这里属于进入显示功能。

void display(void)
{

if (is_depth)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
else
glClear(GL_COLOR_BUFFER_BIT);

跆拳道是这样的? 你认为什么样的影响,这是否有? 是有清除帧缓存只有部分多通道技术,但你没有做这样的。 摆脱is_depth

textureLoader();

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);

看起来不错,到目前为止,除了你不提供法线。 你需要的照明。

但跆拳道是这样的:

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);

你在一个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();
}

没有! 没有! NO!这不是 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);

这东西是属于到显示屏。 我知道,许多(大多数)的教程编写这种方式,喜欢你,但请相信我:你想实现的东西像HUD或者多路渲染设置在调整大小处理投影会咬你尽快。

}

void drawcube(float xc, float yc, float zc, float x_offset, float y_offset, float z_offset, int color)
{

啊,在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);

你调用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);

是不是你的问题如何使用纹理? 我没有看到来电glTexCoord那里...

glEnd();
}

OpenGL的多张纹理

您需要启用要呈现的质感。

看看这个例子是如何做的。 这个例子可能有点复杂,但接缝处做正是你正在尝试做的。

编辑

顺便说一句不创造纹理要渲染他们每一次。 你只需要一次创建它们,后来就使用它们(启用和渲染之前绑定到纹理)。

分类:C# 时间:2015-03-15 人气:0
本文关键词: C#中,OpenGL的,纹理
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.834 (s). 10 q(s)