Announcement

Collapse
No announcement yet.

In-game interfaces/terminals (Doom 3 style)

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • In-game interfaces/terminals (Doom 3 style)

    How can I use CSQC to create a terminal UI, in-game, as in Doom 3? In this thread: Inside3d Forums • View topic - CSQC GUI for DarkPlaces spike says at the end that you can "render polygons". Anyone know anything about it? I think that what I'm doing, can be done by having an array of brushes, and then writing code that changes the surface texture. As the sort of UI I want is a logic puzzle which operates on a simple uniform grid. But this is messy.

    Can't ask on inside3D, as I am awaiting administrator approval of my new account :/

  • #2
    I can't actually think of a way, but this would actually be really cool. Somebody who knows their quake C should totally reply. ;P
    twitch
    wew lad

    Comment


    • #3
      Code:
      void(string shader, vector org, vector s, vector t, string text, vector col, float alph) drawlame3dtext =
      {
      	/*the shader must be a 16*16 grid of 256 chars*/
      	vector st = draw_getimagesize(shader);
      	vector pos = org;
      	float chr;
      	float idx;
      	vector tc0,tc1,tc2,tc3;
      
      	//with GL_LINEAR sampling, the sample value is interpolated from the nearby two pixels
      	//this means that we must move the texture coord inwards by half of a pixel to avoid any bleed through into neighbouring chars
      	//(with nearest sampling, this isn't needed)
      	if (st != '0 0 0')
      	{
      		st_x = 0.5 / st_x;
      		st_y = 0.5 / st_y;
      	}
      
      	//precompute the st offset for each vertex
      	tc0_x = (0.0/16) + st_x;
      	tc1_x = (1.0/16) - st_x;
      	tc2_x = (1.0/16) - st_x;
      	tc3_x = (0.0/16) + st_x;
      	tc0_y = (0.0/16) + st_y;
      	tc1_y = (0.0/16) + st_y;
      	tc2_y = (1.0/16) - st_y;
      	tc3_y = (1.0/16) - st_y;
      
      	/*begin looks up the shader and is thus potentially expensive, fte requires it only once per batch of polygons.*/
      	R_BeginPolygon(shader);
      
      	while((chr = text[idx]))
      	{
      		idx+=1;
      
      		/*handle new lines*/
      		if (chr == '\n')
      		{
      			org += t;
      			pos = org;
      			continue;
      		}
      
      		/*skip spaces*/
      		if (chr != ' ')
      		{
      			/*its a grid, so the top-left texturecoord should be easy to calculate*/
      			/*weirdly though, qc has no (direct) modulo functionality, not even as a builtin, so this code is ugly*/
      			st_x = (chr & 15) / 16;
      			st_y = floor(chr/16) / 16;
      
      			/*plot the poly's point and emit the quad*/
      			R_PolygonVertex(pos    , st + tc0, col, alph);
      			R_PolygonVertex(pos + s, st + tc1, col, alph);
      			R_PolygonVertex(pos+s+t, st + tc2, col, alph);
      			R_PolygonVertex(pos + t, st + tc3, col, alph);
      			R_EndPolygon();
      		}
      		pos += s;
      	}
      };
      arguments:
      shader: something like 'gfx/conchars'
      org: the top-left of the text in world coords
      s: the world direction of the text's s coord (ie: v_right), scaled by the char size (in qu)
      t: the world direction of the text's t coord (ie: v_up * -1), scaled by the char size (in qu)
      text: the string you want to print. \n will act as carrage return and linebreak. no other control chars are supported.
      col: the RGB colour vector you want the text to appear.
      alph: the alpha value. probably 1, but you can use it to fade text in/out.

      notes:
      there's no support for clipping or line wrapping in this code. you'd have to write that yourself
      I wrote the code for FTE. you'll probably need to remove a couple of optimisations to get it to run in DP too.
      copy+paste into this text box seems to have fucked up my indenting. fix it yourself.
      I wrote it a while ago. deal with it.
      its single sided. if you're using fte you can use a shader to make it double sided. if you're using dp, you're fucked. in reality, you'd probably want to reverse the text order for the back side of the text anyway so single-sided is a good thing - just call it twice with the s vector inverted and the origin updated.
      you'll need to know enough csqc to determine the origin and other arguments yourself. ents or hardcoded or whatever, I don't care.

      actual text entry is also up to you. you'll need to use strcat+chr2str+substring to edit the string to add+remove chars etc as the user types.
      you might want to use stringbuffers to deal with history and text scrolling, if you need that.
      Some Game Thing

      Comment


      • #4
        Awesome, that's really useful, thanks spike. But I think I've confused us both with the word terminal. What I meant was a terminal, as in a screen or monitor in the game world, not a terminal like a shell with text input xD

        What I want, is something like a chess board, a grid of graphics that can be changed by the user. Some of the graphics will have simple animations.
        I think though, I can reverse engineer this to create a function that works with graphics? The r_polygonvertex() function blits on to the texture without using more memory? What I mean is, do I have to release the polygon's memory? Or can I just infinitely pile the graphics on top of each other without worrying about an overflow?

        Comment


        • #5
          throw as many polygons at it as you need. they'll only last a frame.
          bear in mind that this is csqc code, and will not work in ssqc.
          Some Game Thing

          Comment

          Working...
          X