我有一个使用像素艺术风格的游戏,升级,因此1个像素等于屏幕上的2x2区域。然而,当我在OpenGl中旋转一个精灵时,它使用屏幕像素绘制它,这样就打破了低分辨率风格游戏的错觉:
如何旋转精灵并使用较大的像素绘制它?现在使用Sprite类和一个名为Draw的方法绘制精灵,代码如下所示:
void Sprite::Draw(int x, int y, int w, int h, int tx = 0, int ty = 0, int tw = 1, int th = 1, int rotation = 0, int rx = 0, int ry = 0, int sr = 0, float r = 1, float g = 1, float b = 1) {
glEnable(GL_TEXTURE_2D);
glTranslatef(x+(w/2), y+(h/2), 0);
glRotatef((float) sr, 0.0f, 0.0f, 1.0f);
glTranslatef(-x-(w/2), -y-(h/2), 0);
glTranslatef(x+(w/2)+rx, y+(h/2)+ry, 0);
glRotatef((float) rotation, 0.0f, 0.0f, 1.0f);
glTranslatef(-(w/2)-rx, -(h/2)-ry, 0);
glColor3f(r, g, b);
glBindTexture(GL_TEXTURE_2D, texture);
const float verts[] = {
0, (float) h,
(float) w, (float) h,
0, 0,
(float) w, 0
};
const float tVerts[] = {
(float)tx/(float)width, ((float)ty+(float)th)/(float)height,
((float)tx+(float)tw)/(float)width, ((float)ty+(float)th)/(float)height,
(float)tx/(float)width, (float)ty/(float)height,
((float)tx+(float)tw)/(float)width, (float)ty/(float)height
};
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, verts);
glTexCoordPointer(2, GL_FLOAT, 0, tVerts);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glLoadIdentity();
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisable(GL_TEXTURE_2D);
}
谢谢!
编辑:我想我应该提到我正在使用SDL2进行窗口管理。答案 0 :(得分:3)
您可以以分辨率的一半渲染整个场景,然后将其放大。为此,您使用FBO(帧缓冲区对象)进行主渲染,然后将其blit到默认帧缓冲区。
在设置过程中,创建FBO并渲染目标,并将渲染目标附加到FBO:
GLuint fboId = 0;
glGenFramebuffers(1, &fboId);
GLuint rbId = 0;
glGenRenderbuffers(1, &rbId);
// Need to bind this once so object is created.
glBindRenderbuffer(GL_RENDERBUFFER, rbId);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboId);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbId);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
在每个窗口调整大小时,将窗口调整为width
/ height
,将渲染目标分配为窗口大小的一半。如果您的窗口不可调整大小,可以将其与设置代码结合使用:
glBindRenderbuffer(GL_RENDERBUFFER, rbId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width / 2, height / 2);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
在每次重绘时,渲染到FBO,并将结果blit到默认的帧缓冲区:
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboId);
glViewport(0, 0, width / 2, height / 2);
// draw content
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, fboId);
glBlitFramebuffer(0, 0, width / 2, height / 2,
0, 0, width, height,
GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
以上假设width
和height
是偶数。如果它们可能很奇怪,你可能需要稍微调整一下。