mattdesl

Members
  • Content count

    11
  • Joined

  • Last visited

Community Reputation

176 Neutral

About mattdesl

  • Rank
    Member
  1. There is some useful information and code here: http://www.java-gaming.org/topics/opengl-lightning-fast-managed-vbo-mapping/28209/msg/255576/view.html#msg255576
  2. If you were using GL 3+, you can utilize geometry shaders and instancing.    But really there is no need to restrict your audience to GL 3+ (it's not yet very widely supported, especially not in the casual market). GL 2+ functionality will be more than enough for a 2D sprite batcher.   The simplest way to optimize your sprite batcher is to send as little as possible to GL. Update your uniforms (e.g. ortho 2D projection matrix) only as necessary, and only pass the attributes you really need. If you know some of your data is static, you can use multiple VBOs, otherwise you should just stick to interleaved data.   My sprite batcher uses the following attributes per vertex:   { x, y, color, u, v }     The color is a packed float. That means 5 attributes per vertex, and 4 vertices per sprite using element indices. One-off transformations (like sprite rotation) are done in CPU before passing vetex position.   Most of the time, optimizing in 2D is more about using texture atlases, improving batch rendering, and minimizing overdraw rather than worrying about small things like whether or not to interleave your VBO data. Besides, 99% of the time a 2D game will become fill-rate bound before it becomes vertex bound.   On the subject of fill rate, you can use hexagons or some other non-rectangular primitive as an optimization (although it comes at the cost of more vertices and may be undesirable depending on you sprites).    For more reading on my sprite batcher: https://github.com/mattdesl/lwjgl-basics/wiki/Sprite-Batching https://github.com/mattdesl/lwjgl-basics/blob/master/src/mdesl/graphics/SpriteBatch.java   Using plain old VBOs or even vertex arrays will be plenty fast, but if you want to squeeze a bit more performance out of GL 2.0 you should look into mapped VBOs: http://www.java-gaming.org/topics/opengl-lightning-fast-managed-vbo-mapping/28209/view.html
  3. OpenGL Porting to OpenGL

      GL 3.0+ is still not very widely supported. If you are targeting a casual market, you may want to stick with 2.0 as your target. In this thread it was listed that as few as 51% of Minecraft users supports GL 3.0+. It really comes down to what you need; GL 2 is a fine target for most purposes and can be used in almost the same way as the 3+ programmable pipeline (shaders, custom built-ins, etc). Many drivers will support geometry shaders, FBOs, float textures, etc. through extensions. For example, [url=http://feedback.wildfiregames.com/report/opengl/feature/GL_EXT_framebuffer_object]93%[/url] of drivers support FBO EXT, and it's pretty much a staple in any driver in the last several years.    GL 2.0 and GLSL < 150 is also more compatible with OpenGL ES, so it will prepare you for iOS/Android/WebGL graphics programming.
  4. A VBO should be performant enough for the vast majority of cases. If you need better performance you can pass points and expand them to triangles in a geometry shader.   Read up here on some techniques for VBO optimization with sprite batching: http://www.java-gaming.org/topics/opengl-lightning-fast-managed-vbo-mapping/28209/view.html   Since ultimately the performance may vary depending on the driver, the absolute "fastest" solution is to use whatever works best for the driver. For example, in the intro cutscene of your game you might benchmark a few different rendering techniques, and pick whichever runs the fastest.
  5. OpenGL Good books for OpenGL

    I'm writing a tutorial series aimed at beginners wanting to learn the programmable pipeline and GLSL shaders, check it out here: https://github.com/mattdesl/lwjgl-basics/wiki
  6. If you do not need perfectly scalable fonts, then plain old bitmap fonts are very simple and hassle-free.    You can see my minimal implementation [url=https://github.com/mattdesl/lwjgl-basics/blob/master/src/mdesl/graphics/text/BitmapFont.java]here[/url].
  7. Doing the the matrix calculations in software shouldn't be too bad. But if you are CPU limited (maybe the case on Android) then here is an alternative that does the matrix calculation on the GPU:   Pass a vec4 Rotation (rotX, rotY, rotZ, angle) to your vertex shader. Then calculate the rotation matrix in your shader:   [code]mat4 transform = mat4(1.0); //identity   ... make rotation matrix from axis and angle ...   gl_Position = projection * view * transform * a_position;[/code]   Theoretically you could put the Position and Normal attributes into a separate static VBO since they are unchanged (and update the view matrix instead). If you fill all your instance data in one go, you could end up with a single draw call per frame.
  8. OpenGL Default color attribute

    If you are using version 330 you should be doing some things a bit differently in GLSL:   - Use "in" and "out" instead of "varying" and "attribute" - Use layout(location=X) to specify the index to bind the attribute to - Use a custom output instead of gl_FragColor   Also just so you know, GL 3.0+ is still not very widely supported. If you are targeting a casual market, you may want to stick with 2.0 as your target. [url=http://www.java-gaming.org/index.php?topic=26377.0]In one thread[/url] it was listed that as few as 51% of Minecraft users supports GL 3.0+. It really comes down to what you need; GL 2 is a fine target for most purposes and can be used in almost the same way as the 3+ programmable pipeline. Many drivers will support geometry shaders, FBOs, float textures, etc. through extensions.
  9. Your code looks extremely complicated for something so simple. Are you making a 2D game? Why are you using world coordinates instead of orthographic projection? In addition to ortho, texture states, etc. you should also read up a little on classes and object oriented programming. For example, you might:[list] [*]Define a "Texture" class which wraps OpenGL textures (bind, wrap modes, filtering, etc) and pads for NPOT [*]Define a "TextureRegion" class utility which determines normalized texture coordinates from un-normalized pixel coordinates [*]Define a "TextureAtlas" (or "SpriteSheet") class which splits a TextureRegion into an array of many TextureRegion objects [/list] Also, the whole point of a sprite sheet is to reduce texture binds and state changes. Bind the texture atlas, glBegin quads, specify the vertices for [i]all of your sprites [/i]within that sheet, then glEnd to push the data to the GPU. Here's a very simple example, similar to what I use: [code]public class TextureRegion { protected float normalizedWidth, normalizedHeight; protected float width, height; protected float centerX, centerY; protected float textureOffsetX, textureOffsetY; protected Texture texture; public TextureRegion(Texture texture) { this.texture = texture; //e.g. a 240x240 PNG image would be loaded as a 256x256 texture this.normalizedWidth = texture.getImageWidth() / (float) texture.getTextureWidth(); this.normalizedHeight = texture.getImageHeight() / (float) texture.getTextureHeight(); this.width = texture.getImageWidth(); this.height = texture.getImageHeight(); this.centerX = width / 2f; this.centerY = height / 2f; } public TextureRegion copy() { TextureRegion img = new TextureRegion(texture); return img; } public TextureRegion getSubImage(float x, float y, float width, float height) { float tx = ( x / this.width * normalizedWidth ) + textureOffsetX; float ty = ( y / this.height * normalizedHeight ) + textureOffsetY; float tw = width / this.width * normalizedWidth; float th = height / this.height * normalizedHeight; TextureRegion img = copy(); img.textureOffsetX = tx; img.textureOffsetY = ty; img.width = width; img.height = height; img.normalizedWidth = tw; img.normalizedHeight = th; img.centerX = width / 2f; img.centerY = height / 2f; return img; } // ideally you should use a modern solution like VBOs and place rendering elsewhere... public void begin() { GL11.glEnable(GL11.GL_TEXTURE_2D); texture.bind(); GL11.glBegin(GL11.GL_QUADS); } public void end() { GL11.glEnd(); GL11.glDisable(GL11.GL_TEXTURE_2D); } public void draw(float x, float y) { GL11.glTexCoord2f(textureOffsetX, textureOffsetY; //TOP LEFT GL11.glVertex2f(x, y); GL11.glTexCoord2f(textureOffsetX, textureOffsetY+normalizedHeight); //BOTTOM LEFT GL11.glVertex2f(x, y+height); GL11.glTexCoord2f(textureOffsetX+normalizedWidth, textureOffsetY+normalizedHeight); //BOTTOM RIGHT GL11.glVertex2f(x+width, y+height); GL11.glTexCoord2f(textureOffsetX+normalizedWidth, textureOffsetY); //TOP RIGHT GL11.glVertex2f(x+width, y); } }[/code]
  10. NeHe's tutorials are old and outdated, and it's a terrible place to start learning today's OpenGL. Instead, you should be learning the "modern" programmable pipeline (GLSL). I'd also suggest using a framework (other than GLUT) to help you through common tasks like window creation, PNG decoding, etc. Java and LWJGL/JOGL are popular choices for this as you jump right into OpenGL programming without the need for memory management, OS hacks, display code, context creation, etc. If you want to stick with C++, there are a number of libraries like SDL and GLFW that will help set up the basics for you. This series covers context creation and other things from a more "modern" perspective: [url="http://open.gl/"]http://open.gl/[/url] And here's another popular "modern OpenGL" tutorial: [url="http://www.arcsynthesis.org/gltut/"]http://www.arcsynthesis.org/gltut/[/url]
  11. Generally you will want to use GL_TEXTURE_2D and two triangles (or a quad). GL_TEXTURE_RECTANGLE was originally used for a means of achieving non-power-of-two textures; now most modern hardware supports NPOT textures with GL_TEXTURE_2D.