2016-03-29 3 views
-2

http://coliru.stacked-crooked.com/a/400b648e7442eeb3画像openglの

でポリゴンを埋めるあなたがコードの一部を読むことができます:アイデアは、テクスチャ(画像は、クワッド内で繰り返される)とポリゴンクワッドを気力することです。

イメージが1回だけ繰り返されるようにしてください。言い換えれば、イメージをポリゴンの背景として配置したいと思っています。私は800x600のウィンドウで、私は(たとえばglvertex3iで定義されたクワッド内に)600x400のビリヤードテーブルを載せたいと思います。 glvertex2iと2Dで実装することもできます(2Dゲームと同様)。あなたは非推奨バージョンのを使用している

GLuint MyLoadTexture(std::string const filename) 
{ 
    GLuint texname = 0; 
    /* this is actually tied to the OpenGL context, so this should 
    * actually be a map GLcontext -> std::string -> texturename */ 
    static std::map<std::string, GLuint> loaded_textures; 
    if(loaded_textures.find(filename) != loaded_textures.end()) { 
     texname = loaded_textures[filename]; 
     glBindTexture(GL_TEXTURE_2D, texname); 
     return texname; 
    } 

    int width,height; 
    std::vector<uint8_t> image; 
    if(ReadJPEG(filename, &image, &width, &height)) { 
     std::cerr 
      << "error reading JPEG" 
      << std::endl; 
     return 0; 
    } 

    glGenTextures(1, &texname); 
    if(!texname) { 
     std::cerr 
      << "error generating OpenGL texture name" 
      << std::endl; 
     return 0; 
    } 

    glBindTexture(GL_TEXTURE_2D, texname); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE); 

    /* glTexImage2D(
     GL_TEXTURE_2D, 0, GL_RGB, 
     width, height, 0, 
     GL_RGB, 
     GL_UNSIGNED_BYTE, buffer); 
    */ 
    glTexImage2D(
      GL_TEXTURE_2D, 0, GL_RGB, 
      width, height, 0, 
      GL_RGB, 
      GL_UNSIGNED_BYTE, &image[0]); 

    loaded_textures[filename] = texname; 

    return texname; 
} 

int ReadJPEG(
    std::string const filename, 
    std::vector<uint8_t> *image, 
    int *width, int *height) 
{ 
    if(!image) { 
      return -1; 
     } 

     FILE * const infile = fopen(filename.c_str(), "rb"); 
     if(!infile) { 
      std::cerr 
       << "error opening file " 
       << filename 
       << " : " 
       << strerror(errno) 
       << std::endl; 
      return -2; 
     } 

     struct jpeg_decompress_struct cinfo; 
     struct jpeg_error_mgr jerr; 
     cinfo.err = jpeg_std_error(&jerr); 

     jpeg_create_decompress(&cinfo); 

     jpeg_stdio_src(&cinfo, infile); 
     jpeg_read_header(&cinfo, TRUE); 
     jpeg_calc_output_dimensions(&cinfo); 
     jpeg_start_decompress(&cinfo); 

     if(width) { *width = cinfo.output_width; } 
     if(height) { *height = cinfo.output_height; } 

     size_t const stride = cinfo.output_width * cinfo.output_components; 
     image->resize(cinfo.output_height * stride); 

     for(size_t i = 0; i < cinfo.output_height;) { 
      uint8_t * const row = &(*image)[stride * i]; 
      i += jpeg_read_scanlines(&cinfo, (unsigned char**)&row, 1); 
     } 
     jpeg_finish_decompress(&cinfo); 

     fclose(infile); 
     return 0; 
    } 
+0

コードの関連部分を投稿してください。 'ReadJPEG'は実際にこの質問に答えるのに役立ちません。描画コードを表示します。 – szym

+0

サンプルコードはcoliruにあります。クワッド内のテクスチャを繰り返す例です。更新:具体的な例のIve更新coliruリンク(pared.jpgは、テクスチャを持つ画像、この場合は壁です...) –

