2017-01-02 19 views
-1

私が作成した円GL_POLYGONに時計の顔の正方形の画像をマッピングしようとしています。私は現在、次のコードを使用しています:私はそれを行うときテクスチャ正方形の画像を円にマッピングするOpenGl

 float angle, radian, x, y, xcos, ysin, tx, ty;  

     glEnable(GL_TEXTURE_2D); 
     glBindTexture(GL_TEXTURE_2D, an_face_texture1); 

     glBegin(GL_POLYGON); 

     for (angle=0.0; angle<360.0; angle+=2.0) 
     { 
      radian = angle * (pi/180.0f); 

      xcos = (float)cos(radian); 
      ysin = (float)sin(radian); 
      x = xcos * radius; 
      y = ysin * radius; 
      tx = (x/radius + 1)*0.5; 
      ty = (y/radius + 1)*0.5; 

      glTexCoord2f(tx, ty); 
      glVertex2f(x, y);   
     } 

     glEnd(); 
     glDisable(GL_TEXTURE_2D); 

は、しかし、私は奇妙なオーバーラップ画像効果で終わります。ここに示すように:enter image description here元のテクスチャ画像はenter image description hereですが、コーナーが切り取られており、それはpng形式です。テクスチャ座標を生成し、前の回答から取っているのこの方法:以下HERE

は、画像をロードするために使用されるコードです:

#ifndef PNGLOAD_H 

#include <png.h> 
#include <stdlib.h> 

int png_load(const char* file_name, 
      int* width, 
      int* height, 
      char** image_data_ptr) 
{ 
png_byte header[8]; 

FILE* fp = fopen(file_name, "rb"); 
if (fp == 0) 
{ 
    fprintf(stderr, "erro: could not open PNG file %s\n", file_name); 
    perror(file_name); 
    return 0; 
} 

// read the header 
fread(header, 1, 8, fp); 

if (png_sig_cmp(header, 0, 8)) 
{ 
    fprintf(stderr, "error: %s is not a PNG.\n", file_name); 
    fclose(fp); 
    return 0; 
} 

png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 
if (!png_ptr) 
{ 
    fprintf(stderr, "error: png_create_read_struct returned 0.\n"); 
    fclose(fp); 
    return 0; 
} 

// create png info struct 
png_infop info_ptr = png_create_info_struct(png_ptr); 
if (!info_ptr) 
{ 
    fprintf(stderr, "error: png_create_info_struct returned 0.\n"); 
    png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); 
    fclose(fp); 
    return 0; 
} 

// create png info struct 
png_infop end_info = png_create_info_struct(png_ptr); 
if (!end_info) 
{ 
    fprintf(stderr, "error: png_create_info_struct returned 0.\n"); 
    png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); 
    fclose(fp); 
    return 0; 
} 

// the code in this if statement gets called if libpng encounters an error 
if (setjmp(png_jmpbuf(png_ptr))) { 
    fprintf(stderr, "error from libpng\n"); 
    png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); 
    fclose(fp); 
    return 0; 
} 

// init png reading 
png_init_io(png_ptr, fp); 

// let libpng know you already read the first 8 bytes 
png_set_sig_bytes(png_ptr, 8); 

// read all the info up to the image data 
png_read_info(png_ptr, info_ptr); 

// variables to pass to get info 
int bit_depth, color_type; 
png_uint_32 temp_width, temp_height; 

// get info about png 
png_get_IHDR(png_ptr, info_ptr, &temp_width, &temp_height, &bit_depth, &color_type, 
    NULL, NULL, NULL); 

if (width) { *width = temp_width; } 
if (height){ *height = temp_height; } 

// Update the png info struct. 
png_read_update_info(png_ptr, info_ptr); 

// Row size in bytes. 
int rowbytes = png_get_rowbytes(png_ptr, info_ptr); 

// glTexImage2d requires rows to be 4-byte aligned 
rowbytes += 3 - ((rowbytes-1) % 4); 

// Allocate the image_data as a big block, to be given to opengl 
png_byte* image_data; 
image_data = (png_byte*)malloc(rowbytes * temp_height * sizeof(png_byte)+15); 
if (image_data == NULL) 
{ 
    fprintf(stderr, "error: could not allocate memory for PNG image data\n"); 
    png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); 
    fclose(fp); 
    return 0; 
} 

