我之前正在开发一款游戏并遇到了一些问题!我用单张图片开始游戏。每个纹理都有自己的文件。我有点意识到我要做多少白痴,并尝试切换到使用包含所有纹理的一张图片(无论如何它们都非常小)。现在,出现了一个问题。当加载比原始纹理(10 x 10)更大的图像时,它几乎就像没有使用最近邻大小算法一起显示。我得到的是模糊的图像。它也被翻转......为什么会出现这些问题?
下面的代码和图片。
这是第一个显示包含文本和符号的精灵表。 (它很小,100 x 100) http://imgur.com/HU5zEAO.jpg
这是程序运行时的结果。 http://i.imgur.com/HeVPdPy.jpg
这是main.cpp文件
#include <GL/glew.h>
#include <GL/glut.h>
#include "spritesheet_class.h"
#include "load_img.h"
GLuint TextSheet;
Spritesheet Test;
void LoadFiles()
{
GLuint TextSheet = LoadTexture( "davetica.png", 100, 100, 0 );
Test.SetTex( TextSheet, 100, 100, 10, 10 );
}
void Reshape( int width, int height )
{
glViewport( 0, 0, (GLsizei)width, (GLsizei)height );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0.0f, width, 0.0f, height, 1.0f, 100.0f );
glMatrixMode( GL_MODELVIEW );
}
void Display()
{
glClear( GL_COLOR_BUFFER_BIT );
glLoadIdentity();
glTranslatef( 0.0f, 0.0f, -1.0f );
Test.DrawSprite( 1, 0, 0, 400, 400 );
glutSwapBuffers();
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_DOUBLE );
glutInitWindowPosition( 200, 100 );
glutInitWindowSize( 512, 512 );
glutCreateWindow( "Sprite Sheets" );
glutDisplayFunc( Display );
glutIdleFunc( Display );
glutReshapeFunc( Reshape );
LoadFiles();
glutMainLoop();
}
现在这里是我编写Spritesheet类的类头。
#ifndef SPRITESHEET_CLASS_H_INCLUDED
#define SPRITESHEET_CLASS_H_INCLUDED
#include "load_img.h"
class Spritesheet
{
public:
void SetTex( GLuint Tex, int ImgW, int ImgH, int HorzAm, int VertAm );
void DrawSprite( int spriteNum, int xLoc, int yLoc, int width, int height );
private:
GLuint Texture;
int imageWidth, imageHeight, horiAm, vertAm;
};
void Spritesheet::SetTex( GLuint Tex, int ImgW, int ImgH, int HorzAm, int VertAm )
{
imageWidth = ImgW;
imageHeight = ImgH;
horiAm = HorzAm;
vertAm = VertAm;
Texture = Tex;
}
void Spritesheet::DrawSprite( int spriteNum, int xLoc, int yLoc, int width, int height )
{
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, Texture );
glBegin( GL_QUADS );
glTexCoord2f( 1.0f, 0.0f );
glVertex2f( xLoc, yLoc );
glTexCoord2f( 1.0f, 1.0f );
glVertex2f( xLoc, yLoc+height );
glTexCoord2f( 0.0f, 1.0f );
glVertex2f( xLoc+width, yLoc+height );
glTexCoord2f( 0.0f, 0.0f );
glVertex2f( xLoc+width, yLoc );
glEnd();
glDisable( GL_TEXTURE_2D );
}
#endif // SPRITESHEET_CLASS_H_INCLUDED
最后,如果你需要这个,这里是处理LoadImage函数的文件,我用它来加载和格式化纹理。
#ifndef LOAD_IMG_H_INCLUDED
#define LOAD_IMG_H_INCLUDED
#include <iostream>
#include <stbimg.h>
#include <string>
bool loadCorrectly = true;
using namespace std;
GLuint LoadTexture( const char *filename, int w, int h, int n )
{
unsigned char *data = stbi_load( filename, &w, &h, &n, 4 );
GLuint texture;
if( data == NULL )
{
cout << "ERROR: '"<< filename << "' HAS BEEN MODIFIED OR IS MISSING." << endl;
return 0;
}else
{
cout << "Loaded: '" << filename << "' successfully." << endl;
}
glGenTextures( 1, &texture );
glBindTexture( GL_TEXTURE_2D, texture );
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT );
gluBuild2DMipmaps( GL_TEXTURE_2D, 3, w, h,GL_RGBA, GL_UNSIGNED_BYTE, data );
free( data );
return texture;
}
编辑:我发现了这个问题。我的图像不是两个正方形,所以它没有正确显示。
答案 0 :(得分:9)
您的图片被翻转是因为您没有将它们翻转为正确定位。它听起来是同义反复的,但OpenGL的坐标系统将纹理映射到向上,其中(0,0)位于左下角,(1,1)位于右上角。修复这是一种教科书类型的练习。
您需要致电glActiveTexture(GL_TEXTURE0)
以使后续的gl*
调用知道他们正在修改哪个纹理(即使该纹理处于活动状态)。初始值为GL_TEXTURE0
,但我仍然会将其放入,以便您不会遇到潜在的问题。
我知道这不是你问题的一部分,但你使用的是已被弃用了7年的OpenGL代码。作为一般建议,您应该切换到可编程管道。 Here's a link to ogldev了解现代OpenGL的基础知识,或者至少其中一些是4.0+。有些是三分之一,但着色器比FFP好。 Here's another short few from Swiftless。基本上搜索OpenGL 4.0或更高版本,谷歌将指导您。这是一个更陡峭的学习曲线,但它是值得的。
答案 1 :(得分:2)
我只在DDS(DXT)文件中遇到过这种情况,其中需要翻转块以防止它们颠倒。我必须在代码中执行此操作,但另一种方法是简单地在图像程序中翻转图像。
老实说,我不会在OpenGL中使用PNG文件,我想我上次使用PNG的时候是在不久前使用过XNA。
我在这里找到了这个:Flipping OpenGL texture 这是一种不同的语言,但你们似乎都有同样的问题。
我也会调查这个函数,看看它是否能够翻转数据
stbi_load( filename, &w, &h, &n, 4 );
要么是这样,要么你必须自己动手或使用别的东西来导入PNG图像。
我确实注意到该链接上的答案,建议您可以在渲染期间使用glMatrixMode(GL_TEXTURE)翻转矩阵,但我想这不是您想要做的事情。
祝你好运。