C++ 如何为OpenGL ES重新编写2D OpenGL应用程序?

C++ 如何为OpenGL ES重新编写2D OpenGL应用程序?,c++,c,opengl,opengl-es,sprite,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_TE

我正在开发一个带有精灵图形的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();
}

要使此OpenGL ES兼容,我需要更改什么?另外,我使用固定函数而不是着色器的原因是,我正在一台不支持GLSL的机器上开发。

在OpenGL ES 1.1中,使用
GLVERTEPOINTER()
GLCOLORPOINT()
glTexCoordPointer()
glDrawArrays()
函数绘制四元组。与OpenGL实现相反,您必须描述四元组所包含的结构(向量、颜色、纹理坐标),而不是仅使用内置的
glTexCoord2f
glVertex2f
glColor3f
方法

下面是一些示例代码,它们可以实现您想要的功能。(我使用了您在函数定义中使用的参数名称,因此从示例中移植代码应该很简单。)

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

// 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;
然后,您应该定义一个结构来描述由四个顶点组成的整个四边形:

// Define a quad structure
typedef struct Quad {
    QuadVertex tl;
    QuadVertex bl;
    QuadVertex tr;
    QuadVertex br;
} Quad; 
现在,实例化四边形并指定四边形顶点信息(位置、颜色、纹理坐标):

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

// "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));
最后,指定纹理并绘制四边形
glDrawArrays
告诉OpenGL使用先前定义的偏移以及
Quad
对象中包含的值来绘制由
4
顶点定义的形状

glBindTexture(GL_TEXTURE_2D, tex);

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

glBindTexture(GL_TEXTURE_2D, 0);

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

好的,但我不完全理解如何将其转换为函数。像Vec2这样的东西从何而来-我在编译它时得到了“Vec2不命名类型”。从他的例子中:“(假设Vec2是一个由两个浮点数(x,y)组成的结构,并为一个有4个字节(r,g,b,a)的结构着色”)我刚刚编辑了我的答案,希望它现在对你更有用。现在将其用作端口的模板应该相对简单。答案很好,但请注意,在发送二维四边形顶点时,glVertexPointer维度的值为3,这看起来像是输入错误。我更正了代码示例中的顶点浮动数。希望它现在100%正确。1.1我想,因为我使用的是固定管道。
glBindTexture(GL_TEXTURE_2D, tex);

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

glBindTexture(GL_TEXTURE_2D, 0);