+1

テクスチャ座標を0.0 ... 1.0の範囲にクランプします。また、あなたは非常に古いOpenGL 2.0 APIを使用していることを意識する必要があります。これをやめ、すぐにOpenGL 4に行くのは良い考えです。 – Drop

答えて

0

は私が気づい:

すべてのヘルプはまた

をapreciatedされるだろう、私が代わりにloadtextureとreadjpeg(と思う)のいずれかのJPGファイルをサポートするための、より良いコードを持っていますOpenGL。あなたの状況については、テクスチャ内のアルファ値に関心があるかどうかはわかりません。また、各カラーチャンネルには何バイトありますか?これは知ることが重要です。あなたのコードのこのセクションでは

私はそれが改善されなければならない参照カップルの事があります。

glGenTextures(1, &texname); 
if(!texname) { 
    std::cerr 
     << "error generating OpenGL texture name" 
     << std::endl; 
    return 0; 
} 

glBindTexture(GL_TEXTURE_2D, texname); 
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE); 

/* glTexImage2D(
    GL_TEXTURE_2D, 0, GL_RGB, 
    width, height, 0, 
    GL_RGB, 
    GL_UNSIGNED_BYTE, buffer); 
*/ 
glTexImage2D(
     GL_TEXTURE_2D, 0, GL_RGB, 
     width, height, 0, 
     GL_RGB, 
     GL_UNSIGNED_BYTE, &image[0]); 

loaded_textures[filename] = texname; 

あなたはglGenTextures(1, &texname);呼び出す前に、あなたはこれが最初に呼び出す必要があります:あなたの呼び出しの後

glGetError(); // This will clear errors 

をtexnameにエラーがないかどうかを確認する代わりにglGenTextures(1, &texname);に変更してください。

GLenum err = glGetError(); 
if (err != GL_NO_ERROR) { 
    // Generate Error Here, either log message to file, console or throw an error 
} 

次はあなたのglBindTexture(GL_TEXTURE_2D, texname);です。今度は、テクスチャを生成してバインドするOpenGLの関数については、2番目のパラメータはOpenGLが自動的に生成し、与えられたファイル名に関連付ける無署名のIDです。マシンが符号なしの値を読み取って複数のリソースをチェックするのは、文字列をチェックして検証するよりも簡単です。また、アプリケーションが100秒、1000秒、または1,000,000秒のリソースファイルを処理している場合のパフォーマンスの向上です。

これで、OpenGLがミップマップを処理する方法に関するパラメータを設定します。そして、あなたのコードのこのセクションは、これがミップマッピングに必要な振る舞いであれば問題ありません。しかし、テクスチャを使用するためのこの関数の呼び出し側には、ミップマップの品質レベルを設定するメソッドはありません。ここで私が普通にやっているのは、ミップマップのさまざまな品質レベルを扱う列挙です。ミップマップを扱う方法のスニペットです:

注:この関数では、enum値は定義されていないか宣言されています。パラメータに渡されます。私はそれは無関係である可能性が参照

// This enum I usually have it declared or defined in a CommonStructs header. 
enum FilterQuality { 
    FILTER_NONE = 1, 
    FILTER_GOOD, 
    FILTER_BETTER, 
    FILTER_BEST 
}; // FilterQuality 

// Now as within side of my function for generating texture files I have something like this for mipmaps:  
if (texture.generateMipMap) { 
    switch (texture.filterQuality) { 
     case TextureInfo::FILTER_NONE : { 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); 
      break; 
     } 
     case TextureInfo::FILTER_GOOD: { 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); 
      break; 
     } 
     case TextureInfo::FILTER_BEST: { 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 
      break; 
     } 
     default: { 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); 
     } 
    } // Switch 

    if (openglVersion.x < 3) { 
     // In OpenGL v3 GL_GENERATE_MIPMAP Is Deprecated, And In 3.1+ It Was Removed 
     // So For Those Versions We Use glGenerateMipmap below 
     static const unsigned int GL_GENERATE_MIPMAP = 0x8191; 
     glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); 
    } 
} else { // No MipMaps 
    switch(texture.filterQuality) { 
     case TextureInfo::FILTER_NONE: 
     case TextureInfo::FILTER_GOOD: { 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
      break; 
     } 
     default: { 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
     } 
    } 
} 

