简体   繁体   English

OpenGL纹理渲染颠倒,模糊

[英]OpenGL Textures rendering upside down, and blurred

I was developing a game earlier and came across a bit of an issue! 我之前正在开发一款游戏并遇到了一些问题! I had started the game with single images. 我用单张图片开始游戏。 Each texture had it's own file. 每个纹理都有自己的文件。 It was a bit into it that I realized how much of an idiot I was to do that, and tried to switch over to using one picture that contains all the textures ( they're quite small anyway ). 我有点意识到我要做多少白痴,并尝试切换到使用包含所有纹理的一张图片(无论如何它们都非常小)。 Now, a problem arose. 现在,出现了一个问题。 When a larger image than my original texture ( 10 x 10 ) is loaded in, it's almost as if it's not being displayed with the nearest neighbor sizing algorithm. 当加载比原始纹理(10 x 10)更大的图像时,它几乎就像没有使用最近邻大小算法一起显示。 What I get is a blurred image. 我得到的是模糊的图像。 Also it's flipped... Why are either of these issues happening? 它也被翻转......为什么这些问题都发生了?

Code and images below. 代码和图片如下。

Here is the first showing a sprite sheet containing text and symbols. 这是第一个显示包含文本和符号的精灵表。 (It's quite small, 100 x 100 ) http://imgur.com/HU5zEAO.jpg (它很小,100 x 100) http://imgur.com/HU5zEAO.jpg

This is what I get when the program is run. 这是程序运行时我得到的。 http://i.imgur.com/HeVPdPy.jpg http://i.imgur.com/HeVPdPy.jpg

Here is the main.cpp file 这是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();

}

Now here is the class header in which I write the Spritesheet class. 现在这里是我编写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

Finally, if you need this, here is the file that handles the LoadImage function in which I use to load and format the textures. 最后,如果你需要这个,这里是处理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;
}

EDIT: I found out the issue. 编辑:我发现了这个问题。 My image was not a square of two, so therefore it was not displaying properly. 我的图像不是两个正方形,所以它没有正确显示。

  • Your images are flipped because you have not flipped them to be oriented properly. 您的图像被翻转,因为您没有将它们翻转为正确定向。 It sounds tautological, but OpenGL's coordinate system maps textures down to up where (0,0) is in the bottom left and (1,1) is in the top right. 它听起来是同义反复的,但OpenGL的坐标系统将纹理映射到向上,其中(0,0)位于左下角,(1,1)位于右上角。 Fixing this is a textbook type of exercise. 修复这是一种教科书类型的练习。

  • You need to call glActiveTexture(GL_TEXTURE0) to make subsequent gl* calls know which texture they're modifying (ie make that texture active). 你需要调用glActiveTexture(GL_TEXTURE0)来使后续的gl*调用知道他们正在修改哪个纹理(即使该纹理处于活动状态)。 The initial value is GL_TEXTURE0 but I'd still put it in so that you don't end up with potential problems down the line. 初始值是GL_TEXTURE0但我仍然把它放进去,这样你就不会遇到潜在的问题了。

  • I know it's not part of your question, but you're using OpenGL code that's been deprecated for 7 years. 我知道这不是你问题的一部分,但你使用的是已被弃用了7年的OpenGL代码。 As a general suggestion, you should switch to the programmable pipeline. 作为一般建议,您应该切换到可编程管道。 Here's a link to ogldev to the basics in modern OpenGL, or at least some of it is 4.0+. 这里是ogldev到现代OpenGL基础知识的链接 ,或者至少有一些是4.0+。 Some is in the 3's but shaders are better than FFP. 有些是三分之一,但着色器比FFP好。 Here's another short few from Swiftless . 这是Swiftless的另外一小部分 Basically search for OpenGL 4.0 or later and the Googles will guide you. 基本上搜索OpenGL 4.0或更高版本,谷歌将指导您。 It's a steeper learning curve but it is worth it. 这是一个更陡峭的学习曲线,但它是值得的。

I have only ever encountered this with DDS (DXT) files, in which the blocks needed to be flipped to prevent them being upside down. 我只用DDS(DXT)文件遇到过这种情况,其中需要翻转块以防止它们颠倒。 I had to do this in code, but the alternative is to simply flip the image in an image program. 我必须在代码中执行此操作,但另一种方法是简单地在图像程序中翻转图像。

To be honest though, I don't use PNG files in OpenGL and I think the last time I used PNG was with XNA some time ago. 说实话,我不在OpenGL中使用PNG文件,我想我上次使用PNG的时候是不久前的XNA。

I found this here: Flipping OpenGL texture It's a different language but you both seem to have the same problem. 我在这里找到了这个: 翻转OpenGL纹理这是一种不同的语言,但你们似乎都有同样的问题。

I'd also look into this function and see if it is capable of flipping the data 我也会研究这个函数,看看它是否能够翻转数据

stbi_load( filename, &w, &h, &n, 4 );

Either that, or you have to do it yourself or use something else to import PNG images. 要么是这样,要么你必须自己做或使用其他东西来导入PNG图像。

I did notice an answer on that link which suggests you can flip the matrix during rendering using glMatrixMode(GL_TEXTURE), but I imagine this isn't something you want to do. 我确实注意到该链接上的答案,建议您可以在渲染期间使用glMatrixMode(GL_TEXTURE)翻转矩阵,但我想这不是您想要做的事情。

Good luck. 祝好运。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM