4

以前にゲームを開発していて、ちょっとした問題に遭遇しました! 私は単一の画像でゲームを開始しました。各テクスチャには独自のファイルがありました。私がそれを行うのがどれほどばかであるかに気づき、すべてのテクスチャを含む 1 つの画像を使用することに切り替えようとしたのは少し気になりました (いずれにせよ、それらは非常に小さいです)。さて、問題が発生しました。元のテクスチャ ( 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;
}

編集:私は問題を発見しました。私の画像は 2 の正方形ではないため、正しく表示されませんでした。

4

2 に答える 2

11
  • 適切な向きになるように反転していないため、画像が反転しています。トートロジーのように聞こえますが、OpenGL の座標系はテクスチャを上にマッピングします。ここで、(0,0) は左下、(1,1) は右上です。これを修正することは、教科書的なタイプの演習です。

  • glActiveTexture(GL_TEXTURE0)後続のgl*呼び出しで、変更中のテクスチャを認識できるようにする (つまり、そのテクスチャをアクティブにする)必要があります。初期値GL_TEXTURE0

  • それがあなたの質問の一部ではないことは知っていますが、7年間廃止されたOpenGLコードを使用しています. 一般的な提案として、プログラマブル パイプラインに切り替える必要があります。これは、最新の OpenGL の基本への ogldevへのリンクです。または、少なくともその一部は 4.0+ です。一部は 3 年代ですが、シェーダーは FFP より優れています。これは Swiftless からの別の短いものです。基本的に OpenGL 4.0 以降を検索すると、Google が案内してくれます。それはより急な学習曲線ですが、それだけの価値があります。

于 2013-07-22T03:41:49.713 に答える
3

これは、DDS (DXT) ファイルでのみ発生したことがあり、ブロックが逆さまになるのを防ぐために反転する必要がありました。コードでこれを行う必要がありましたが、別の方法として、画像プログラムで画像を反転するだけです。

正直なところ、私は OpenGL で PNG ファイルを使用していません。最後に PNG を使用したのは、少し前に XNA を使用したときだったと思います。

私はここでこれを見つけました: Flipping OpenGL texture 言語は違いますが、どちらも同じ問題を抱えているようです。

また、この関数を調べて、データを反転できるかどうかを確認します

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

それか、自分で行うか、他の何かを使用して PNG 画像をインポートする必要があります。

glMatrixMode(GL_TEXTURE) を使用してレンダリング中にマトリックスを反転できることを示唆するそのリンクの回答に気付きましたが、これはあなたがやりたいことではないと思います。

幸運を。

于 2013-07-22T18:52:47.323 に答える