我在3d中实现迷宫。它工作正常,但现在我必须在其中放置纹理。我喜欢加载不同的纹理,取决于它的墙壁,食物或走廊。每次我需要纹理时,我都会找到调用LoadTexture的方法。
我使用Readjpeg和LoadTexture函数遇到了一个模板。但结果太慢了。程序逻辑很好,但运动很慢。假设因为我多次从文件中读取并且空闲时间没有像以前那样被调用。
v
oid Maze::draw3D(int w, int h){
if (rows == 0 || columns == 0)
throw std::out_of_range("Error: El numero columnas o filas no puede ser cero. Error división por cero");
if (rows > h || columns > w)
throw std::out_of_range("Error: La ventana tiene que tener un tamaño mayor a las fila por columnas");
int numberRow, numberColumn;
int widthRatio =int(w / columns);
int heightRatio = int(h / rows);
//int numberRow;
GLUquadric *sphere=gluNewQuadric();
for(numberRow=0;numberRow < rows; numberRow++)
for(numberColumn=0; numberColumn< columns;numberColumn++)
if(!isCenter(numberRow,numberColumn)){
if( map[numberRow][numberColumn]==WALL ) {
//Selecciona el color actual con el que dibujar. Parámetros R G y B, rango [0..1], así que estamos ante el color azul
//glColor3f(0.0, 0.0, 1.0);
/*glBegin() comienza una secuencia de vértices con los que se construirán primitivas. El tipo de primitivas viene dado por el parámetro de glBegin(), en este caso GL_QUADS.
* Al haber cuatro vértices dentro de la estructura, está definiendo un cuadrado. glEnd() simplemente cierra la estructura.
*
*/
//las x son iguales cambian las y
//ysim =(rows-numberRow);
//numberRow=numberRow;
//Pared suelo
glColor3f(1.0, 0.0, 0.0); // Red = rgb <1, 0, 0>
glBegin(GL_QUADS);
//Vertice arriba izquierda
glVertex3i((numberColumn*widthRatio)-(WIDTH/2),0,(numberRow*heightRatio)-(HEIGHT/2));
//Vertice abajo izquierda
glVertex3i((numberColumn*widthRatio)-(WIDTH/2),0,(numberRow+1)*heightRatio-(HEIGHT/2));
//Vertice abajo derecha
glVertex3i((numberColumn+1)*widthRatio-(WIDTH/2),0,(numberRow+1)*heightRatio-(HEIGHT/2));
//Vertice arriba derecha
glVertex3i((numberColumn+1)*widthRatio-(WIDTH/2),0,(numberRow)*heightRatio-(HEIGHT/2));
glEnd();
/*
//Pared techo
glColor3f(1.0, 0.0, 0.0); // Red = rgb <1, 0, 0>
glBegin(GL_QUADS);
//Vertice arriba izquierda
glVertex3i((numberColumn*widthRatio)-(WIDTH/2),DEPTH,(numberRow*heightRatio)-(HEIGHT/2));
//Vertice abajo izquierda
glVertex3i((numberColumn*widthRatio)-(WIDTH/2),DEPTH,(numberRow+1)*heightRatio-(HEIGHT/2));
//Vertice abajo derecha
glVertex3i((numberColumn+1)*widthRatio-(WIDTH/2),DEPTH,(numberRow+1)*heightRatio-(HEIGHT/2));
//Vertice arriba derecha
glVertex3i((numberColumn+1)*widthRatio-(WIDTH/2),DEPTH,(numberRow)*heightRatio-(HEIGHT/2));
//glVertex3i(50,-50,50);
glEnd();
*/
//Pared exterior (las x mas izquierda) (1)
glColor3f(0.0, 1.0, 0.0); //Green = rgb <0, 1, 0>
glBegin(GL_QUADS);
//Vertice arriba izquierda
glVertex3i((numberColumn*widthRatio)-(WIDTH/2),0,(numberRow*heightRatio)-(HEIGHT/2));
//Vertice abajo izquierda
glVertex3i((numberColumn*widthRatio)-(WIDTH/2),0,(numberRow+1)*heightRatio-(HEIGHT/2));
//Vertice abajo derecha
glVertex3i( ((numberColumn)*widthRatio)-(WIDTH/2),DEPTH,(numberRow+1)*heightRatio-(HEIGHT/2));
//Vertice arriba derecha
glVertex3i((numberColumn*widthRatio)-(WIDTH/2),DEPTH,(numberRow*heightRatio)-(HEIGHT/2));
glEnd();
//Pared exterior ( las y mas abajo) (2)
glColor3f(0.0, 0.0, 1.0);//Blue = rgb <0, 0, 1>
glBegin(GL_QUADS);
//Vertice arriba izquierda
glVertex3i((numberColumn*widthRatio)-(WIDTH/2),DEPTH,(numberRow+1)*heightRatio-(HEIGHT/2));
//Vertice abajo izquierda
glVertex3i(((numberColumn)*widthRatio)-(WIDTH/2),0, (numberRow+1)*heightRatio-(HEIGHT/2));
//Vertice abajo derecha
glVertex3i(((numberColumn+1)*widthRatio)-(WIDTH/2),0, (numberRow+1)*heightRatio-(HEIGHT/2));
//Vertice arriba derecha
glVertex3i(((numberColumn+1)*widthRatio)-(WIDTH/2),DEPTH, (numberRow+1)*heightRatio-(HEIGHT/2));
glEnd();
//Pared exterior ( las x mas abajo) (3)106;90;205
glColor3f(1.0, 0.5, 0.0); //Orange = color red 1 green 0.5 blue 0.0
glBegin(GL_QUADS);
//Vertice arriba izquierda
glVertex3i(((numberColumn+1)*widthRatio)-(WIDTH/2),DEPTH, (numberRow+1)*heightRatio-(HEIGHT/2));
//Vertice abajo izquierda
glVertex3i(((numberColumn+1)*widthRatio)-(WIDTH/2),0, (numberRow+1)*heightRatio-(HEIGHT/2));
//Vertice abajo derecha
glVertex3i(((numberColumn+1)*widthRatio)-(WIDTH/2),0, (numberRow)*heightRatio-(HEIGHT/2));
//Vertice arriba derecha
glVertex3i(((numberColumn+1)*widthRatio)-(WIDTH/2),DEPTH, (numberRow)*heightRatio-(HEIGHT/2));
glEnd();
//Pared exterior ( las y mas arriba) (4)
glColor3f(0.752, 0.752, 0.752); //Grey = color red 0.752941 green 0.752941 blue 0.752941
glBegin(GL_QUADS);
//Vertice arriba izquierda
glVertex3i((numberColumn*widthRatio)-(WIDTH/2),0, (numberRow)*heightRatio-(HEIGHT/2));
//Vertice abajo izquierda
glVertex3i(((numberColumn)*widthRatio)-(WIDTH/2),DEPTH, (numberRow)*heightRatio-(HEIGHT/2));
//Vertice abajo derecha
glVertex3i(((numberColumn+1)*widthRatio)-(WIDTH/2),DEPTH, (numberRow)*heightRatio-(HEIGHT/2));
//Vertice arriba derecha
glVertex3i(((numberColumn+1)*widthRatio)-(WIDTH/2),0, (numberRow)*heightRatio-(HEIGHT/2));
glEnd();
//Textura pared techo
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,0);
LoadTexture("Groundplant64x64.jpg",64);
glBegin(GL_QUADS);
glTexCoord2f(-4.0,0.0); glVertex3i((numberColumn*widthRatio)-(WIDTH/2),DEPTH,(numberRow*heightRatio)-(HEIGHT/2));
glTexCoord2f(4.0,0.0); glVertex3i((numberColumn*widthRatio)-(WIDTH/2),DEPTH,(numberRow+1)*heightRatio-(HEIGHT/2));
glTexCoord2f(4.0,4.0); glVertex3i((numberColumn+1)*widthRatio-(WIDTH/2),DEPTH,(numberRow+1)*heightRatio-(HEIGHT/2));
glTexCoord2f(-4.0,4.0); glVertex3i((numberColumn+1)*widthRatio-(WIDTH/2),DEPTH,(numberRow)*heightRatio-(HEIGHT/2));
glEnd();
glDisable(GL_TEXTURE_2D);
}
else if(map[numberRow][numberColumn] == FOOD){
//Selecciona el color actual con el que dibujar. Parámetros R G y B, rango [0..1], así que estamos ante el color blanco
glColor3f(1.0,1.0,0.0); //Orange
/*glBegin() comienza una secuencia de vértices con los que se construirán primitivas. El tipo de primitivas viene dado por el parámetro de glBegin(), en este caso GL_QUADS.
* Al haber cuatro vértices dentro de la estructura, está definiendo un cuadrado. glEnd() simplemente cierra la estructura.
*
*/
//GLUquadric *sphere=gluNewQuadric();
gluQuadricDrawStyle( sphere, GLU_FILL);
gluQuadricNormals( sphere, GLU_SMOOTH);
gluQuadricOrientation( sphere, GLU_OUTSIDE);
gluQuadricTexture( sphere, GL_TRUE);
glPushMatrix();
glTranslated(((numberColumn+0.5)*widthRatio)-(WIDTH/2),DEPTH/3,(numberRow+0.5)*heightRatio-(HEIGHT/2) );
//glRotated(45,1,1,1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,0);
LoadTexture("Flames64x64.jpg",64);
gluSphere(sphere,5.0,50,50);//(numberColumn+1)*widthRatio)-(WIDTH/2),0, (ysim)*heightRatio-(HEIGHT/2)
glPopMatrix();
glDisable(GL_TEXTURE_2D);
}
else if(map[numberRow][numberColumn] == PASSAGE){
//Selecciona el color actual con el que dibujar. Parámetros R G y B, rango [0..1], así que estamos ante el color blanco
glColor3f(1.0,0.5,0.0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,0);
LoadTexture("FloorsMedieval64x64.jpg",64);
glBegin(GL_QUADS);
glTexCoord2f(-4.0,0.0); glVertex3i((numberColumn*widthRatio)-(WIDTH/2),2,(numberRow*heightRatio)-(HEIGHT/2));
glTexCoord2f(4.0,0.0); glVertex3i((numberColumn*widthRatio)-(WIDTH/2),2,(numberRow+1)*heightRatio-(HEIGHT/2));
glTexCoord2f(4.0,4.0); glVertex3i((numberColumn+1)*widthRatio-(WIDTH/2),2,(numberRow+1)*heightRatio-(HEIGHT/2));
glTexCoord2f(-4.0,4.0); glVertex3i((numberColumn+1)*widthRatio-(WIDTH/2),2,(numberRow)*heightRatio-(HEIGHT/2));
glEnd();
glDisable(GL_TEXTURE_2D);
}
}
}
我们的老师将以下代码传递给我们:
/*--------------------------------------------------------*/
/*--------------------------------------------------------*/
void Maze::ReadJPEG(char *filename,unsigned char **image,int *width, int *height)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE * infile;
unsigned char **buffer;
int i,j;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
if ((infile = fopen(filename, "rb")) == NULL) {
printf("Unable to open file %s\n",filename);
exit(1);
}
jpeg_stdio_src(&cinfo, infile);
jpeg_read_header(&cinfo, TRUE);
jpeg_calc_output_dimensions(&cinfo);
jpeg_start_decompress(&cinfo);
*width = cinfo.output_width;
*height = cinfo.output_height;
*image=(unsigned char*)malloc(cinfo.output_width*cinfo.output_height*cinfo.output_components);
buffer=(unsigned char **)malloc(1*sizeof(unsigned char **));
buffer[0]=(unsigned char *)malloc(cinfo.output_width*cinfo.output_components);
i=0;
while (cinfo.output_scanline < cinfo.output_height) {
jpeg_read_scanlines(&cinfo, buffer, 1);
for(j=0;j<cinfo.output_width*cinfo.output_components;j++)
{
(*image)[i]=buffer[0][j];
i++;
}
}
free(buffer);
jpeg_finish_decompress(&cinfo);
}
/*--------------------------------------------------------*/
/*--------------------------------------------------------*/
void Maze::LoadTexture(char *filename,int dim)
{
unsigned char *buffer;
unsigned char *buffer2;
int width,height;
long i,j;
long k,h;
ReadJPEG(filename,&buffer,&width,&height);
buffer2=(unsigned char*)malloc(dim*dim*3);
//-- The texture pattern is subsampled so that its dimensions become dim x dim --
for(i=0;i<dim;i++)
for(j=0;j<dim;j++)
{
k=i*height/dim;
h=j*width/dim;
buffer2[3*(i*dim+j)]=buffer[3*(k*width +h)];
buffer2[3*(i*dim+j)+1]=buffer[3*(k*width +h)+1];
buffer2[3*(i*dim+j)+2]=buffer[3*(k*width +h)+2];
}
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,dim,dim,0,GL_RGB,GL_UNSIGNED_BYTE,buffer2);
free(buffer);
free(buffer2);
}
如果另外一种方式,我可以在内存中有不同的纹理(在jpeg中是64x64像素的图像)或任何提高速度的想法。动画非常慢。
由于
根据@datenwolf的建议更新
我的readJPEG.cpp
#include "ReadJPEG.h"
/*--------------------------------------------------------*/
/*--------------------------------------------------------*/
int ReadJPEG(
std::string const filename,
std::vector<uint8_t> *image,
int *width, int *height )
{
if( !image ) {
return -1;
}
FILE * const infile = fopen(filename, "rb");
if( !infile ) {
std::cerr
<< "error opening file "
<< filename
<< " : "
<< strerror(errno)
<< std::endl;
return -2;
}
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, infile);
jpeg_read_header(&cinfo, TRUE);
jpeg_calc_output_dimensions(&cinfo);
jpeg_start_decompress(&cinfo);
if( width ) { *width = cinfo.output_width; }
if( height ) { *height = cinfo.output_height; }
size_t const stride = cinfo.output_width * cinfo.output_components;
// image->resize(cinfo.output.height * stride);
image->resize(cinfo.output_height * stride);
jpeg_read_scanlines(&cinfo, &(*image)[0], cinfo.output_height);
jpeg_finish_decompress(&cinfo);
//jpeg_read_scanlines(&cinfo, &(*image)[0], cinfo.output_height);
return 0;
}
MyLoadTexture.cpp
#include "MyLoadTexture.h"
//using namespace std;
GLuint MyLoadTexture(std::string const filename)
{
GLuint texname = 0;
/* this is actually tied to the OpenGL context, so this should
* actually be a map GLcontext -> std::string -> texturename */
static std::map<std::string, GLuint> loaded_textures;
if( loaded_textures.find(filename) != loaded_textures.end() ) {
texname = loaded_textures[filename];
glBindTexture(GL_TEXTURE_2D, texname);
return texname;
}
int width,height;
std::vector<uint8_t> image;
if( ReadJPEG(filename, &image, &width, &height) ) {
std::cerr
<< "error reading JPEG"
<< std::endl;
return 0;
}
glGenTextures(1, &texname);
if( !texname ) {
std::cerr
<< "error generating OpenGL texture name"
<< std::endl;
return 0;
}
glBindTexture(GL_TEXTURE_2D, texname);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
/* glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGB,
width, height, 0,
GL_RGB,
GL_UNSIGNED_BYTE, buffer );
*/
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGB,
width, height, 0,
GL_RGB,
GL_UNSIGNED_BYTE, &texname);
loaded_textures[filename] = texname;
return texname;
}
注意我改变了@datewnwolf
glTexImage2D(
GL_TEXTURE_2D,0,GL_RGB,
宽度,高度,0,
GL_RGB,
GL_UNSIGNED_BYTE,缓冲区);
by(因为缓冲区不再存在):
glTexImage2D(
GL_TEXTURE_2D,0,GL_RGB,
宽度,高度,0,
GL_RGB,
GL_UNSIGNED_BYTE,&amp; texname);
也是一个词汇错误: image-&gt; resize(cinfo.output.height * stride); 至 image-&gt; resize(cinfo.output_height * stride);
我面对这个错误:
描述资源路径位置类型 'fopen'未在此范围内声明ReadJPEG.cpp / RandomMaze3d第22行C / C ++问题
描述资源路径位置类型 不能将'unsigned char *'转换为'JSAMPARRAY {aka unsigned char **}'以将参数'2'转换为'JDIMENSION jpeg_read_scanlines(j_decompress_ptr,JSAMPARRAY,JDIMENSION)'ReadJPEG.cpp / RandomMaze3d line 50 C / C ++问题
语义错误(可能与上述错误有关): 描述资源路径位置类型 参数无效' 候选人是: _IO_FILE * fopen(const char *,const char *) 'ReadJPEG.cpp / RandomMaze3d第22行语义错误
描述资源路径位置类型 参数无效' 候选人是: unsigned int jpeg_read_scanlines(jpeg_decompress_struct *,unsigned char * *,unsigned int) 'ReadJPEG.cpp / RandomMaze3d第50行语义错误
另外我可以保存使用int而不是unint_8和String或char *而不是std:string ??不是吗?
更新执行错误:
@datenwolf非常感谢。我今天早上一直在工作,我可以毫无错误地执行。但是现在我面临一个奇怪的执行错误,我在一个地方改变了以MyLoadTexture和新的ReadJPEG开始LoadTextures:
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,0);
MyLoadTexture("Groundplant64x64.jpg");
glBegin(GL_QUADS); ....
给我一个:当我启动Groundplant64x64,jpg时,应用程序传输的扫描线太少....文件没有损坏,因为我可以打开它...我正在谷歌但没有得到答案。
Groundplants是96x64像素(因为我保存错误)但我也尝试使用fire.jpg 64x64。 jpg以85%的质量保存。我也试图保存100%和相同的错误。
更新执行错误2:
@datenwolf看到我的更新错误。现在,如果我用一个文件运行我以前的函数loadTextures,那么它与64作为参数在开始时效果很好。但是如果我调用MyLoadTexture只是窗口消失而没有任何错误消息。所以具有所有纹理的地图
static std :: map loaded_textures;
不应该在MyLoadTexture之外并定义为全局变量。我想当函数结束时,loaded_textures消失(它从内存中释放)并假设它变成空白。
问题显然在MyLoadTexture中,好像我用LoadTextures替换(“fire.jpg”,64);一切顺利。如果我再次使用MyLoadTexture(“fire.jpg”);窗口消失(试图绘制迷宫)。
如前所述,MyLoadTexture和ReadJPEG是公共全局函数,因为我需要从Maze之外的其他类中调用它们,例如Ghost,Pacman类。
请提出任何其他建议。
答案 0 :(得分:0)
LoadTexture
正在经历从磁盘(缓存)解析文件,然后加载数据的整个麻烦。而且很有趣的是,你基本上利用了一个可以追溯到OpenGL-1.0的时代错误(它已经在1992年的IIRC上发布了; geesh我甚至没有那个规范)你可以将图像数据加载到纹理0
。这样做并不是很聪明。
相反,只需将所有纹理加载一次,每个纹理都加载到自己的纹理对象中。您会看到所有glBindTexture
次来电。第二个参数是&#34; name&#34;要使用哪种纹理。因此,在加载图像时,您首先要创建&#34;名称&#34;,对于要与glGenTextures
一起使用的每个图像一个,然后绑定每个名称,加载图像然后转到下一个图像。
在绘制所有你需要做的事情时,只需glBindTexture
你想要使用的纹理,不需要在那里加载任何东西,因为它已经加载了。
因此,在您的代码中,您会出现大量此类模式:
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,0);
LoadTexture( a_filename );
/* --- draw something --- */
glDisable(GL_TEXTURE_2D);
您可以绑定OpenGL纹理0(允许与OpenGL-1.0保持兼容)并使用LoadTexture将图像加载到其中。顺便说一下,LoadTexture的参数dim
是完全没必要的,事实上危险。 JPEG文件已经包含了您需要的所有信息。
相反,你应该用这样的东西替换它:
首先更改LoadTexture
一点。将它从Maze类中删除,它不属于那里。使其成为一个全球功能。让它生成一个OpenGL纹理名称,将纹理加载到其中并返回纹理名称。所有的子采样都是疯狂的; OpenGL可以使用任意纹理尺寸,只需使用它。最后但并非最不重要的是使用地图将文件名映射到纹理名称,以便已经加载的图像文件不会被冗余地重新加载。
/*--------------------------------------------------------*/
/*--------------------------------------------------------*/
#include <map>
#include <string>
GLuint LoadTexture(std::string const filename)
{
GLuint texname = 0;
/* this is actually tied to the OpenGL context, so this should
* actually be a map GLcontext -> std::string -> texturename */
static std::map<std::string, GLuint> loaded_textures;
if( loaded_textures.find(filename) != loaded_textures.end() ) {
texname = loaded_textures[filename];
glBindTexture(GL_TEXTURE_2D, texname);
return texname;
}
int width,height;
std::vector<uint8_t> image;
if( ReadJPEG(filename, &image, &width, &height) ) {
std::cerr
<< "error reading JPEG"
<< std::endl;
return 0;
}
glGenTextures(1, &texname);
if( !texname ) {
std::cerr
<< "error generating OpenGL texture name"
<< std::endl;
return 0;
}
glBindTexture(GL_TEXTURE_2D, texname);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGB,
width, height, 0,
GL_RGB,
GL_UNSIGNED_BYTE, &image[0] );
loaded_textures[filename] = texname;
return texname;
}
应用这些更改LoadTexture
只会加载一次图像,而在以后的调用中,使用文件名映射到已加载的OpenGL纹理,而不是生成新的纹理。您可以将其用作替代品,以及它的编写方式,只需工作即可。与其余代码一起使用。
#include <string>
#include <vector>
#include <stdint.h>
#include <string.h>
#include <errno.h>
/*--------------------------------------------------------*/
/*--------------------------------------------------------*/
int ReadJPEG(
std::string const filename,
std::vector<uint8_t> *image,
int *width, int *height )
{
if( !image ) {
return -1;
}
FILE * const infile = fopen(filename.c_str(), "rb");
if( !infile ) {
std::cerr
<< "error opening file "
<< filename
<< " : "
<< strerror(errno)
<< std::endl;
return -2;
}
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, infile);
jpeg_read_header(&cinfo, TRUE);
jpeg_calc_output_dimensions(&cinfo);
jpeg_start_decompress(&cinfo);
if( width ) { *width = cinfo.output_width; }
if( height ) { *height = cinfo.output_height; }
size_t const stride = cinfo.output_width * cinfo.output_components;
image->resize(cinfo.output.height * stride);
for(size_t i = 0; i < cinfo.output_height;) {
uint8_t * const row = &(*image)[stride * i];
i += jpeg_read_scanlines(&cinfo, (unsigned char**)&row, 1);
}
jpeg_finish_decompress(&cinfo);
fclose(infile);
return 0;
}
请注意,这个新版本使用RAII和合适的C ++习语;我强烈建议不要使用引用,因为引用是伪装的指针,可以绊倒你。真实,明确的指针可以防止你陷入这样的陷阱。
描述资源路径位置类型'fopen'未在此范围内声明ReadJPEG.cpp / RandomMaze3d第22行C / C ++问题
将#include <stdio.h>
添加到ReadJPEG.cpp的顶部 - 我也使用iostream
发出错误消息,因此还要在其中添加#include <iostream>
,并在LoadTexture.cpp中进行测量。< / p>
描述资源路径位置类型无法将'unsigned char *'转换为'JSAMPARRAY {aka unsigned char **}'以将参数'2'转换为'JDIMENSION jpeg_read_scanlines(j_decompress_ptr,JSAMPARRAY,JDIMENSION)'ReadJPEG.cpp / RandomMaze3d line 50 C / C ++问题 (......) 说明资源路径位置类型无效参数&#39;候选人是:unsigned int jpeg_read_scanlines(jpeg_decompress_struct *,unsigned char * *,unsigned int)&#39; ReadJPEG.cpp / RandomMaze3d第50行语义错误
查看我编辑的ReadJPEG版本(geesh,使用双指针间接设计libjpeg API)。无论如何,每条扫描线上的循环和辅助指针变量都无法解决。
语义错误(可能与上述错误有关):描述资源路径位置类型无效的参数&#39;候选人是:_IO_FILE * fopen(const char *,const char *)&#39; ReadJPEG.cpp / RandomMaze3d第22行语义错误
另见我编辑的ReadJPEG版本
我也可以使用int而不是unint_8
否!!! 强>
对于一个sizeof(int) != sizeof(uint8_t)
。你可以用uint8_t
代替unsigned char
,但是char
的大小并不是一成不变的(它通常是8位,但并非总是如此)。 libjpeg API使用unsigned char
作为数据类型而不是像uint8_t
这样的真正固定大小的数据类型,总是在所有情况下都是8位大小。
和String或char *而不是std:string ??不是吗?
我不知道您指的是哪种String
类型。但从不使用C风格char*
&#34;字符串&#34;在C ++代码中,除了与纯C API接口的时候。哎呀,我基本上更喜欢C over C ++,甚至在那里我尽可能远离char*
并使用像uStr或类似的字符串抽象。裸char*
字符串是完全危险的。
C ++有一个标准(作为语言标准库的一部分)字符串类型。它被称为std::string
,如果您正在编写C ++代码,则使用它。这不是辩论。
同时保持C ++标准库类型可以省去显式分配和删除内存的所有麻烦。所有这些血淋淋的细节都很好地隐藏在STL的分配器中,如果你虔诚地坚持使用RAII(=从未明确使用new
或delete
operatos),你将永远不会遇到内存泄漏;当然,你不能总是坚持RAII。