【发布时间】:2014-05-23 02:15:47
【问题描述】:
所以我有这段代码,它几乎可以在屏幕上绘制各种 2D 纹理,尽管必须从纹理(spritesheet)中“剖析”多个精灵。问题是旋转不能正常工作;当它旋转时,它不会在纹理的中心旋转,这就是我想要做的。我已将其范围缩小到翻译不正确:
glTranslatef(x + sr->x/2 - sr->w/2,
y + sr->y/2 - sr->h/2,0);
glRotatef(ang,0,0,1.f);
glTranslatef(-x + -sr->x/2 - -sr->w/2,
-y + -sr->y/2 - -sr->h/2,0);
X 和 Y 是它被绘制到的位置,sheet rect 结构包含从纹理中绘制的精灵的位置 X 和 Y,以及 w 和 h,它们是“精灵”的宽度和高度' 从纹理。我尝试了其他各种公式,例如:
glTranslatef(x, y, 0);
The below three switching the negative sign to positive (x - y to x + y)
glTranslatef(sr->x/2 - sr->w/2, sr->y/2 - sr->h/2 0 );
glTranslatef(sr->x - sr->w/2, sr->y - sr->h/2, 0 );
glTranslatef(sr->x - sr->w, sr->y - sr->w, 0 );
glTranslatef(.5,.5,0);
这样说也可能会有所帮助:
glOrtho(0,screen_width,screen_height,0,-2,10);
正在使用中。
我尝试阅读各种教程,浏览各种论坛,询问各种人,但似乎没有有效的解决方案,也找不到任何有用的资源来解释我如何找到中心图像以便将其转换为“(0,0)”。我对 OpenGL 还很陌生,所以很多东西我需要一段时间才能消化。
这是整个函数:
void Apply_Surface( float x, float y, Sheet_Container* source, Sheet_Rect* sr , float ang = 0, bool flipx = 0, bool flipy = 0, int e_x = -1, int e_y = -1 ) {
float imgwi,imghi;
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,source->rt());
// rotation
imghi = source->rh();
imgwi = source->rw();
Sheet_Rect t_shtrct(0,0,imgwi,imghi);
if ( sr == NULL ) // in case a sheet rect is not provided, assume it's width
//and height of texture with 0/0 x/y
sr = &t_shtrct;
glPushMatrix();
//
int wid, hei;
glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_WIDTH,&wid);
glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_HEIGHT,&hei);
glTranslatef(-sr->x + -sr->w,
-sr->y + -sr->h,0);
glRotatef(ang,0,0,1.f);
glTranslatef(sr->x + sr->w,
sr->y + sr->h,0);
// Yeah, out-dated way of drawing to the screen but it works for now.
GLfloat tex[] = {
(sr->x+sr->w * flipx) /imgwi, 1 - (sr->y+sr->h *!flipy )/imghi,
(sr->x+sr->w * flipx) /imgwi, 1 - (sr->y+sr->h * flipy)/imghi,
(sr->x+sr->w * !flipx) /imgwi, 1 - (sr->y+sr->h * flipy)/imghi,
(sr->x+sr->w * !flipx) /imgwi, 1 - (sr->y+sr->h *!flipy)/imghi
};
GLfloat vertices[] = { // vertices to put on screen
x, (y + sr->h),
x, y,
(x +sr->w), y,
(x +sr->w),(y +sr->h)
};
// index array
GLubyte index[6] = { 0,1,2, 2,3,0 };
float fx = (x/(float)screen_width)-(float)sr->w/2/(float)imgwi;
float fy = (y/(float)screen_height)-(float)sr->h/2/(float)imghi;
// activate arrays
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// pass verteices and texture information
glVertexPointer(2, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, tex);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, index);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glPopMatrix();
glDisable(GL_TEXTURE_2D);
}
工作表容器类:
class Sheet_Container {
GLuint texture;
int width, height;
public:
Sheet_Container();
Sheet_Container(GLuint, int = -1,int = -1);
void Load(GLuint,int = -1,int = -1);
float rw();
float rh();
GLuint rt();
};
表格矩形类:
struct Sheet_Rect {
float x, y, w, h;
Sheet_Rect();
Sheet_Rect(int xx,int yy,int ww,int hh);
};
图片加载功能:
Sheet_Container Game_Info::Load_Image(const char* fil) {
ILuint t_id;
ilGenImages(1, &t_id);
ilBindImage(t_id);
ilLoadImage(const_cast<char*>(fil));
int width = ilGetInteger(IL_IMAGE_WIDTH), height = ilGetInteger(IL_IMAGE_HEIGHT);
return Sheet_Container(ilutGLLoadImage(const_cast<char*>(fil)),width,height);
}
【问题讨论】:
-
您的描述与我有关:“它不会在纹理的中心旋转”相当模糊。我假设您正在绘制一个纹理映射的四边形,而您要旋转的是那个四边形?您使用的 GL 版本仍然支持纹理矩阵,因此您同样可能指代纹理坐标的旋转和平移(尽管在使用精灵表时这会产生一些奇怪的结果)。
-
是的,我正在使用 devIL 库的 ilLoadImage 函数加载图像。我相信这是一个四边形。基本上,draw 函数绑定了 GL_TEXTURE_2D 纹理,推送一个新矩阵,进行旋转,然后绘制到屏幕上。如有必要,我可以发布整个功能。但是,无论如何,我试图围绕精灵/图像本身的“中心”旋转它。目前,如果我不翻译它,它会在图像的左上角旋转。
-
好的,所以你想围绕它的中心旋转这个四边形。我认为您将不得不发布更多代码,我无法从您显示的内容中弄清楚您的四边形的尺寸。
-
我发布了更多代码;当显示多个时,四边形的尺寸会随着纹理的变化而变化。
-
在“整个函数”中,您有 0 度的旋转。这只是复制/粘贴错误吗?