Skip to content
View in the app

A better way to browse. Learn more.

Tip.It Forum

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Veiva

Members
  • Joined

  • Last visited

Everything posted by Veiva

  1. Nope! I got it from the data sent to the GPU via OpenGL. It's a very lossy process.
  2. Veiva replied to Leoo's topic in Off-Topic
    But w won't be 1 after a perspective transformation. Here: Let P be your point. Let P` be your point post-transformation. Let M be the combined model-view-projection transformation. Let S be the normalized device coordinates. First, transform P: P` = M * PThen compute S: Sx = P`x / P`w Sy = P`y / P`w Sz = P`z / P`w See: https://www.khronos.org/opengl/wiki/GluProject_and_gluUnProject_code Here's my projection method used in a MoonScript math library I made: project: (point, view, projection, viewport) -> Promise.keep("point", Promise.IsClass(point, Vector)) Promise.keep("view", Promise.IsClass(view, Matrix)) Promise.keep("projection", Promise.IsClass(projection, Matrix)) Promise.keep("viewport", Promise.IsTable(viewport)) Promise.keep("viewport[1]", Promise.IsNumber(viewport[1])) Promise.keep("viewport[2]", Promise.IsNumber(viewport[2])) Promise.keep("viewport[3]", Promise.IsNumber(viewport[3])) Promise.keep("viewport[4]", Promise.IsNumber(viewport[4])) view_projection = projection * view transformed_point, w = view_projection\perspective_transform(point) transformed_point *= Vector(1 / w) return Vector( (transformed_point.x * 0.5 + 0.5) * viewport[3] + viewport[1], (transformed_point.y * 0.5 + 0.5) * viewport[4] + viewport[2], (1 + transformed_point.z) * 0.5)
  3. Veiva replied to Leoo's topic in Off-Topic
    Do you divide projected_point.xyz by projected_point.w?
  4. Veiva replied to Leoo's topic in Off-Topic
    I created an in-process OpenGL tracing module called ARDEN. It's composed of Touchstone, which generates the OpenGL trace; Jaques, which hooks the OpenGL functions; and Rosalind, which generates low-level rendering events relevant to RuneScape, like "draw_gui" or "draw_item_icon_model." I then created a module called WALDEN to generate game state from the low-level Rosalind events. See, RuneScape's rendering is a bit odd at times. A single animated model (e.g., NPC, player, fire) may be split into a few draw calls. This isn't determininistic. There's other quirks I've encountered too. So I created Chomsky--thus far the only WALDEN component. It pieces together what events correspond to what game state. For example, it sorts skinned model draws by position to piece together individual animated models. Luckily, GUI stuff is much simpler. At the end of a frame, the game world is transferred into the default back buffer, and then the GUI elements are drawn. Essentially, I compose a GUI element stream: a collection of quads with their associated texture hashes (more like fingerprints, since I apply some heuristics to generate most-certainly unique 16-byte value represents certain visual aspects of the texture). I have to manually identify textures, but that's easy enough using my tool, Poltergeist. I created a texture dictionary resources, which assigns various metadata (a value, like a name; tags; and key-value data pairs) to a texture hash. Example: With a DSL I created (boringly named "GPD", for "GUI Parser Definitions"), I can apply a series of matches on the GUI element stream to construct a high-level representation of the GUI. For example, here's the chat panel GPD: chat-panel-content[panel-content]: { .background: repeat image panel-background; .buttons[]: widget button[chat-button]; .splitter: { .bottom: image chat-panel-border; .top: image chat-panel-border; }; .display-name: text(shadowed: true) small-font; .quick-chat-button: widget button[chat-button]; .prompt: text(shadowed: true) small-font; optional { .log[]: text(shadowed: true, break_on_newline: false) small-font; }; .scroll-bar: widget button[vertical-scroll-bar]; }; The language is pretty simple. Essentially, you have fundamental match statements: text, image, size, color, and widget. You can compose multiple statements together (using curly braces). The root groups are called widgets (like chat-panel-content above). Widgets can have fields (which can also have fields, see ".splitter" above). Generally, a match statement assigns the GUI element to the field or widget on success. Failed matches result in the parent node terminating. You can also apply decorators to statements. Decorators modify the behavior of a match statement. For example, the "invert" decorators does what it says on the tin: inverts the result of a match statement. The "peek" statement doesn't change the position in the element stream; the "find" decorator attempts a match, and if that fails, increments the position in the stream and tries again; etc. You can chain decorators: "optional skip repeat image *[icon];" would consume all images with the 'icon' tag, for example. The grammar is self-explanatory: [hide] # "GUI Pattern Definition", or GPD for short. IDENTIFIER := [A-Za-z][A-Za-z0-9_-]* NUMBER_LITERAL := [0-9]* COLOR_LITERAL := '#' [0-9A-Fa-f]+ LEFT_PARENTHESIS := '(' RIGHT_PARENTHESIS := ')' LEFT_CURLY := '{' RIGHT_CURLY := '}' LEFT_BRACKET := '[' RIGHT_BRACKET := ']' FIELD_PREFIX := '.' COMMA := ',' COLON := ':' SEMICOLON := ';' WILDCARD := '*' parameter := IDENTIFIER COLON IDENTIFIER parameter-list := LEFT_PARENTHESIS parameter ( COMMA parameter )* RIGHT_PARENTHESIS find-decorator := 'find' repeat-decorator := 'repeat' parameter-list? expression optional-decorator := 'optional' expression skip-decorator := 'skip' expression peek-decorator := 'peek' expression invert-decorator := 'invert' expression rewind-decorator := 'rewind' expression expression := ( decorator | statement ) tag-collection := LEFT_BRACKET IDENTIFIER ( COMMA IDENTIFIER )* RIGHT_BRACKET widget := IDENTIFIER tag-collection? COLON expression field := FIELD_PREFIX IDENTIFIER ( LEFT_BRACKET RIGHT_BRACKET )? COLON expression statement := ( group-statement | match-statement | print-statement ) SEMICOLON group-qualifier := 'any' | 'all' group-statement := LEFT_CURLY ( field | expression )+ RIGHT_CURLY group-qualifier? print-statement := 'print' color-match-statement := 'color' COLOR_LITERAL image-match-statement := 'image' ( WILDCARD | IDENTIFIER ) tag-collection? text-match-statement := 'text' parameter-list? ( WILDCARD | IDENTIFIER ) tag-collection? size-match-statement := 'size' ( WILDCARD | NUMBER_LITERAL ) ( WILDCARD | NUMBER_LITERAL ) widget-match-statement := 'widget' ( WILDCARD | IDENTIFIER ) tag-collection? match-statement := text-match-statement | image-match-statement | color-match-statement | size-match-statement root := widget+ [/hide] Anyway, the above GPD produces the following state: (See the window labeled "GUI State"). Now, item icons are generated at run-time. This means I have to render the geometry myself. Item icons are fully-fledged models. They are rendered into a small framebuffer, and then a bunch of post-processing effects are applied. The actual item render is essentially identical to rendering a model in the game world. For stacked items, the same GUI matching code is used to parse the quantity text. I just hard-code the text-matching parser: auto quantity_text_node = new parser::MatchTextNode(); quantity_text_node->set_wildcard(); quantity_text_node->set_shadowed(true); quantity_text_node->set_include_spaces(false); auto quantity_field_node = new parser::FieldNode(); quantity_field_node->set_name("quantity"); quantity_field_node->add(quantity_text_node); auto root_node = new parser::GroupNode(); root_node->add(quantity_field_node); this->gui_parser.add_node(quantity_text_node); this->gui_parser.add_node(quantity_field_node); this->gui_parser.add_node(root_node); this->gui_parser.set_root_node(root_node); So I made an ItemIconManager that listens for 'draw_item_icon_model', 'draw_item_icon_gui', 'clear_item_icon', and 'transfer_item_icon', and 'copy_texture' events. It essentially emulates the RuneScape rendering, albeit without texturing and post-processing. However, the cool thing is, since item icons are models, and I'm the one doing the rendering, I can render the item icons however I want! So I created an 3D item icon viewer (as pictured in those images). I can select any item icon rendered up to the current frame and view it in all its 3D glory: And there you have it. What a wonderful waste of time and talent!
  5. Veiva replied to Leoo's topic in Off-Topic
    Doot doot. Pretty cool! Spooky...
  6. Veiva replied to Leoo's topic in Off-Topic
    Quaternions are used to represent rotations. They are generally converted into matrices before being used for rendering. For example, a Transform object may be composed of a scale vector, translation vector, and rotation quaternion, which are all combined into a matrix when concatenating transforms or transforming vertices. Usually, you have the world matrix, which represents the objects transformation from model-space to world-space; the view matrix, which represents the transformation into camera-space from world-space; and the projection matrix, which transforms a point into normalized device coordinates (e.g., 0 to 1) after dividing by w.
  7. Veiva replied to Leoo's topic in Off-Topic
    Looks awesome, Ring_World! Making a software renderer is a bunch of fun. Translation is easy. You simply use a four-dimensional vector (x, y, z, 1.0) for a vertex position and multiple it by the 4x4 transformation matrix with the last row/column (depending on row column-major or row-major matrices) being the translation vector. Projection transformations require dividing the xyz components by w after the transformation.
  8. Veiva replied to Leoo's topic in Off-Topic
    I want to match existing UI elements so I can graphically customize them. For example, changing colors or icons. (No layout changes, though.) For example, the above snippet matches the "ribbon menu" in RuneScape. I created a tool that allows me to assign resources names and tags (like "panel-border"). I'm going to do a write-up when I finish... It's all very interesting stuff.
  9. Veiva replied to Leoo's topic in Off-Topic
    I wrote a DSL to match GUI elements extracted from OpenGL state. The DSL produces a "parser tree" that operates on a stream of GUI elements. It supports functionality including back-tracking. And best of all? It works! This matches a ribbon menu: [hide] ribbon: { .background: image panel-background; .border: repeat image panel-border; .buttons[]: { { size 32 32; size 30 37; } any; .icon: image *; }; optional { .customize-button: widget button[customize-ribbon-button]; .lock-button: widget button[lock-button]; }; };[/hide] And now I'm making carrot cake.
  10. Veiva replied to Leoo's topic in Off-Topic
    A patch I submitted to an open source project was accepted! I'm proud. 8)
  11. Veiva replied to Leoo's topic in Off-Topic
    This single line sped up my code by over 5x (100 ms/frame to 15 ms/frame): this->model_tags.insert(tag);Who knew when implementing a cache, you need to actually update the cache?
  12. Veiva replied to Leoo's topic in Off-Topic
    For me, parents being able to buy their children a car places the household in a "well to do" position. But that's coming from someone who has a warped view of wealthy is, I suppose. I mean, I'm 25 and my household only ever had a working car for maybe 10 non-consecutive years in total, all of which were before I was an adult, and we've never grossed more than $25,000 a year, so... Considering how frugal we live, even $40,000 a year would make us feel like kings, lol.
  13. Veiva replied to Leoo's topic in Off-Topic
    "Most people" I assume would hover around or below the median household income, and by that metric, someone making $50,000 (in the United States) a year buying a $50,000 car is making a financially unsound decision. In other words, "most people" cannot afford a $50,000 car, loan or no loan.
  14. Veiva replied to Leoo's topic in Off-Topic
    I was under the impression you deposit $X to get an $X credit line (i.e., the bank risks nothing). I suppose I'll try for a secured card when we have enough in savings to last two months without income. Right now we're at just over one month... It'll be a while, since we can only save $100-$200 a month. I wasn't talking about my younger brother. :P I have more than one sibling. (Not that you knew! I don't think I've mentioned him/her before.)
  15. Veiva replied to Leoo's topic in Off-Topic
    I don't understand how secured credit card works. You borrow against your money? If I have $1000, I can spend $100 and take however long I want to 'pay back' the $100, while with a secured credit card, I'll be charged interest? They are literally charging me for nothing. I must be missing something. I just want to build credit--I would pay the statement in full every month--but I have no credit history. I don't get it. I have a sibling who had no credit history and then got a few credit cards and maxed them and never paid them back. Yet here I am, someone who is financially responsible, who can't get a credit card without spending my own money. How absurd.
  16. Veiva replied to Leoo's topic in Off-Topic
    I'm working on a library as a part of "custom NXT" renderer to allow rewriting the OpenGL call stream, and I have successfully created dependency graphs for calls (...or so I think...). For example, item icons are models rendered via multiple stages and then copied into a texture atlas: (The arrows are pointing to the item icons.) The call set for the texture at the end of the frame includes creating the shaders early during start-up: [hide] frame 1900: texture 26: call 914: glActiveTexture call 1610: glDrawBuffer call 1611: glReadBuffer call 1964: glShaderSource call 1965: glCompileShader call 2135: glShaderSource call 2136: glCompileShader call 2139: glCreateProgram call 2144: glBindAttribLocation call 2145: glBindAttribLocation [/hide] The texture itself being created: [hide] call 43238: glGenTextures call 43239: glBindTexture call 43240: glTexImage2D call 43241: glTexParameteri call 43242: glTexParameteri call 43243: glBindTexture call 43244: glTexParameteri call 43245: glTexParameteri call 43246: glTexParameterf call 43247: glTexParameteri call 43248: glTexParameteri call 43249: glTexParameteri call 43250: glTexParameteri call 43251: glTexParameteri call 43254: glBindTexture call 43255: glTexSubImage2D call 43257: glBindTexture call 43258: glTexSubImage2D call 43260: glBindTexture call 43261: glTexSubImage2D [/hide] And the item icon draws (seemingly): [hide] call 436528: glBindFramebufferEXT call 436529: glClearColor call 436530: glClear call 436534: glBlendFuncSeparate call 436535: glBlendEquationSeparate call 436546: glViewport call 436550: glDisable call 436551: glDisable call 436552: glColorMask call 436553: glUseProgram call 436556: glUniform1f call 436559: glUniform1f call 436564: glUniform1i call 436568: glUniform4fv call 436571: glUniform1f call 436574: glUniform1f call 436577: glUniformMatrix4fv call 436579: glDrawRangeElements call 436582: glBlendFuncSeparate call 436583: glBlendEquationSeparate call 436586: glDisable call 436587: glDisable call 436588: glColorMask call 436589: glDisable call 436590: glDepthMask call 436591: glDepthFunc call 436592: glDisable call 436620: glUseProgram call 436621: glBindVertexArray call 436623: glEnableVertexAttribArray call 436624: glVertexAttribPointer call 436625: glEnableVertexAttribArray call 436626: glVertexAttribPointer call 436627: glDisableVertexAttribArray call 436628: glDisableVertexAttribArray call 436629: glDisableVertexAttribArray call 436630: glDisableVertexAttribArray call 436631: glDisableVertexAttribArray call 436632: glDisableVertexAttribArray call 436633: glDisableVertexAttribArray call 436634: glDisableVertexAttribArray call 436635: glDisableVertexAttribArray call 436636: glDisableVertexAttribArray call 436637: glDisableVertexAttribArray call 436638: glDisableVertexAttribArray call 436639: glDisableVertexAttribArray call 436640: glDisableVertexAttribArray call 436641: glBindFramebufferEXT call 436645: glUniform4fv call 436647: glUniform1i call 436649: glUniform1i call 436650: glDrawArrays call 436655: glUniform4fv call 436657: glUniform1i call 436659: glBindFramebufferEXT call 436663: glUniform1i call 436664: glDrawArrays call 436669: glDisable call 436670: glEnable call 436671: glBlendFuncSeparate call 436672: glBlendEquationSeparate call 436673: glColorMask call 436675: glViewport call 436677: glCopyImageSubData [/hide] Now I need to write a tool to replay the 'minimum dependent call set' (or DiscreteCallSet, as the object is called) to test it...
  17. Veiva replied to Leoo's topic in Off-Topic
    Really? WTF Yes. There's potentially more. I think there were (maybe still are) questions about socialist/communist beliefs on security clearance applications, too. (Also nearly all IT jobs in professional firms around here require top secret clearance too. Hahaha. The joys of living next to one of the biggest military bases in the United States.)
  18. Veiva replied to Leoo's topic in Off-Topic
    Could you not get security clearance? Possibly, possibly not. A history of psychosis (unspecified schizophrenia spectrum disorder) may make that a bit hard, due to the nature of my symptoms, as far as I know. Also, don't know how being a socialist helps matters, either. (I know it's not the Cold War anymore, but there's still laws against being a or holding socialist/communist beliefs on the books, don't know if it affects security clearances, and I'm not going to lie about it). I started with C! For Christmas in 2003 (sixth grade), I got a book called "C Primer Plus." (I affectionately refer to it as "the big blue book.") We moved up here to NC the following month, and I read it cover-to-cover on the two trips it took to move stuff up here. Over the next year, I did exercises in the book until I had a firm understanding of C. Stayed with C for the longest time, developing games with Allegro 4 and other such things. Eventually, I met someone in my RuneScape clan (The Moriquendi) who programmed a little bit in C++ and the syntax fascinated me. He wrote a contact book program, and I remember seeing std::vector. Learned C++ over the next few years, moving on from "C with classes" to my current status of "moderately comfortable with most common C++ semantics" (e.g., SFINAE, RAII, the bulk of the standard library). I've also made extensive use of C# because I fell in love with XNA (made by the same developer behind Allegro 4!), Lua, and dabbled with at least half a dozen other languages (Python, JavaScript, Java, MoonScript, etc).
  19. Veiva replied to Leoo's topic in Off-Topic
    Every programming job around here requires security clearance. They also require things like a Bachelor's degree, but that's actually possible for me to get.
  20. Veiva replied to Leoo's topic in Off-Topic
    Writing code that writes code is the best. I've written my own speedy in-process OpenGL tracer. So far I can serializing OpenGL calls to a memory buffer. Taking a slightly customized OpenGL spec file, I wrote some monster that generates code to serialize and deserialize OpenGL calls, such as glTexImage2D: I should be able to identify interesting OpenGL calls and modify them, as well as injecting completely new OpenGL calls. Will allow me to customize the rendering of any OpenGL application. Such as changing the colors of GUI elements, or adding a day/night cycle, or whatever else... (I noticed a mistake in the code generation while reading the excerpt I posted. Another good thing about code generation is such bugs are easier to fix. :P)
  21. Veiva replied to Leoo's topic in Off-Topic
    I'm aware Java isn't JavaScript. I just brought it up because Randox thought Java's equality comparisons were bad. You don't in correct code, but what happens when a typo results in you passing a number as a string due to the dynamic typing system? Or the dozens of other cases where the wrong type of variable is passed around?
  22. Veiva replied to Leoo's topic in Off-Topic
    JavaScript's equality comparisons... If Cthulhu were a programming language, it would be less bizarre than that.
  23. Veiva replied to Leoo's topic in Off-Topic
    The FreeBSD bootloader uses Forth! The configuration file (loader.conf) is actually a Forth script. Pretty snazzy! I tried hacking at the GELI passphrase prompt but got lost. Forth is such an alien language, speaking as someone who comes from a largely self-taught/experience-based background of C-family languages.
  24. Veiva replied to Leoo's topic in Off-Topic
    I wear leather boots, riding jeans, leather jacket, full-face helmet, and leather gloves, whether I'm going a few blocks away to the store or 10 miles away for a doctor appointment, be it 70 degrees or 100 degrees. It may look ridiculous on a 50cc scooter, but I really don't care (Though when I'm off the scooter, I think I look pretty cool. [JOKE WARNING] And when I'm on my pink Honda Metropolitan, I think it's an interesting juxtaposition of gender role aesthetics in society. Similarly, I really want this jacket and these boots, then I'd say I look bad-ass. Or so I delude myself into thinking...)

Important Information

By using this site, you agree to our Terms of Use.

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.