Thread: Error in my logic somewhere

  1. #1
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733

    Error in my logic somewhere

    I've been learning opengl, finally managed to use index buffers correctly but having an issue with vertex management, specifically and 2nd triangle that should appear is not appearing, I get the first but not the second, when I print the vertices identified by the 2nd triangle's indices they appear to be correct, I cannot for the life of me see where I'm going wrong. I've also been posting here just in case anyone tries to direct me there, it's not the calls that are the issue, only the data being fed. I attached the whole project I'm using to learn opengl, would someone mind having a look through my code and seeing if they can spot the issue, the primary function to look at is glfwRefreshCB(), I've been using trigon instead of triangle because I have a tendency to mistype triangle as traingle. The functions of most interest besides glfwRefreshCB() are add_trigons(), find_quad/trio/pair() and add_trigon_to_index_buffers(). I may have misremembered the spelling of those functions but you get the picture.
    Attached Files Attached Files

  2. #2
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Finally managed to narrow it down to this function:

    Code:
    int list_is_taken( struct _LIST *List, uint index, int take )
    {
    	BUFF *Took = &(List->Took);
    	unsigned char *took = Took->addr, b;
    	uint i = index / CHAR_BIT;
    
    	if ( Took->have <= i )
    	{
    		print___x( errout, __FILE__, __LINE__, "index" );
    		fprintf( errout, "%s\n", "was out of range" );
    		return -1;
    	}
    
    	b = !!take;
    	b <<= (index % CHAR_BIT);
    
    	if ( take >= 0 )
    		took[i] |= b;
    
    	return !!(took[index] & b);
    }
    ...Just as I was going to post this I finally noticed what I did wrong, I used index instead of i in the return statement

  3. #3
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    I've got gospel in a about 10min, it's unlikely I'll spot the cause before then, the short of the problem is this:
    Code:
    	/* Can do in 1 loop but I like how the vectors line up this way */
    	for ( uint v = 0; v < 3; ++v )
    	{
    		Trigon.raw[v].Color = find_quad( Core, Model, quads[v].raw );
    #if 0
    	}
    
    	for ( uint v = 0; v < 3; ++v )
    	{
    #endif
    		Trigon.raw[v].Place = find_trio( Core, Model, trios[v].raw );
    	}
    enabling the code between gives different results to what I expect, since I know it must be th find_* family of functions and their respective code paths that are at fault I'll direct you here:
    floats.c * main * Lee Shallis / glEngine * GitLab
    There's not a lot of code in the file so you'll find what you're looking for fast

  4. #4
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Never mind, I gave up on the shared floats idea and just used separate buffers, somehow lost all triangles in the process though, just gonna have to check every change I made

  5. #5
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    New problem, not seeing the cause of why my byte flip misses the end (for example 0x12340000 should become 0x00001234, not 0x00123400), I know my system is using Little Endian but the results are not as I expect, here's the code (the last function is provided for usage context, for that function look for leng, Image->SpanX & Image->SpanY)
    Code:
    void flip_byte_order( void * data, size_t size )
    {
    	uchar *dst = data, *src = data + size;
    	while ( dst < src )
    	{
    		uchar tmp = *dst;
    		*dst = *src;
    		*src = tmp;
    		++dst;
    		--src;
    	}
    }
    
    void fill_at_end( void * dst, size_t dstSize, void *src, size_t srcSize )
    {
    	uchar *d = dst, *s = src;
    	if ( srcSize < dstSize )
    	{
    		while ( srcSize )
    			d[--dstSize] = s[--srcSize];
    		while ( dstSize )
    			d[--dstSize] = 0;
    	}
    	else
    	{
    		while ( dstSize )
    			d[--dstSize] = s[--srcSize];
    	}
    }
    
    void large_endian_to_local_endian( void *data, size_t size )
    {
    	intmax_t local = 0x12345678;
    	uchar *loc = (uchar*)&local;
    
    	switch ( loc[0] )
    	{
    	case 0x78: flip_byte_order( data, size ); return;
    	case 0x12: return;
    	}
    
    	/* Make it clear a failure happened */
    	memset( data, 0, size );
    	return;
    }
    
    /* TODO: Adapt this to CHAR_BIT */
    IMG_PNG * load_img_png( ALLOC *Alloc, IMG_PNG *Image, bool loop )
    {
    	BIN_FILE *BinFile = open_bin_file( &(Image->BinFile), 04 );
    	BUFF *FullImg = &(Image->FullImg);
    	IMG_PNG_ENTRY *Entry = &(Image->Entry);
    	char first_bytes[8] = {0};
    	char should_be[8] = { 0x89, 'P', 'N', 'G', '\r', '\n', 0x1A, '\n' };
    	intmax_t done, size, _leng = 0, leng = 0;
    	uint Pixels = 0, entry = 0;
    
    	Image->Pixels = 0;
    	Image->Color = 0;
    
    	if ( !BinFile )
    		return NULL;
    
    	done = copy_bin_file_region( BinFile, first_bytes, 8, loop );
    
    	if ( strncmp( first_bytes, should_be, 8 ) != 0 )
    	{
    		shut_bin_file( BinFile );
    		return NULL;
    	}
    
    	while ( (size = copy_bin_file_region( BinFile, &_leng, 4, loop )) ==  4 )
    	{
    		uint CRC = 0x12345678;
    		uchar *data, *dst, *src;
    		BUFF *Data;
    		done += size;
    
    		fill_at_end( &leng, sizeof(leng), &_leng, 4 );
    		large_endian_to_local_endian( &leng, sizeof(leng) );
    		size = leng + 8;
    		Data = buff_inc_only( Alloc, &(Entry->data), char, size );
    
    		if ( !Data )
    		{
    			shut_bin_file( BinFile );
    			return NULL;
    		}
    
    		data = Data->addr;
    
    		if ( copy_bin_file_region( BinFile, data, size, loop ) != size )
    		{
    			shut_bin_file( BinFile );
    			return NULL;
    		}
    
    		Data->used = size;
    		done += size;
    
    		for ( uint c = 0; c < 4; ++c )
    			Entry->type[c] = data[c];
    		Entry->type[4] = 0;
    
    		data += 4;
    		src = data + leng;
    		dst = (uchar*)&(Entry->CRC);
    		for ( CRC = 0; CRC < 4; ++CRC )
    			dst[CRC] = src[CRC];
    
    		fprintf( errout, "%s, index %u\n", Entry->type, entry );
    
    		if ( strcmp( Entry->type, "IHDR" ) == 0 )
    		{
    			fill_at_end( &(Image->SpanX), sizeof(Image->SpanX), data + 0, 4 );
    			fill_at_end( &(Image->SpanY), sizeof(Image->SpanY), data + 4, 4 );
    			large_endian_to_local_endian( &(Image->SpanX), sizeof(Image->SpanX) );
    			large_endian_to_local_endian( &(Image->SpanY), sizeof(Image->SpanY) );
    			Image->Depth				= data[8];
    			Image->Color				= data[9];
    			Image->CompressionMethod	= data[10];
    			Image->FilterMethod			= data[11];
    			Image->InterlaceMethod		= data[12];
    
    			Image->Pixels = (Image->SpanX) * (Image->SpanY);
    			FullImg = img_png_fullimg( Alloc, Image, Image->Pixels );
    		}
    		else if ( strcmp( Entry->type, "IDAT" ) == 0 )
    		{
    			Pixels += leng;
    			FullImg = img_png_fullimg( Alloc, Image, Pixels );
    		}
    		else if ( strcmp( Entry->type, "PLTE" ) == 0 )
    		{
    			BUFF * Palette = buff_inc_only( Alloc, &(Image->Palette), ulong, leng );
    			uint pused = 0, cused = 0;
    			uint colorsize = 1;
    			uchar *colors;
    
    			if ( !Palette )
    			{
    				shut_bin_file( BinFile );
    				return NULL;
    			}
    
    			switch ( Image->Color )
    			{
    				case IMG_PNG_CLUT_TRUECOLORA:
    				case IMG_PNG_CLUT_PALLETEPOS:
    				{
    					colorsize = 4;
    					break;
    				}
    				case IMG_PNG_CLUT_TRUECOLOR:
    				{
    					colorsize = 3;
    					break;
    				}
    				case IMG_PNG_CLUT_GREYSCALEA:
    				{
    					colorsize = 2;
    					break;
    				}
    			}
    
    			colors = Palette->addr;
    			memset( colors, 0, Palette->size );
    
    			for ( ; cused < leng; cused += colorsize, pused += sizeof(ulong) )
    				memcpy( colors + pused, data + cused, colorsize );
    
    			Palette->used = pused / sizeof(ulong);
    		}
    		else if ( strcmp( Entry->type, "IEND" ) == 0 )
    			break;
    		else
    		{
    			for ( uint chunk = 0; chunk < IMG_PNG_CHUNK_COUNT; ++chunk )
    			{
    				if ( strcmp( Entry->type, ImageChunksPNG[chunk] ) == 0 )
    				{
    					BUFF *Buffer = buff_inc_only( Alloc, &(Image->Chunks[chunk]), uchar, leng );
    
    					if ( !Buffer )
    					{
    						shut_bin_file( &(Image->BinFile) );
    						return NULL;
    					}
    
    					memset( Buffer->addr, 0, Buffer->size );
    					memcpy( Buffer->addr, Entry->data.addr, leng );
    					break;
    				}
    			}
    		}
    
    		if ( !FullImg )
    		{
    			shut_bin_file( BinFile );
    			return NULL;
    		}
    	}
    
    	Image->Pixels = Pixels = (Image->Pixels < Pixels) ? Pixels : Image->Pixels;
    	Image->FullImg.used = Image->Pixels;
    
    	switch ( Image->Color )
    	{
    		case IMG_PNG_CLUT_TRUECOLOR:
    		{
    			break;
    		}
    		case IMG_PNG_CLUT_PALLETEPOS:
    		{
    			break;
    		}
    		case IMG_PNG_CLUT_TRUECOLORA:
    		{
    			break;
    		}
    		case IMG_PNG_CLUT_GREYSCALEA:
    		{
    			break;
    		}
    	}
    
    	shut_bin_file( BinFile );
    	return Image;
    }

  6. #6

  7. #7
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Before I go blaming my PNG loading function (which surely has it's own bugs) have I done anything wrong for printing in PPM format?
    Code:
    int main()
    {
    	PROC *Proc;
    	//TASK *Builder, *Painter;
    	GLFWwindow *window = NULL;
    	IMG_PNG Image = {0};
    	ALLOC *Alloc = &(core.Alloc);
    	ulong *colours;
    	core.Span.x = 640;
    	core.Span.y = 480;
    	Alloc->alloc = defaultAlloc;
    
    	if ( !setup_img_png( Alloc, &Image, "./PNG-Gradient_hex.png" ) )
    	{
    		fprintf( errout, "Failed PNG setup\n" );
    		return EXIT_FAILURE;
    	}
    
    	if ( !load_img_png( Alloc, &Image, true ) )
    	{
    		fprintf( errout, "Failed PNG load\n" );
    		empty_img_png( Alloc, &Image );
    		return EXIT_FAILURE;
    	}
    
    	printf("P3\n%u %u\n255\n", Image.SpanX, Image.SpanY );
    
    	colours = Image.FullImg.addr;
    	for ( uint i = 0; i < Image.FullImg.used; ++i )
    	{
    		ulong colour = *(colours + i);
    		ulong r = (colour & 0xFF000000) >> 24;
    		ulong g = (colour & 0x00FF0000) >> 16;
    		ulong b = (colour & 0x0000FF00) >> 8;
    		printf( "%s%lu %lu %lu", i ? ((i % Image.SpanX) ? " " : "\n") : "", r, g, b );
    	}
    
    	empty_img_png( Alloc, &Image );
    	return EXIT_SUCCESS;

  8. #8
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    What file extension should an "PPM format" have?
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  9. #9
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    literally "*.ppm"

    Edit: Was using this when I wrote that code: PPM Format Specification
    Was planning to use eog to check the image comes out right before I go checking the other details that need more than the palette, I also don't know what size the indices are supposed to be so if you know that I would appreciate knowing, I'm assuming their big endian like everything else I've found so far

  10. #10
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Never mind, forgot that I was printing the read chunks too, that got in the resulting ppm, when I removed that I got an image, just not sure if I was writing the colours correctly, gonna do my daily reading of god's word before I investigate the reason for an image mismatch, if anyone cares to try looking themselves here's the function:
    Code:
    IMG_PNG * load_img_png( ALLOC *Alloc, IMG_PNG *Image, bool loop )
    {
    	BIN_FILE *BinFile = open_bin_file( &(Image->BinFile), 04 );
    	IMG_PNG_ENTRY *Entry = &(Image->Entry);
    	BUFF *FullImg = &(Image->FullImg), *Data = &(Entry->data), *Palette;
    	uchar *data;
    	char first_bytes[8] = {0};
    	char should_be[8] = { 0x89, 'P', 'N', 'G', '\r', '\n', 0x1A, '\n' };
    	intmax_t done, size, _leng = 0, leng = 0;
    	uint Pixels = 0, entry = 0;
    	ulong *targets, *colours;
    
    	Image->Pixels = 0;
    	Image->Color = 0;
    
    	if ( !BinFile )
    		return NULL;
    
    	done = copy_bin_file_region( BinFile, first_bytes, 8, loop );
    
    	if ( strncmp( first_bytes, should_be, 8 ) != 0 )
    	{
    		shut_bin_file( BinFile );
    		return NULL;
    	}
    
    	while ( (size = copy_bin_file_region( BinFile, &_leng, 4, loop )) ==  4 )
    	{
    		uint CRC = 0x12345678;
    		uchar *dst, *src;
    		done += size;
    
    		fill_at_end( &leng, sizeof(leng), &_leng, 4 );
    		large_endian_to_local_endian( &leng, sizeof(intmax_t) );
    		size = leng + 8;
    		Data = buff_inc_only( Alloc, Data, char, size );
    
    		if ( !Data )
    		{
    			shut_bin_file( BinFile );
    			return NULL;
    		}
    
    		data = Data->addr;
    		_leng = copy_bin_file_region( BinFile, data, size, loop );
    
    		if ( _leng != size )
    		{
    			print___x( errout, __FILE__, __LINE__, "[ERROR]" );
    			fprintf( errout, "0x%016jX vs 0x%016jX\n", _leng, size );
    			shut_bin_file( BinFile );
    			return NULL;
    		}
    
    		Data->used = size;
    		done += size;
    
    		for ( uint c = 0; c < 4; ++c )
    			Entry->type[c] = data[c];
    		Entry->type[4] = 0;
    
    		data += 4;
    		src = data + leng;
    		dst = (uchar*)&(Entry->CRC);
    		for ( CRC = 0; CRC < 4; ++CRC )
    			dst[CRC] = src[CRC];
    
    		fprintf( errout, "%s, index %u\n", Entry->type, entry );
    
    		if ( strcmp( Entry->type, "IHDR" ) == 0 )
    		{
    			fill_at_end( &(Image->SpanX), sizeof(Image->SpanX), data + 0, 4 );
    			fill_at_end( &(Image->SpanY), sizeof(Image->SpanY), data + 4, 4 );
    			large_endian_to_local_endian( &(Image->SpanX), sizeof(Image->SpanX) );
    			large_endian_to_local_endian( &(Image->SpanY), sizeof(Image->SpanY) );
    			Image->Depth				= data[8];
    			Image->Color				= data[9];
    			Image->CompressionMethod	= data[10];
    			Image->FilterMethod			= data[11];
    			Image->InterlaceMethod		= data[12];
    
    			Image->Pixels = (Image->SpanX) * (Image->SpanY);
    			FullImg = img_png_fullimg( Alloc, Image, Image->Pixels );
    		}
    		else if ( strcmp( Entry->type, "IDAT" ) == 0 )
    		{
    			Pixels += leng;
    			FullImg = img_png_fullimg( Alloc, Image, Pixels );
    		}
    		else if ( strcmp( Entry->type, "PLTE" ) == 0 )
    		{
    			Palette =
    				setup_palette( Alloc, &(Image->Palette), Data, Image->Color, 4 );
    
    			if ( !Palette )
    			{
    				shut_bin_file( BinFile );
    				return NULL;
    			}
    		}
    		else if ( strcmp( Entry->type, "IEND" ) == 0 )
    			break;
    		else
    		{
    			for ( uint chunk = 0; chunk < IMG_PNG_CHUNK_COUNT; ++chunk )
    			{
    				if ( strcmp( Entry->type, ImageChunksPNG[chunk] ) == 0 )
    				{
    					BUFF *Buffer = buff_inc_only( Alloc, &(Image->Chunks[chunk]), uchar, leng );
    
    					if ( !Buffer )
    					{
    						shut_bin_file( &(Image->BinFile) );
    						return NULL;
    					}
    
    					memset( Buffer->addr, 0, Buffer->size );
    					memcpy( Buffer->addr, Entry->data.addr, leng );
    					break;
    				}
    			}
    		}
    
    		if ( !FullImg )
    		{
    			shut_bin_file( BinFile );
    			return NULL;
    		}
    
    		++entry;
    	}
    
    	shut_bin_file( BinFile );
    	Image->Pixels = Pixels = (Image->Pixels < Pixels) ? Pixels : Image->Pixels;
    	Data = buff_inc_only( Alloc, Data, uchar, FullImg->size );
    
    	if ( !Data )
    		return NULL;
    
    	/* We still need to convert the indices to colours, to do that we first
    	 * need to shift the indices elsewhere, conveniently we no longer need to
    	 * temporarily store chunk data so now we go ahead and reuse that buffer
    	 * for the indices we need to move */
    	data = Data->addr;
    	memcpy( data, FullImg->addr, FullImg->size );
    	Data->used = Pixels;
    
    	/* Make sure the size was correct, don't want buffer overflow attacks */
    	FullImg = buff_inc_only( Alloc, FullImg, ulong, Pixels );
    
    	if ( !FullImg )
    		return NULL;
    
    	Palette = &(Image->Palette);
    	colours = Palette->addr;
    	targets = FullImg->addr;
    
    	for ( size_t s = 0, d = 0; s < Pixels; s += 4, ++d )
    	{
    		ulong *target = targets + d, index = 0;
    		uchar *source = data + s;
    		fill_at_end( &index, sizeof(ulong), source, 4 );
    		large_endian_to_local_endian( &index, sizeof(ulong) );
    		*target = (index < Palette->used) ? *(colours + index) : 0;
    	}
    
    	FullImg->used = Pixels;
    
    	return Image;
    }
    And for reference png.h:
    Code:
    #ifndef IMG_PNG_H
    #define IMG_PNG_H
    
    #include "common.h"
    
    typedef struct _IMG_PNG_ENTRY
    {
    	uint CRC;
    	char type[5];
    	BUFF data;
    } IMG_PNG_ENTRY;
    
    #define IMG_PNG_CLUT_GREYSCALE 0
    #define IMG_PNG_CLUT_TRUECOLOR 2
    #define IMG_PNG_CLUT_PALLETEPOS 3
    #define IMG_PNG_CLUT_GREYSCALEA 4
    #define IMG_PNG_CLUT_TRUECOLORA 6
    
    typedef enum _IMG_PNG_CHUNK_TYPE
    {
    	IMG_PNG_CHUNK_bKGD,
    	IMG_PNG_CHUNK_cHRM,
    	IMG_PNG_CHUNK_dSIG,
    	IMG_PNG_CHUNK_eXIf,
    	IMG_PNG_CHUNK_iCCP,
    	IMG_PNG_CHUNK_iTXt,
    	IMG_PNG_CHUNK_pHYs,
    	IMG_PNG_CHUNK_sBIT,
    	IMG_PNG_CHUNK_sPLT,
    	IMG_PNG_CHUNK_sRGB,
    	IMG_PNG_CHUNK_sTER,
    	IMG_PNG_CHUNK_tEXt,
    	IMG_PNG_CHUNK_tRNS,
    	IMG_PNG_CHUNK_zTXt,
    	IMG_PNG_CHUNK_COUNT
    } IMG_PNG_CHUNK_TYPE;
    
    char const * const img_png_chunk_desc( IMG_PNG_CHUNK_TYPE type );
    
    typedef struct _IMG_PNG
    {
    	uint		SpanX;
    	uint		SpanY;
    	uchar		Depth;
    	uchar		Color;
    	uchar		CompressionMethod;
    	uchar		FilterMethod;
    	uchar		InterlaceMethod;
    	time_t		TimeLastChanged;
    	float		Gama;
    	BIN_FILE	BinFile;
    	IMG_PNG_ENTRY Entry;
    	BUFF		Palette;
    	BUFF		AlternativePalette;
    	BUFF		Chunks[IMG_PNG_CHUNK_COUNT];
    	uint		Pixels;
    	BUFF		FullImg;
    } IMG_PNG;
    
    IMG_PNG *
    	setup_img_png( ALLOC *Alloc, IMG_PNG *Image, tch const * const path );
    IMG_PNG *
    	load_img_png( ALLOC *Alloc, IMG_PNG *Image, bool loopUntilRdAll );
    void
    	empty_img_png( ALLOC *Alloc, IMG_PNG *Image );
    
    #endif
    All the parameters of BUFF besides 'have' are visible, have is set to size / sizeof(T) so ignore that for this case

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compile error? Logic error? Syntax Error? Please help
    By Khody Afkhami in forum C Programming
    Replies: 4
    Last Post: 10-11-2014, 01:36 AM
  2. logic error
    By gameover6005 in forum C Programming
    Replies: 2
    Last Post: 03-30-2013, 12:47 PM
  3. I think it's logic error
    By c++ in forum C++ Programming
    Replies: 3
    Last Post: 04-23-2009, 08:02 PM
  4. logic Error
    By asmaa in forum C++ Programming
    Replies: 4
    Last Post: 02-13-2009, 10:58 PM
  5. logic error
    By sscook69 in forum C++ Programming
    Replies: 5
    Last Post: 04-07-2002, 06:00 PM

Tags for this Thread