Problem mit statischer Klassenfunktion



  • Ich habe eine als static deklarierte Memberfunktion

    void GLButton::load_textures(char *fl_tex_rel_lft, char *fl_tex_rel_rgt, char *fl_tex_rel_mdl,
    				  char *fl_tex_psh_lft, char *fl_tex_psh_rgt, char *fl_tex_psh_mdl)
    {
    	uint16_t hgt1, hgt2, hgt3, hgt4, hgt5;
    	uint16_t wth1, wth2, wth3;
    
    	tex_rel_lft = png_load_texture(fl_tex_rel_lft, wth_tex_lft, sz.y);
    	tex_rel_rgt = png_load_texture(fl_tex_rel_rgt, wth_tex_rgt, hgt1);
    	tex_rel_mdl = png_load_texture(fl_tex_rel_mdl, wth_tex_mdl, hgt2);
    
    	tex_psh_lft = png_load_texture(fl_tex_rel_lft, wth1, hgt3);
    	tex_psh_rgt = png_load_texture(fl_tex_rel_rgt, wth2, hgt4);
    	tex_psh_mdl = png_load_texture(fl_tex_rel_mdl, wth3, hgt5);
    
    	printf("%ux%u\n",wth_tex_lft, sz.y);
    	printf("%ux%u\n",wth_tex_rgt, hgt1);
    	printf("%ux%u\n",wth_tex_mdl, hgt2);
    	printf("%ux%u\n",wth1, hgt3);
    	printf("%ux%u\n",wth2, hgt4);
    	printf("%ux%u\n",wth3, hgt5);
    
    }
    

    Hierbei sind

    wth_tex_lft
    wth_tex_mdl
    wth_tex_rgt
    sz
    

    als static deklarierte Membervariablen

    Die Funktion wird in meinem Quelltext insgesamt nur einmal aufgerufen und ich bekomme dabei folgende Ausgabe:

    40x40
    40x0
    40x0
    0x0
    0x0
    40x40
    

    Eigentlich sollte überall 40x40 herauskommen. Wenn ich die Variablen hgt1, hgt2, hgt3, ... und wth1, wth2 und wth3 als static deklariere bekomme ich das gewünschte Ergebniss, warum?

    static	uint16_t hgt1, hgt2, hgt3, hgt4, hgt5;
    static	uint16_t wth1, wth2, wth3;
    
    40x40
    40x40
    40x40
    40x40
    40x40
    40x40
    


  • 😕 DU hast die Variablen doch gar net initialisiert, da kommt wohl nie 40 raus. Du musst =40 dazuschreiben.



  • out schrieb:

    😕 DU hast die Variablen doch gar net initialisiert, da kommt wohl nie 40 raus. Du musst =40 dazuschreiben.

    Vielleicht werden sie per Referenz an png_load_texture übergeben?

    Man weiß zu wenig, um hier sinnvoll antworten zu können.



  • Die Variablen initialisieren macht die Funktion

    GLuint png_load_texture(const char *file, uint16_t &width, uint16_t &height)
    {
    	png_byte header[8];
    
    	FILE *fp = fopen(file, "rb");
    	if (fp == 0)
    	{
    		perror(file);
    		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);
    		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;
    
    	// get info about png
    	png_get_IHDR(png_ptr, info_ptr, (png_uint_32*)&width, (png_uint_32*)&height, &bit_depth, &color_type,
    		NULL, NULL, NULL);
    
    	// 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 * 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(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 < height; i++)
    	{
    		row_pointers[height - 1 - i] = image_data + i * rowbytes;
    	}
    
    	// read the png into image_data through row_pointers
    	png_read_image(png_ptr, row_pointers);
    
    	// Generate the OpenGL texture object
    	GLuint texture;
    	glGenTextures(1, &texture);
    	glBindTexture(GL_TEXTURE_2D, texture);
    	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image_data);
    	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    
    	// clean up
    	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
    	free(image_data);
    	free(row_pointers);
    	fclose(fp);
    	return texture;
    }
    


  • Falsches Board, übrigens.

    (png_uint_32*)&width

    AFAICS Ganz doofe Idee. width ist doch nur 16 Bit groß.



  • rejak schrieb:

    GLuint png_load_texture(const char *file, uint16_t &width, uint16_t &height)
    	// get info about png
    	png_get_IHDR(png_ptr, info_ptr, (png_uint_32*)&width, (png_uint_32*)&height, &bit_depth, &color_type,
    		NULL, NULL, NULL);
    

    Na das hast du dir wohl ein bisschen zu einfach vorgestellt. Einfach mal nach png_uint_32* casten und auf ein Wunder hoffen? Nein, das musst du anders lösen, z.B.

    png_uint32 tempwidth, tempheight;
      png_get_IHDR(png_ptr, info_ptr, &tempwidth, &tempheight, &bit_depth, &color_type, NULL, NULL, NULL);
      height = static_cast<uint16_t>(tempheight);
      width = static_cast<uint16_t>(tempwidth);
    

Anmelden zum Antworten