初始化多个纹理的问题 OpenGL、SDL、C++
Issues with initializing multiple textures OpenGL, SDL, C++
我最近一直在使用 C++、SDL 和 OpenGL,但我 运行 遇到了一个问题,我正在尝试构建一个自动纹理加载系统,如下所示,但是所有我的纹理显示为空白的白色图像,我测试了 GLuint,它们似乎生成正确,并且我检查以确保正确分配了地图中键的名称。
这是我程序的图形部分:
SDL_GLContext Graphics_Handler::context;
SDL_Window * Graphics_Handler::window;
std::vector<struct Graphics_Handler::Surface_Container> surface_list;
unsigned int Graphics_Handler::texture_index = 0;
std::map<std::string, GLuint> Graphics_Handler::textures;
/**
* Loads an image
*/
struct Graphics_Handler::Surface_Container {
SDL_Surface * surface;
std::string name;
};
void Graphics_Handler::Load_Textures() {
GLuint *textures = new GLuint[surface_list.size()];
glGenTextures(surface_list.size(), textures);
for (unsigned int i = 0; i < surface_list.size(); i++) {
glBindTexture(GL_TEXTURE_2D, textures[i]);
glTexImage2D(GL_TEXTURE_2D, 0, surface_list[i].surface->format-
>BytesPerPixel, surface_list[i].surface->w, surface_list[i].surface->h, 0,
GL_RGBA, GL_UNSIGNED_BYTE, surface_list[i].surface->pixels);
Graphics_Handler::textures[surface_list[i].name] = textures[i];
}
glBindTexture(GL_TEXTURE_2D, 0);
}
void Graphics_Handler::Load_Surface(const char * file, std::string name) {
Graphics_Handler::Surface_Container surf;
surf.surface = IMG_Load(file);
surf.name = name;
if (surf.surface == 0) Game::GameError((std::string)"Error Loading image
file: " + (std::string)SDL_GetError()); // display the error
surface_list.push_back(surf);
}
/**
* draw a GLuint texture
*/
void Graphics_Handler::Draw_Texture(GLuint texture, float x, float y, float
width, float height){
glColor3f(1,1,1); // Sets the vertex color
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_QUADS); // Begin drawing a quadrilateral
glTexCoord2f(0.0f,0.0f); // Specifies where the vertex is on the image
rectangle(0 = left, 0 = top);
glVertex3f(x, y,0.0f); // Specifies where in space the vertex is
glTexCoord2f(1.0f,0.0f);
glVertex3f(width + x,0.0f + y,0.0f);
glTexCoord2f(1.0f,1.0f);
glVertex3f(width + x, height + y,0.0f);
glTexCoord2f(0.0f,1.0f);
glVertex3f(x,height + y,0.0f);
glEnd();
}
/*
* gets a texture from the texture map
*/
GLuint Graphics_Handler::Get_Texture(std::string name){
return Graphics_Handler::textures[name];
}
/**
* pretty self exclamatory, determines whether a string has a suffix
*/
bool has_suffix(const std::string &str, const std::string &suffix) {
return str.size() >= suffix.size() && str.compare(str.size() -
suffix.size(), suffix.size(), suffix) == 0;
}
/**
* gets all of the textures from the specified location and adds them to the
texture map (Load_Image)
*/
void Graphics_Handler::Load_Texture_Files(std::string location) {
std::string loc = location;
DIR *dir; //um... idk
struct dirent *ent; //pointer to directory
if ((dir = opendir ("textures")) != NULL) {
//loop through the file pointers (ent) and stop once they're null
while ((ent = readdir (dir)) != NULL) {
if(has_suffix(ent->d_name, ".png")){ //make sure it's an image
location = loc;
std::string full_location = location.append(ent->d_name);
//add the texture directory to the string to the png file and convert it to
a const char*
std::string name = ((std::string)ent-
>d_name).erase(((std::string)ent->d_name).length()-4); //remove the .png
extension from the file name to get the common name
Graphics_Handler::Load_Surface(full_location.c_str(), name);
}
}
closedir (dir); //no memory leaks ;)
Graphics_Handler::Load_Textures();
} else {
//could not open directory
Game::GameError("Couldn't load textures!?");
}
}
/**
* Draws everything to the screen
*/
void Graphics_Handler::Draw(int x, int y){
glClear(GL_COLOR_BUFFER_BIT); // clear the screen
glClearColor(0,0,0,1); // set the clear color
Draw_Texture(Graphics_Handler::Get_Texture("cat"), 50, 50, 100, 100);
//loop through all of the entities and draw them
SDL_GL_SwapWindow(Graphics_Handler::window); // Display the screen
}
我有两个纹理 cat.png 和 dirt.png
textures are coming up as blank white images
听起来像 incomplete textures:
What's wrong with this code?
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
The texture won't work because it is incomplete. The default
GL_TEXTURE_MIN_FILTER
state is GL_NEAREST_MIPMAP_LINEAR
. And because
OpenGL defines the default GL_TEXTURE_MAX_LEVEL
to be 1000, OpenGL
will expect there to be mipmap levels defined. Since you have only
defined a single mipmap level, OpenGL will consider the texture
incomplete until the GL_TEXTURE_MAX_LEVEL
is properly set, or the
GL_TEXTURE_MIN_FILTER
parameter is set to not use mipmaps.
加载一些 mipmap 或将 GL_TEXTURE_MIN_FILTER
切换为 GL_NEAREST
或 GL_LINEAR
。
我最近一直在使用 C++、SDL 和 OpenGL,但我 运行 遇到了一个问题,我正在尝试构建一个自动纹理加载系统,如下所示,但是所有我的纹理显示为空白的白色图像,我测试了 GLuint,它们似乎生成正确,并且我检查以确保正确分配了地图中键的名称。 这是我程序的图形部分:
SDL_GLContext Graphics_Handler::context;
SDL_Window * Graphics_Handler::window;
std::vector<struct Graphics_Handler::Surface_Container> surface_list;
unsigned int Graphics_Handler::texture_index = 0;
std::map<std::string, GLuint> Graphics_Handler::textures;
/**
* Loads an image
*/
struct Graphics_Handler::Surface_Container {
SDL_Surface * surface;
std::string name;
};
void Graphics_Handler::Load_Textures() {
GLuint *textures = new GLuint[surface_list.size()];
glGenTextures(surface_list.size(), textures);
for (unsigned int i = 0; i < surface_list.size(); i++) {
glBindTexture(GL_TEXTURE_2D, textures[i]);
glTexImage2D(GL_TEXTURE_2D, 0, surface_list[i].surface->format-
>BytesPerPixel, surface_list[i].surface->w, surface_list[i].surface->h, 0,
GL_RGBA, GL_UNSIGNED_BYTE, surface_list[i].surface->pixels);
Graphics_Handler::textures[surface_list[i].name] = textures[i];
}
glBindTexture(GL_TEXTURE_2D, 0);
}
void Graphics_Handler::Load_Surface(const char * file, std::string name) {
Graphics_Handler::Surface_Container surf;
surf.surface = IMG_Load(file);
surf.name = name;
if (surf.surface == 0) Game::GameError((std::string)"Error Loading image
file: " + (std::string)SDL_GetError()); // display the error
surface_list.push_back(surf);
}
/**
* draw a GLuint texture
*/
void Graphics_Handler::Draw_Texture(GLuint texture, float x, float y, float
width, float height){
glColor3f(1,1,1); // Sets the vertex color
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_QUADS); // Begin drawing a quadrilateral
glTexCoord2f(0.0f,0.0f); // Specifies where the vertex is on the image
rectangle(0 = left, 0 = top);
glVertex3f(x, y,0.0f); // Specifies where in space the vertex is
glTexCoord2f(1.0f,0.0f);
glVertex3f(width + x,0.0f + y,0.0f);
glTexCoord2f(1.0f,1.0f);
glVertex3f(width + x, height + y,0.0f);
glTexCoord2f(0.0f,1.0f);
glVertex3f(x,height + y,0.0f);
glEnd();
}
/*
* gets a texture from the texture map
*/
GLuint Graphics_Handler::Get_Texture(std::string name){
return Graphics_Handler::textures[name];
}
/**
* pretty self exclamatory, determines whether a string has a suffix
*/
bool has_suffix(const std::string &str, const std::string &suffix) {
return str.size() >= suffix.size() && str.compare(str.size() -
suffix.size(), suffix.size(), suffix) == 0;
}
/**
* gets all of the textures from the specified location and adds them to the
texture map (Load_Image)
*/
void Graphics_Handler::Load_Texture_Files(std::string location) {
std::string loc = location;
DIR *dir; //um... idk
struct dirent *ent; //pointer to directory
if ((dir = opendir ("textures")) != NULL) {
//loop through the file pointers (ent) and stop once they're null
while ((ent = readdir (dir)) != NULL) {
if(has_suffix(ent->d_name, ".png")){ //make sure it's an image
location = loc;
std::string full_location = location.append(ent->d_name);
//add the texture directory to the string to the png file and convert it to
a const char*
std::string name = ((std::string)ent-
>d_name).erase(((std::string)ent->d_name).length()-4); //remove the .png
extension from the file name to get the common name
Graphics_Handler::Load_Surface(full_location.c_str(), name);
}
}
closedir (dir); //no memory leaks ;)
Graphics_Handler::Load_Textures();
} else {
//could not open directory
Game::GameError("Couldn't load textures!?");
}
}
/**
* Draws everything to the screen
*/
void Graphics_Handler::Draw(int x, int y){
glClear(GL_COLOR_BUFFER_BIT); // clear the screen
glClearColor(0,0,0,1); // set the clear color
Draw_Texture(Graphics_Handler::Get_Texture("cat"), 50, 50, 100, 100);
//loop through all of the entities and draw them
SDL_GL_SwapWindow(Graphics_Handler::window); // Display the screen
}
我有两个纹理 cat.png 和 dirt.png
textures are coming up as blank white images
听起来像 incomplete textures:
What's wrong with this code?
glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D, textureID); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
The texture won't work because it is incomplete. The default
GL_TEXTURE_MIN_FILTER
state isGL_NEAREST_MIPMAP_LINEAR
. And because OpenGL defines the defaultGL_TEXTURE_MAX_LEVEL
to be 1000, OpenGL will expect there to be mipmap levels defined. Since you have only defined a single mipmap level, OpenGL will consider the texture incomplete until theGL_TEXTURE_MAX_LEVEL
is properly set, or theGL_TEXTURE_MIN_FILTER
parameter is set to not use mipmaps.
加载一些 mipmap 或将 GL_TEXTURE_MIN_FILTER
切换为 GL_NEAREST
或 GL_LINEAR
。