3

SOIL を使用して JPEG 画像からテクスチャを読み込む機能があります。

これまでのところ、関数を使用してテクスチャをロードし、SOIL_load_image()OpenGL を使用してイメージを提供してきましたglTexImage2D(以下のコードを参照)。でも!私のテクスチャは上下逆なので、SOIL_load_OGL_texture()代わりにを使用しSOIL_FLAG_INVERT_Y、画像を反転するために を提供したいと思いました。私の問題は、SOIL_load_OGL_texture()関数で未処理の例外が発生することです。

コードはほとんどドキュメントからのコピー ペーストなので、このエラーが発生する理由がわかりません。

(注: 頂点シェーダーでテクスチャを反転できますが、SOIL を使用したいと思います。)

古い方法

int width;
int height;

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);

image = SOIL_load_image(filename, &width, &height, 0, SOIL_LOAD_RGB);

if (image == NULL) {
    std::cout << "An error occurred while loading image." << std::endl;
    exit(EXIT_FAILURE);
}
std::cout << "Loaded first texture image" << std::endl;

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
SOIL_free_image_data(image);

今試していること

GLuint image;

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);

image = SOIL_load_OGL_texture(
        filename,
        SOIL_LOAD_RGB,
        SOIL_CREATE_NEW_ID,
        SOIL_FLAG_INVERT_Y
    );

if (image == 0)
    cerr << "SOIL loading error: '" << SOIL_last_result() << "' (" << "res_texture.png" << ")" << endl;

そしてエラー

Unhandled exception at 0x0F5427FF (msvcr110d.dll) in AnotherTutorial.exe: 0xC0000005: Access violation reading location 0x00000000.
4

5 に答える 5

1

SOILの使用には答えがないように思われるので、私の解決策を投稿します:

頂点シェーダーでは、次のことを行います。

Texcoord = vec2(texcoord.x, 1.0-texcoord.y);
gl_Position = proj * view * model * vec4( position, 1.0 );

1.0-texcoord.y は、画像の y 軸を反転します。それほどクリーンなソリューションではありませんが、機能します。

于 2013-06-05T15:00:39.310 に答える
1
void loadTexture(GLuint* texture, char* path){
    *texture = SOIL_load_OGL_texture(filename,
                                     SOIL_LOAD_AUTO,
                                     SOIL_CREATE_NEW_ID,
                                     SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_MULTIPLY_ALPHA
                                    );
    if(*textre == NULL){
        printf("[Texture loader] \"%s\" failed to load!\n", filename);
    }
}

void drawTexturedRect(int x, int y, int w, int h, GLuint texture){
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDepthMask(GL_FALSE);
    glDisable(GL_DEPTH_TEST);
    glBegin(GL_QUADS);
        glColor3f(255,255,255);
        glTexCoord2f(0,0);
        glVertex2f(x,y);
        glTexCoord2f(1,0);
        glVertex2f(x+w,y);
        glTexCoord2f(0,1);
        glVertex2f(x,y+h);
        glTexCoord2f(1,1);
        glVertex2f(x+w,y+h);
        glTexCoord2f(0,1);
        glVertex2f(x,y+h);
    glEnd();
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glDisable(GL_BLEND);
}

そして、次のことができます:

// At initialization
GLuint texture;
loadTexture(&texture, "filename.png");

// Drawing part
drawTexturedRect(25,25,256,256,texture);

これは私が個人的に使用しているもので、完璧に機能します。SDL と SOIL を組み合わせた Visual Studio 2012 を使用しています。

于 2013-09-30T11:48:09.107 に答える
0

上記の解決策はどれもうまくいきません。次のような同じ問題があります。

SOIL_load_OGL_texture Unhandled exception at xxxxxx (msvcr120d.dll)

http://www.idevgames.com/forums/thread-10281.htmlで解決策を読んだ後、パスを「相対パス」から「絶対パス」に変更しました。

ところで、私は中国人なので、パスが非ASCII文字なしですべて英語であることを確認する必要があります。

例えば:

コードを次から変更します

SOIL_load_OGL_texture("my_texture.bmp",
        SOIL_LOAD_AUTO,
        SOIL_CREATE_NEW_ID,
        SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_MULTIPLY_ALPHA
        );

SOIL_load_OGL_texture("D:\temp_20160926\ConsoleApplication20\ConsoleApplication19\my_texture.bmp",
        SOIL_LOAD_AUTO,
        SOIL_CREATE_NEW_ID,
        SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_MULTIPLY_ALPHA
        );

そして、それは私の問題を完全に解決します。

これは SOIL のバグ/制限だと思います。ただし、ここで行うように絶対パスを指定することでこれを回避できます。

それがあなたにも役立つことを願っています。

于 2016-11-01T16:34:51.047 に答える
0

基本的にはコマンドで

SOIL_load_image(filename, &width, &height, 0, SOIL_LOAD_RGB);

渡す 0 (NULL) は、ライブラリによって設定されたチャネルへのポインタであるため、もちろん、ライブラリがそれにアクセスしようとすると、次のようになります。

AnotherTutorial.exe の 0x0F5427FF (msvcr110d.dll) で未処理の例外: 0xC0000005: アクセス違反の読み取り場所 0x00000000

変数を宣言して使用してみてください。

int channels;
SOIL_load_image(filename, &width, &height, &channels, SOIL_LOAD_RGB);
于 2015-02-05T15:34:14.220 に答える
0

SOIL_load_imageunsigned char*はい、画像データを保持する配列を返します。

次に、通常、このデータを に送り、 をgl使用してglGenerateTexturesテクスチャ ID を割り当て、 を呼び出しglTexImage2Dます。

SOIL_load_OGL_textureテクスチャIDを返すので、代わりにこれを行うことができます:

texture[0] = SOIL_load_OGL_texture(...)

あなたの目標がテクスチャ0、1、2をロードすることである場合。

invert y に関しては、最も簡単で重みのない解決策は、 でテクスチャ座標を反転するglTexCoordことですが、それは何をしているかによって異なります。リソースを 1 回限りの操作などとしてロードしている場合は、おそらく言及する価値のない起動時間を除いて、害はありません。ただし、必要に応じてメイン ループを介してリソースを動的にロードしている場合、y フラグ (および任意のフラグについて) を反転すると、プログラム全体で追加の処理が行われるため、パフォーマンスが低下する可能性があります。

使用する大きな利点の 1 つは、提供されていないSOIL_load_image元の画像から幅、高さ、およびチャネル番号を取得できることです。SOIL_load_OGL_texture

それが役立つ場合、SOIL_load_OGL_textureRGB 画像を RGB としてロードするとしばらくするとクラッシュしSOIL_LOAD_RGBAますが、.

の方が簡単だと思いますSOIL_load_image。これが役立つことを願っています。また、soil に同梱されている SOIL ソース コードをチェックして、何が起こっているかを確認してください。

于 2013-12-27T01:53:06.960 に答える