The below code works fine in Ubuntu. I am loading a texture for openGL using glad and glfw.
下面的代码在Ubuntu中运行良好。我正在使用GREAD和GLFW为OpenGL加载纹理。
#include <vector>
#include <iostream>
#include <fstream>
using namespace std;
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
const bool loadResavedImages = true;
GLFWwindow* window;
void loadTexture( char const *filename, unsigned int &texture )
{
cout << filename << endl;
//static int texturesLoaded = 0;
glGenTextures( 1, &texture );
glBindTexture( GL_TEXTURE_2D, texture );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
int width, height, nrChannels;
stbi_set_flip_vertically_on_load( true );
unsigned char * data = NULL;
char newFileName[ 50 ];
snprintf( newFileName, sizeof(char) * ( strlen( filename ) - 3 ), "%s", filename );
ifstream readFile( newFileName );
if( loadResavedImages && readFile )
{
if( readFile.is_open() )
{
readFile >> width >> height;
data = new unsigned char[ width * height * 4 ];
readFile.read( (char *)data, width * height * 4 );
}
else
{
cout << "shouldnt happendfklgdskf" << endl;
}
readFile.close();
}
else
{
readFile.close();
data = stbi_load( filename, &width, &height, &nrChannels, 0 );
//saved images
//save to a file
ofstream saveFile( newFileName );
if( saveFile.is_open() )
{
saveFile << width << " " << height;
saveFile.write( (char *)&data[ 0 ], width * height * 4 );
}
else
cout << "WHY!?!?!SDSGGFGAGSSG" << endl;
saveFile.close();
}
for( int i = 0; i < width * height * 4; i++ )
{
cout << int( data[ i ] ) << " ";
}
if ( data )
{
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
glGenerateMipmap( GL_TEXTURE_2D );
}
else
{
cout << "failed to load texture " << filename <<endl;
exit( 0 );
}
if( loadResavedImages && readFile )
delete [] data;
else
{
stbi_image_free( data );
}
}
// main
int main()
{
glfwInit();
window = glfwCreateWindow( 500, 500, "Window", NULL, NULL );
glfwMakeContextCurrent( window );
if ( !gladLoadGLLoader( (GLADloadproc)glfwGetProcAddress ) )
{
cout << "Failed to initialize GLAD" << endl;
return 0;
}
//load texture
unsigned int texture;
loadTexture( "twirl.png", texture );
return 0;
}
When loading this 400x400 texture "twirl.png" on Ubuntu, which is mostly empty transparent space we get expectedly a bunch of 0s at the end.
当在Ubuntu上加载这个400x400的纹理“twirl.png”时,我们意外地在最后得到了一堆0。
If you save and reload this texture from the data file "twirl" it expectedly outputs the same thing on Ubuntu.
如果你从数据文件“twirl”中保存并重新加载这个纹理,它会意外地在Ubuntu上输出相同的东西。
If this is run on windows the outputs at the end are different. We have an output of
如果这是在Windows上运行,则末尾的输出是不同的。我们的产量是
205 205 205 205 205 205 205 205 205 205 205 205 205 205 205 205 205 205 205 205 205 205 205 205 205
... etc
instead of the expected empty space
..。等,而不是预期的空白处
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
etc..
等等.。
Why does this occur on windows and how to get it to load and save correctly?
为什么在Windows上会发生这种情况,以及如何正确加载和保存?
更多回答
Recommendation: Open up the file in a hex editor and see what really made it into the file. Given single-line snippets we can't help you much better than a car mechanic can if you just give them the car's steering wheel. Too much context missing.
建议:在十六进制编辑器中打开该文件,并查看文件中真正包含的内容。给出单行代码片段,如果你只给汽车的方向盘,我们不能比汽车修理工更好地帮助你。缺少太多上下文。
There is no "unsigned char * to char * conversion", it is just a pointer type-cast, the actual data is unaltered. Also, (char *)&data[ 0 ]
can be simplified to (char *)data
. In any case, please provide a minimal reproducible example showing how you are allocating and filling data
, width
and height
before saving/loading to/from the file. Writing 0
s to file and then reading them back as 205
s implies undefined behavior is at play somewhere in your code. Decimal 205
is hex 0xCD
, and a series of 0xCD
bytes is a common indicator of uninitialized memory being used, depending on your compiler config
没有“无符号char*到char*的转换”,它只是一个指针类型转换,实际数据是不变的。此外,(char*)&data[0]可以简化为(char*)data。在任何情况下,请提供一个最小的可重现示例,说明在保存到文件或从文件加载数据之前如何分配和填充数据、宽度和高度。将0写入文件,然后将其读回为205,这意味着未定义的行为在代码中的某个位置发挥作用。十进制205是十六进制0xCD,一系列0xCD字节是使用未初始化内存的常见指示符,具体取决于您的编译器配置
retired ninja answered this question. Things loaded correctly after doing binary mode
退休忍者回答了这个问题。执行二进制模式后正确加载的内容
Brian, give the minimal reproducible example (MRE) link a good read through. It describes a process for making best-of-breed code examples. It's also a distillation of several very effective debugging techniques. If you start the question-asking process by isolating the problem in a MRE, you'll often find you're done with the question long before you start typing anything into Stack Overflow. Asking good questions is hard work, and usually the reward is not having to ask the question.
Brian,给最小可重复示例(MRE)链接一个很好的通读。它描述了制作最佳代码示例的过程。它也是几种非常有效的调试技术的精华。如果您通过在MRE中隔离问题来开始提问过程,您通常会发现在开始在Stack Overflow中键入任何内容之前很久就已经完成了问题。问好问题是一项艰苦的工作,而通常的回报是不必问问题。
ifstream readFile( newFileName );
maybe the file was not even opened so it read nothing at all. The output you show would be consistent with that in msvc
meaning if your code failed to read I would expect the data to be exactly what you have received if you were running msvc in debug mode. The reason is what @RemyLebeau mentioned long ago. msvc fills heap memory with 0xcd in debug mode: stackoverflow.com/questions/127386/…
ifstream readFile(newFileName);也许文件甚至没有打开,所以它什么也没读。你显示的输出将与msvc中的输出一致,这意味着如果你的代码无法读取,我希望数据与你在调试模式下运行msvc时收到的数据完全一致。原因是@RemyLebeau很久以前提到的。msvc在调试模式下使用0xcd填充堆内存:stackoverflow.com/questions/127386/.
Due to automatic character translation when the file is opened in the default text mode, changing the two lines of code
由于在默认文本模式下打开文件时会自动进行字符转换,因此更改了两行代码
ifstream readFile( newFileName );
//...
//...
ofstream saveFile( newFileName );
//...
to
至
ifstream readFile( newFileName, ios_base::binary );
//...
//...
ofstream saveFile( newFileName, ios_base::binary );
//...
fixes the issue in Windows.
修复了Windows中的问题。
更多回答
我是一名优秀的程序员,十分优秀!