// row_pointers is for pointing to image_data for reading the png with libpng 
png_bytep* row_pointers = (png_bytep*)malloc(temp_height * sizeof(png_bytep)); 
if (row_pointers == NULL) 
{ 
    fprintf(stderr, "error: could not allocate memory for PNG row pointers\n"); 
    png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); 
    free(image_data); 
    fclose(fp); 
    return 0; 
} 

// set the individual row_pointers to point at the correct offsets of image_data 
int i; 
for (i = 0; i < temp_height; i++) 
{ 
    row_pointers[temp_height - 1 - i] = image_data + i * rowbytes; 
} 

// read the png into image_data through row_pointers 
png_read_image(png_ptr, row_pointers); 

// clean up 
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); 

//free(image_data); 
*image_data_ptr = (char*)image_data; // return data pointer 

free(row_pointers); 
fclose(fp); 

fprintf(stderr, "\t texture image size is %d x %d\n", *width, *height); 

return 1; 
} 

#endif 

と:

unsigned int load_and_bind_texture(const char* filename) 
{ 
char* image_buffer = NULL; // the image data 
int width = 0; 
int height = 0; 

// read in the PNG image data into image_buffer 
if (png_load(filename, &width, &height, &image_buffer)==0) 
{ 
    fprintf(stderr, "Failed to read image texture from %s\n", filename); 
    exit(1); 
} 

unsigned int tex_handle = 0; 

// request one texture handle 
glGenTextures(1, &tex_handle); 

// create a new texture object and bind it to tex_handle 
glBindTexture(GL_TEXTURE_2D, tex_handle); 

glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 

glTexImage2D(GL_TEXTURE_2D, 0, 
      GL_RGB, width, height, 0, 
      GL_RGB, GL_UNSIGNED_BYTE, image_buffer); 


free(image_buffer); // free the image buffer memory 

return tex_handle; 
} 

これらはその後と呼ばれていますinit()メソッドから:

background_texture = load_and_bind_texture("images/office-wall.png"); 
an_face_texture1 = load_and_bind_texture("images/clock.png"); 
+0

テクスチャを間違って読み込んでいます。ローディングコードを表示していないため、問題を解決する方法はありません。 –

+0

@ NicolBolas画像は、背景がロードされたのと同じ方法でロードされます。両方の画像はpngです。私はあなたの懸念を反映させるために質問を編集しました。ちょうどそれを任意の用途のそれを入れてください。 –

答えて

1

イメージは、バックグラウンドが読み込まれるのと同じ方法でロードされます。

はい、それはほぼ確実にという問題です。両方の画像はPNGですが、ほぼ同じではありませんフォーマットです。

ロードされたテクスチャに表示されているものを実際にデバッグしましょう。 2と10が重なっているのが見えます.3が9と重なっていて、8が4と重なっています。すべてが互いに交錯しています。そしてこのパターンは3回繰り返されます。

元の画像を縦に折りたたんだのと同じです。 3回。

"3"の繰り返しは、libPNGが実際に読み込んだものと実際にテクセルのデータをOpenGLに伝えたものとの間の不一致を強く示唆しています。 OpenGLに、テクスチャがRGBフォーマット(ピクセルあたり3バイト)であると伝えました。

ただし、すべてのPNGがの形式になっているわけではありません。です。一部のPNGはグレースケールです。 1ピクセルあたり1バイト。また、低レベルのlibPNG読み込みインターフェイスを使用したため、正確な形式のPNGのピクセルデータが読み込まれます。はい、それを解凍します。しかし、PNGが概念的に保存したものを正確に読んでいます。

PNGがグレースケールPNGの場合、png_read_imageを呼び出すと、1ピクセルあたり3バイトではないデータを読み取ることができます。しかし、OpenGLに、そのデータは1ピクセルあたり3バイトであると言った。したがって、libPNGがピクセルあたり1バイトを書き込んだ場合、OpenGLに間違ったテクセルデータが与えられます。

これは悪いです。

libPNGの低レベル読み込みルーチンを使用する場合、で実際に読み込まれるPNGの形式をチェックし、OpenGLコードを一致させる必要があります。

より高いレベルの読み込みルーチンを使用して明示的にグレースケールをRGBに変換するように指示する方がはるかに簡単です。

+0

それについては決して考えなかった!!しかし、私はそれをどうやって行うのかについては迷っています。現在のPNGを正しい形式に変換するにはどうすればいいですか? –

+0

@KieranLavelle:読み込みコードをより堅牢にして、PNG形式に調整できるようにすると良いでしょう。 –

+0

これを行うためのガイドがありますか? –

関連する問題