唯一のことは、私はそれを使用したことがないために、今、これはあなたが望む行動のいくつかのタイプとすることができ、そのために私にはわからないglTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);にお電話です。

mimpmapping情報を設定したら、コードからテクスチャを生成するために欠落しているクランプまたはラップリピートのパラメータを設定します。

bool wrapRepeat; // This variable would not be here inside of the function, 
// but would come from this function's definition so that the caller can 
// set this parameter or flag to the behavior they want for each texture in use. 

// What these two lines of code will do depending on the state of wrapRepeat 
// is they will cause the last parameter to be either WRAP in S & T coordinates or 
// to clamp to edge in both S & T coordinates. 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (wrapRepeat ? GL_REPEAT : GL_CLAMP_TO_EDGE)); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (wrapRepeat ? GL_REPEAT : GL_CLAMP_TO_EDGE)); 

最後に、あなたがメモリにテクスチャをロードしますあなたのコードを持っており、参考として、これは私がテクスチャを生成するために、私の機能の中に持っているものです::

// Load Texture Into Video Memory 
glPixelStorei(GL_UNPACK_ALIGNMENT, texture.hasAlphaChannel ? 4 : 1); 
glTexImage2D(GL_TEXTURE_2D, 
    0, 
    (texture.hasAlphaChannel ? GL_RGBA8 : GL_RGB8), 
    texture.uWidth, 
    texture.uHeight, 
    0, 
    (texture.hasAlphaChannel ? GL_RGBA : GL_RGB), 
    GL_UNSIGNED_BYTE, 
    &texture.vPixelData[0]); 

if (texture.generateMipMap && openglVersion.x >= 3) { 
    glGenerateMipmap(GL_TEXTURE_2D); 
} 

これは助けるべきである彼らは、次のようになりテクスチャがラップされクランプされていない現在の問題を解決する必要があります。

私のプロジェクトでは、具体的にテクスチャファイルを読み込む派生ファイルハンドラクラスがあり、TGAファイルまたはPNGファイルと、それが他のテクスチャや画像ファイルそのクラスに関数を追加してファイルの種類を解析する限りです。レンダリングで使用される私の実際のイメージタイプは、ファイルリーダーとは別です。これらはここでこのコードとは別です。このコードは、AssetStorageクラスに属します。このクラスの鉱山は、すべての資産を保管し、その資産を管理する責任を負いません。このクラスは何もレンダリングしませんが、オブジェクトをRAMとビデオRAMにロードします。バッチクラスとバッチマネージャクラスで、オブジェクトのレンダリングをすべて処理します。今では私のオブジェクトはすべてGLSLシェーダを使って構築されています。しかし、この機能を完全に表示するために、私のフレームワークがどのように設計されているかを参考にすることができます。

