2017-01-02 4 views
-1

시계의 정사각형 이미지를 내가 만든 원 GL_POLYGON에 매핑하려고합니다. 현재 다음 코드를 사용하고 있습니다.텍스처 정사각형 이미지를 원에 매핑하기 OpenGl

그러나 내가 할 때 이상한 오버랩 이미지 효과가 발생합니다. 여기에 표시된대로 : enter image description here 원래 텍스처 이미지는 enter image description here이지만 모서리가 잘려서 png 형식입니다.

#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; 
} 

이 그 다음이라고합니다 아래

HERE 이미지를로드하는 데 사용되는 코드입니다 : 텍스처를 생성하는이 방법은 좌표와 이전의 대답에서했다입니다 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에게 텍스처가 픽셀 당 3 바이트 인 RGB 형식이라고 말했습니까?

그러나 모든 PNG가 형식으로 된 형식이 아닙니다. 그런 식으로되어 있습니다. 일부 PNG는 회색조입니다. 픽셀 당 1 바이트. 그리고 하위 수준의 libPNG 읽기 인터페이스를 사용했기 때문에 정확히 형식의 PNG에서 픽셀 데이터를 읽습니다. 예, 압축을 해제합니다. 그러나 PNG가 개념적으로 저장 한 것을 정확히 읽는 것입니다.

PNG가 그레이 스케일 PNG 인 경우 png_read_image을 호출하면 픽셀 당 3 바이트가 아닌 데이터를 읽을 수 있습니다. 하지만 당신은 OpenGL에게 그 데이터가 픽셀 당 3 바이트라고 말했습니다. 따라서 libPNG가 픽셀 당 1 바이트를 쓴다면 OpenGL에 잘못된 텍셀 데이터를 제공하게됩니다.

그건 나쁘군요.

libPNG의 저수준 읽기 루틴을 사용하려는 경우 이 실제로 읽는 PNG 형식을 확인하고 일치하도록 OpenGL 코드를 조정해야합니다.

더 높은 수준의 읽기 루틴을 사용하고 회색 음영을 RGB로 변환하도록 명시 적으로 말하면 훨씬 쉬울 것입니다.

+0

그것에 대해 결코 생각하지 마라 !! 그러나 나는 그것을하는 방법에 관해서는 손실이다. 현재 PNG를 올바른 형식으로 변환하려면 어떻게해야합니까? –

+0

@KieranLavelle : 로딩 코드를보다 견고하게 만들어서 PNG 형식으로 조정할 수 있다면 좋을 것입니다. –

+0

이 작업을 수행하기위한 가이드가 있습니까? –