2014-10-26 45 views
1

我有一款遊戲使用像素藝術風格,因此1像素等於屏幕上的2x2區域。然而,當我在OpenGL旋轉精靈它吸引它使用的屏幕像素,它打破了一個低分辨率的遊戲風格的幻想:在OpenGL中使用2像素旋轉像素藝術

Rotated sprite

我如何可以旋轉精靈,並使用更大的繪製像素?眼下精靈使用的是有一個方法叫得出一個Sprite類繪製,並且代碼看起來是這樣的:

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進行窗口管理。

+1

所以你想旋轉,然後高檔?我認爲這可能最終看起來很可怕。傳統的像素藝術遊戲不會進行旋轉,或者他們有一小部分方向的手繪精靈。 – Thomas 2014-10-26 14:17:13

+0

@Thomas它可能,我不知道。我可以手繪精靈旋轉,但是這個遊戲有一些軌道機制,所以能夠非常精確地指出這艘船很重要,這意味着它需要大概100個左右的旋轉精靈。 – 2014-10-26 14:19:35

+0

如果問題在於您正在看*旋轉像素,那麼請考慮縮小到「實際」像素,然後再旋轉,然後再放大。 – usr2564301 2014-10-26 15:17:27

回答

2

您可以將整個場景渲染爲分辨率的一半,然後將其放大。爲此,您使用FBO(幀緩衝區對象)作爲主渲染,然後將其閃光到默認幀緩衝區。

一次,在安裝過程中,創建您的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); 

以上假定widthheight是偶數。如果它們可能很奇怪,你可能需要稍微調整它。

+0

看起來很有前途...但是隻要我生成一個framebuffer就會發生段錯誤。 – 2014-10-26 18:06:51

+1

大部分是GL 3.x級功能。您可能沒有支持此版本的上下文。 – 2014-10-26 18:17:07

+0

我如何使用OpenGL 3的東西,而不會擺脫我舊式的非着色GL代碼? – 2014-10-26 19:11:56