如何为OpenGL ES重写2D OpenGL应用程序?

Sky*_*ler 8 c c++ opengl opengl-es sprite

我正在开发一个带有精灵图形的OpenGL 2D游戏.我最近被告知我应该使用OpenGL ES调用,因为它是OpenGL的一个子集,并允许我更轻松地将其移植到移动平台.大多数代码只是调用draw_image函数,它定义如下:

void draw_img(float x, float y, float w, float h, GLuint tex,float r=1,float g=1, float b=1) {
    glColor3f(r,g,b);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, tex);
    glBegin(GL_QUADS);
        glTexCoord2f(0.0f, 0.0f);
        glVertex2f( x, y);
        glTexCoord2f(1.0f, 0.0f);
        glVertex2f(w+x, y);
        glTexCoord2f(1.0f, 1.0f);
        glVertex2f( w+x, h+y);
        glTexCoord2f(0.0f, 1.0f);
        glVertex2f( x, h+y);
    glEnd();
}
Run Code Online (Sandbox Code Playgroud)

我需要更改什么才能使这个OpenGL ES兼容?另外,我使用固定功能而不是着色器的原因是我在不支持GLSL的机器上开发.

sta*_*ugs 13

在OpenGL ES 1.1使用glVertexPointer(),glColorPointer(),glTexCoordPointer()glDrawArrays()功能画出一个四边形.相较于OpenGL实现,你将不得不描述结构(向量,颜色,纹理坐标),你的四组成,而不是只使用内置的glTexCoord2f,glVertex2fglColor3f方法.

这是一些应该做你想做的代码示例代码.(我已经使用了函数定义中使用的参数名称,因此从示例中移植代码应该很简单.)

首先,您需要为四边形的一个顶点定义结构.这将保存四边形顶点位置,颜色和纹理坐标.

// Define a simple 2D vector
typedef struct Vec2 {
    float x,y;
} Vec2;

// Define a simple 4-byte color
typedef struct Color4B {
    GLbyte r,g,b,a;
};

// Define a suitable quad vertex with a color and tex coords.
typedef struct QuadVertex {
    Vec2 vect;              // 8 bytes
    Color4B color;          // 4 bytes
    Vec2 texCoords;         // 8 bytes
} QuadVertex;
Run Code Online (Sandbox Code Playgroud)

然后,您应该定义一个描述由四个顶点组成的整个四边形的结构:

// Define a quad structure
typedef struct Quad {
    QuadVertex tl;
    QuadVertex bl;
    QuadVertex tr;
    QuadVertex br;
} Quad; 
Run Code Online (Sandbox Code Playgroud)

现在,实例化你的四边形并分配四边形顶点信息(位置,颜色,纹理坐标):

Quad quad;
quad.bl.vect = (Vec2){x,y};
quad.br.vect = (Vec2){w+x,y};
quad.tr.vect = (Vec2){w+x,h+y};
quad.tl.vect = (Vec2){x,h+y};
quad.tl.color = quad.tr.color = quad.bl.color = quad.br.color
              = (Color4B){r,g,b,255};
quad.tl.texCoords = (Vec2){0,0};
quad.tr.texCoords = (Vec2){1,0};
quad.br.texCoords = (Vec2){1,1};
quad.bl.texCoords = (Vec2){0,1};
Run Code Online (Sandbox Code Playgroud)

现在告诉OpenGL如何绘制四边形.调用gl...PointerOpenGL为顶点结构的值提供正确的偏移和大小,以便稍后可以使用该信息绘制四边形.

// "Explain" the quad structure to OpenGL ES

#define kQuadSize sizeof(quad.bl)    
long offset = (long)&quad;

// vertex
int diff = offsetof(QuadVertex, vect);
glVertexPointer(2, GL_FLOAT, kQuadSize, (void*)(offset + diff));

// color
diff = offsetof(QuadVertex, color);
glColorPointer(4, GL_UNSIGNED_BYTE, kQuadSize, (void*)(offset + diff));

// texCoods
diff = offsetof(QuadVertex, texCoords);
glTexCoordPointer(2, GL_FLOAT, kQuadSize, (void*)(offset + diff));
Run Code Online (Sandbox Code Playgroud)

最后,分配纹理并绘制四边形.glDrawArrays告诉OpenGL使用先前定义的偏移量和Quad对象中包含的值来绘制由4顶点定义的形状.

glBindTexture(GL_TEXTURE_2D, tex);

// Draw the quad
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

glBindTexture(GL_TEXTURE_2D, 0);
Run Code Online (Sandbox Code Playgroud)

另请注意,如果您不需要着色器,则可以使用OpenGL ES 1.ES1和ES2之间的主要区别在于,在ES2中,没有固定的管道,因此您需要为自己的基本渲染实现矩阵堆栈和着色器.如果您对固定管道提供的功能感到满意,只需使用OpenGL ES 1即可.