// ---------------------------------------------------------------------------- 
// add() 
// Creates An OpenGL Texture And Returns It's ID Value 
// This Can Only Be Called From The Main OpenGL Thread 
TextureInfo AssetStorage::add(const Texture& texture, const std::string& strFilename) { 
    if (INVALID_UNSIGNED != getTextureInfo(strFilename).uTextureId) { 
     std::ostringstream strStream; 
     strStream << __FUNCTION__ << " can not store " << strFilename << " multiple times"; 
     throw ExceptionHandler(strStream); 
    } 

    TextureInfo textureInfo; 
    textureInfo.hasTransparency = texture.hasAlphaChannel; 
    textureInfo.size = glm::uvec2(texture.uWidth, texture.uHeight); 

    glGetError(); // Clear Errors 

    glGenTextures(1, &textureInfo.uTextureId); 

    GLenum err = glGetError(); 
    if (err != GL_NO_ERROR) { 
     std::ostringstream strStream; 
     strStream << __FUNCTION__ << " failed glGenTextures with error code 0x" << std::hex << err; 
     throw ExceptionHandler(strStream); 
    } 

    glBindTexture(GL_TEXTURE_2D, textureInfo.uTextureId); 

    // Wrap Textures 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (texture.wrapRepeat ? GL_REPEAT : GL_CLAMP_TO_EDGE)); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (texture.wrapRepeat ? GL_REPEAT : GL_CLAMP_TO_EDGE)); 

    const glm::uvec2& openglVersion = s_pSettings->getOpenglVersion(); 

    if (texture.generateMipMap) { 
     switch (texture.filterQuality) { 
      case TextureInfo::FILTER_NONE : { 
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); 
       break; 
      } 
      case TextureInfo::FILTER_GOOD: { 
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); 
       break; 
      } 
      case TextureInfo::FILTER_BEST: { 
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 
       break; 
      } 
      default: { 
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); 
      } 
     } // Switch 

     if (openglVersion.x < 3) { 
      // In OpenGL v3 GL_GENERATE_MIPMAP Is Deprecated, And In 3.1+ It Was Removed 
      // So For Those Versions We Use glGenerateMipmap below 
      static const unsigned int GL_GENERATE_MIPMAP = 0x8191; 
      glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); 
     } 
    } else { // No MipMaps 
     switch(texture.filterQuality) { 
      case TextureInfo::FILTER_NONE: 
      case TextureInfo::FILTER_GOOD: { 
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
       break; 
      } 
      default: { 
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
      } 
     } 
    } 

    // Load Texture Into Video Memory 
    glPixelStorei(GL_UNPACK_ALIGNMENT, texture.hasAlphaChannel ? 4 : 1); 
    glTexImage2D(GL_TEXTURE_2D, 
     0, 
     (texture.hasAlphaChannel ? GL_RGBA8 : GL_RGB8), 
     texture.uWidth, 
     texture.uHeight, 
     0, 
     (texture.hasAlphaChannel ? GL_RGBA : GL_RGB), 
     GL_UNSIGNED_BYTE, 
     &texture.vPixelData[0]); 

    if (texture.generateMipMap && openglVersion.x >= 3) { 
     glGenerateMipmap(GL_TEXTURE_2D); 
    } 

    // Store TextureId 
    BlockThread blockThread(s_criticalSection); 
    m_textureInfos.insert(MapTextureInfos::value_type(strFilename, textureInfo)); 

    if (s_pSettings->isDebugLoggingEnabled(Settings::DEBUG_MEMORY)) { 
     Logger::log(std::string("Created ") + strFilename); 
    } 

    return textureInfo; 
} // add 
+0

coliruで編集できますか?使い方の例があるといいですね.http://cnilove.com/pool-table-top/perfect-pool-table-top-for-home-decoration-ideas-with-pool-table-top/バックグラウンドとして...私は四角形の幅、高さのディメンションでそれを使用したいと思います。上記の "改善された"関数(loadtextureとreadjpege)を使用していると仮定し、他のcoliruで使用されていません。ご協力いただきありがとうございます。その色やアルファのアルファベットではないアルファ、私は常に0を使う(私は思う)...私は四角の内部にビリヤードテーブルを表示する必要があります...それからボールなどを追加する必要があります... –

+0

また、そうではありませんこのメソッドを使用するには、何かが簡単であればいいです。例えば、800x600のようなウィンドウでは、glClearColorとして黒色を追加し、billardsテーブルを例えば400x300に置くことができます(境界線を黒くする)。あなたのお手伝いをありがとう... –

+0

@EduardoGutiérrezテクスチャを適用するのではなく、ポリゴンにマテリアル(カラー)を適用することに違いがあります。 –

関連する問題