OpenGL ES Pixel Art - Scaling

和自甴很熟 提交于 2019-12-06 14:56:04

There are quite a few ways of doing this and I would suggest the first one you already found. Draw the scene to a smaller buffer and then redraw it a canvas.

What you are looking here for is a FBO (frame buffer object). Find some examples on how to create a FBO and attach a texture to it. This will create a buffer for you with any dimensions you will input. Some common issues here are that you will most likely need a POT texture (a power of 2 dimensions: 2, 4, 8, 16... So 64x128 buffer for instance) so to control a different size you should use viewport which will then use only a part of the buffer you need.

So in the end this will create a low resolution texture which can be used to draw to the canvas (view). How you draw to it something you should experiment with. The points may not be the best solution, even in your case of a buffer I would use lines between the points you defined in your example. At this point you must choose to draw with or without the antialias. To enable it look for the multisampling on iOS.

After you have the texture to which the shape is drawn you will need to redraw it to the view. This is pretty much drawing a full-screen texture. Again you have multiple ways of drawing it. The most powerful tool here are the texture parameters: Using nearest will discard all the color interpolations and the squares should be visible; using linear (or trilinear) will do some interpolation and the result will probably be nearer to what you want to achieve. Then you may again play around with multisampling to create antialiasing and get a better result.

So the powers here are:

  • Different FBO buffer sizes
  • Antialiasing on the FBO
  • Texture parameters
  • Antialiasing when redrawing to canvas

As for the FBO this is one of the easiest things to do:

  • Generate frame buffer (glGenFramebuffers)
  • Bind the frame buffer (glBindFramebuffer)
  • Create a texture (glGenTextures) and bind it (glBindTexture)
  • Set texture data glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, twidth, theight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  • Attach the texture to the frame buffer glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.textureID, 0);
  • Now when you draw to the texture you need to bind the FBO frame buffer and when you draw to the main buffer just bind that frame buffer.

Since this is quite a broad answer (as is the question)... If you will be implementing this and will have additional questions or issues it will be best to create a separate questions and probably link them in the comments.

Good luck.

Im not sure if my question was not clear, but to draw pixels to screen you have to create a texture and pass in the pixel data to it, then render that texture onto the screen. It would be the equivalent of glDrawPixels.

The code would be:

#define W 255,255,255

#define G 192,192,192

//8 x 8 tile with 3 bytes for each pixel RGB format
GLubyte pixels[8 * 8 * 3] = {
W,W,W,W,W,W,W,W,
W,W,G,G,G,W,W,W,
W,G,W,W,W,G,W,W,
W,G,W,W,W,G,W,W,
W,W,G,G,G,W,W,W,
W,G,W,W,W,G,W,W,
W,G,W,W,W,G,W,W,
W,W,G,G,G,W,W,W
};

somewhere in setup:

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &tex);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 8, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

Then draw the texture as usual:

glActiveTexture(GL_TEXTURE0);
glUniform1i([program uniformLocation:@"s_texture"], 0);
glBindTexture(GL_TEXTURE_2D, tex);

glEnableVertexAttribArray(positionAttrib);
glVertexAttribPointer(positionAttrib, 2, GL_FLOAT, GL_FALSE, 0, v);
glEnableVertexAttribArray(texAttrib);
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 0, t);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, i);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!