Page 1 of 2 12 LastLast
Results 1 to 10 of 17
  1. #1
    Crap Cracker glVertex3f's Avatar
    Join Date
    Jun 2004
    Location
    Under the Sea
    Posts
    164

    DirectX and Chip8

    I know alot of you did your chip8 emulators with directX. My question is what is a good way to draw the "pixels" for a Chip8 emulator.



    The way I tried was extremely slow and I figure that something this simple, I dont need to use the camera stuff.

    Hers how I was doing it
    Code:
    void C8video::RenderScreen ()
    {
    
    	gD3D->Begin ();
    	gD3D->ClearColor ( 0xFF000000 );
    	
    	for ( float x = 0; x < max_width; x++ ) {
    
    		for ( float y = 0; y < max_height; y++ ) {
    
    			
    			if ( Display [ static_cast <int> ( x ) + ( static_cast <int> ( y ) * 
    				static_cast <int> ( max_width ) ) ] != 0 ) {
    			  
    				gD3D->DrawSquare ( x, y, pixel_width, pixel_height, 0xFFFFFFFF );
    
    			}
    
    			else
    				gD3D->DrawSquare ( x, y, pixel_width, pixel_height, 0xFF000000 );
    
    		}
    
    	}
    
    	gD3D->End ();
    
    }
    Here is DrawSquare
    Code:
    void D3Dclass::DrawSquare ( float posx, float posy, float width, float height, DWORD color )
    {
    
    	DxVertex temp_square [] = {
    
    		{   posx * width          ,   posy * height           , 1.0f, 1.0f, color },
    		{ ( posx * width ) + width,   posy * height           , 1.0f, 1.0f, color },
    		{   posx * width          , ( posy * height ) + height, 1.0f, 1.0f, color },
    		{ ( posx * width ) + width, ( posy * height ) + height, 1.0f, 1.0f, color },
    
    	};
    
    	Render ( temp_square, 4 );
    
    }
    where DxVertex is like so
    Code:
    struct DxVertex
    {
    
    	float x, y, z, w;
    
    	DWORD color;
    
    };
    I am very new to directX and cant seem to find the right answers anywhere.
    Last edited by glVertex3f; September 27th, 2004 at 07:52.


    • Advertising

      advertising
      EmuTalk.net
      has no influence
      on the ads that
      are displayed
        
       

  2. #2
    ????????????????????????? Doomulation's Avatar
    Join Date
    Nov 2001
    Location
    ????????????????
    Posts
    8,780
    The methods you use is unknown to me. But that's maybe because of a diffrent version.
    In any case, I drew my pixels using two triangles. And I left my source on the forum too, so you may look up in the source if you wish.
    It also seemed like the vertexes seemed to slow it down very drastically, so I basically rendered the data on-the-fly without any vertex buffers.
    Atashi wa juu-yon-sai no onna no ko! Atashi no namae wa Miizuki. Yurushiku ne!
    Nani? Atashi o shinjirimasen desu ka? Baka!
    "You're all doomed! Doomed, I say! Hehe... are we approaching the end of the world?"

    shikata ga kaite aru - "the instructions are written above"
    Need to download GoodN64 or instructions to use it? Need to check if it's a good or bad rom?
    Download: Glide64 | Hacktarux's wrapper

  3. #3
    Crap Cracker glVertex3f's Avatar
    Join Date
    Jun 2004
    Location
    Under the Sea
    Posts
    164
    Oh yeah, might have helped if I posted the actual render code

    Code:
    bool D3Dclass::Render ( DxVertex *vert_list, int num_verts )
    {
    
    	int vert_size = sizeof ( DxVertex ) * num_verts;
    
    	IDirect3DVertexBuffer9 *VertexBuffer;
    
    	HRESULT result = D3DDevice->CreateVertexBuffer ( vert_size, 0, DxVertexType, 
    													 D3DPOOL_DEFAULT, &VertexBuffer, NULL );
    
    	if ( result != D3D_OK ) return false;
    
    	void *verts = NULL;
    
    	result = VertexBuffer->Lock ( 0, 0, (void**)&verts, D3DLOCK_DISCARD );
    
    	if ( result != D3D_OK ) {
    
    		VertexBuffer->Release ();
    		return false;
    
    	}
    
    	memcpy ( verts, vert_list, vert_size );
    
    	VertexBuffer->Unlock ();
    
    	D3DDevice->SetStreamSource ( 0, VertexBuffer, 0, sizeof ( DxVertex ) );
    	D3DDevice->SetFVF ( DxVertexType );
    	D3DDevice->DrawPrimitive ( D3DPT_TRIANGLESTRIP, 0, 2 );
    
    	VertexBuffer->Release ();
    
    	return true;
    
    }
    And when I say slow I mean CRAWLING. COMPLETELY unplayable.
    So I know im doing something seriously wrong.

    And I did look at your source but I am so new to DirectX I cant really understand what you did. I will continue to look into it.

  4. #4
    EmuTalk Member
    Join Date
    Feb 2003
    Location
    germany
    Posts
    11
    you set up your whole vertex buffer for every (chip8)pixel you are drawing.
    you could use "DrawPrimitiveUP" instead of DrawPrimitive ... i think it would be a lot faster if you want to access every single pixel.
    it is NOT good to use DrawPrimitiveUP if you need to render static goemetry or large amounts of vertices. but in your case : just use it and test if it's faster.
    if you look into the SDK docs and you understand what DrawPrimitiveUP does you will know how to use it ;-)

  5. #5
    ????????????????????????? Doomulation's Avatar
    Join Date
    Nov 2001
    Location
    ????????????????
    Posts
    8,780
    Well mate, see there's a lot of optimizations that can be done. DrawPrimitiveUP is probably the best. Lookie at my source and you'll see how I increased speed a little =)

    EDIT:
    Okay, first make sure you don't allocate new memory for each array, as allocating large heaps of memory over and over is time consuming. A hard learned lesson it was.
    Second, here's little of my code:

    Code:
    void RenderScreen(int* _pixels,int number)
    {
    	if (bExit) return;
    	//CUSTOMVERTEX vFiller[4];
    	//CUSTOMVERTEX vFiller2[4];
    	int index = 0;
    	HRESULT hr;
    	
    	// Initialize the vertices that will fill out the borders of the screen
    	index = InitScreenVertices(vScreen,_pixels,number);
    	//InitFillerVertices(vFiller,vFiller2);
    
    	if (index > 0)
    	{
    		pd3dDevice->BeginScene();
    		pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,0,1.0f,0);
    		hr = pd3dDevice->SetStreamSource(0, pVB, 0, sizeof(CUSTOMVERTEX));
    		hr = pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
    		hr = pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST,index/3,vScreen,sizeof(CUSTOMVERTEX));
    		pd3dDevice->EndScene();
    
    		pd3dDevice->Present(0,0,0,0);
    	}
    }
    Though I don't know if SetStreamSource is necessary.

    And my vertices function:
    Code:
    inline int InitScreenVertices(CUSTOMVERTEX* pVertices,int* pixels,int number)
    {
    	int offsetx = 0;
    	int index = 0;
    	int xvalue = bExtendedScreen ? 128 : 64;
    	int yvalue = bExtendedScreen ? 64 : 32;
    
    	//CUSTOMVERTEX* vertices = new CUSTOMVERTEX[ xvalue * yvalue * 3 ];
    	for (int y=0; y < yvalue; y++)
    	{
    		for (int x=0; x < xvalue; x++)
    		{
    			if (screen[x+y*xvalue] != 1) continue;
    			if (bMonitorDrawOpcode)
    			{
    				char msg[100];
    				wsprintf(msg,"Pixel found at x: %i, y: %i.\n",x,y);
    				DEBUGTRACE(msg);
    			}
    
    #pragma warning(disable: 4244)
    			pVertices[index].x = x*XMultiplier;
    			pVertices[index].y = BORDER1_END + (y*YMultiplier);
    			pVertices[index+1].x = x*XMultiplier+XMultiplier;
    			pVertices[index+1].y = BORDER1_END + (y*YMultiplier);
    			pVertices[index+2].x = x*XMultiplier;
    			pVertices[index+2].y = BORDER1_END + (y*YMultiplier+YMultiplier);
    
    			pVertices[index+3].x = x*XMultiplier+XMultiplier;
    			pVertices[index+3].y = BORDER1_END + (y*YMultiplier);
    			pVertices[index+4].x = x*XMultiplier+XMultiplier;
    			pVertices[index+4].y = BORDER1_END + (y*YMultiplier+YMultiplier);
    			pVertices[index+5].x = x*XMultiplier;
    			pVertices[index+5].y = BORDER1_END + (y*YMultiplier+YMultiplier);
    #pragma warning(default: 4244)
    
    			for (int i=0; i<6; i++)
    			{
    				pVertices[index+i].z = 1.0;
    				pVertices[index+i].rhw = 1.0;
    				pVertices[index+i].color = dwPixelColor;
    			}		
    			index += 6;
    		}
    	}
    	//*pVertices = vertices;
    	return index;
    }
    Now as you can see, just fill your vertices and use DrawPrimitiveUP for rendering.
    Good luck.
    Last edited by Doomulation; September 28th, 2004 at 07:54.
    Atashi wa juu-yon-sai no onna no ko! Atashi no namae wa Miizuki. Yurushiku ne!
    Nani? Atashi o shinjirimasen desu ka? Baka!
    "You're all doomed! Doomed, I say! Hehe... are we approaching the end of the world?"

    shikata ga kaite aru - "the instructions are written above"
    Need to download GoodN64 or instructions to use it? Need to check if it's a good or bad rom?
    Download: Glide64 | Hacktarux's wrapper

  6. #6
    EmuTalk Member
    Join Date
    Feb 2003
    Location
    germany
    Posts
    11
    @doom: you don't need SetStreamSource if you just use DrawPrimitiveUP.
    and if your vertex-format does not change you even don't need to call SetFVF every frame.
    there are very much ways to draw the chip8 pixels in direct3d ;-)

    cya dwx

  7. #7
    ????????????????????????? Doomulation's Avatar
    Join Date
    Nov 2001
    Location
    ????????????????
    Posts
    8,780
    Indeed I don't have to call SetFVF on every frame, but it doesn't incur performance hit and last I tried it wouldn't accept the vertices if I didn't
    Atashi wa juu-yon-sai no onna no ko! Atashi no namae wa Miizuki. Yurushiku ne!
    Nani? Atashi o shinjirimasen desu ka? Baka!
    "You're all doomed! Doomed, I say! Hehe... are we approaching the end of the world?"

    shikata ga kaite aru - "the instructions are written above"
    Need to download GoodN64 or instructions to use it? Need to check if it's a good or bad rom?
    Download: Glide64 | Hacktarux's wrapper

  8. #8
    Emu Author
    Join Date
    Apr 2003
    Posts
    248
    Rendering every pixel of your emulated display as a separate polygon seems a little overkill, don't you think?
    A better approach in most cases would be to copy your display to a texture and draw a single quad mapped with it..

  9. #9
    EmuTalk Member
    Join Date
    Feb 2003
    Location
    germany
    Posts
    11
    ... it's just 64x32 pixels. and they can just be set to ON or OFF. also chip8 only has to render the screen if an opcode changes is (only 1 or 2 opcodes can do that).
    so worst case you have to render 64x32(=2048) quads.

    but like ector said : i would use a textur or something similar.
    in my little emulator i only use a GDI call (StretchDIBIts) to show my buffer, which is fast enough and only one call compared to the whole direct3d stuff ;-)

    cya dwx

  10. #10
    Crap Cracker glVertex3f's Avatar
    Join Date
    Jun 2004
    Location
    Under the Sea
    Posts
    164
    Yeah I ve been wanting to learn DirectX for a long time so I figured I would make another Chip8 emulator and use it.

    My biggest slowdown was creating/setting up the vertex buffer every call. I do stupid stuff like that.

    Have any of you had problems creating the client area in a directX app? When I run my emu, a good bit of the bottom is "below" where it needs to be.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •