void UIBatch::AddQuad(const Matrix3x4& transform, const IntVector2& a, const IntVector2& b, const IntVector2& c, const IntVector2& d, const IntVector2& texA, const IntVector2& texB, const IntVector2& texC, const IntVector2& texD) { Vector3 v1 = (transform * Vector3((float)a.x_, (float)a.y_, 0.0f)) - posAdjust; Vector3 v2 = (transform * Vector3((float)b.x_, (float)b.y_, 0.0f)) - posAdjust; Vector3 v3 = (transform * Vector3((float)c.x_, (float)c.y_, 0.0f)) - posAdjust; Vector3 v4 = (transform * Vector3((float)d.x_, (float)d.y_, 0.0f)) - posAdjust; Vector2 uv1((float)texA.x_ * invTextureSize_.x_, (float)texA.y_ * invTextureSize_.y_); Vector2 uv2((float)texB.x_ * invTextureSize_.x_, (float)texB.y_ * invTextureSize_.y_); Vector2 uv3((float)texC.x_ * invTextureSize_.x_, (float)texC.y_ * invTextureSize_.y_); Vector2 uv4((float)texD.x_ * invTextureSize_.x_, (float)texD.y_ * invTextureSize_.y_); unsigned begin = vertexData_->Size(); vertexData_->Resize(begin + 6 * UI_VERTEX_SIZE); float* dest = &(vertexData_->At(begin)); vertexEnd_ = vertexData_->Size(); dest[0] = v1.x_; dest[1] = v1.y_; dest[2] = 0.0f; ((unsigned&)dest[3]) = color_; dest[4] = uv1.x_; dest[5] = uv1.y_; dest[6] = v2.x_; dest[7] = v2.y_; dest[8] = 0.0f; ((unsigned&)dest[9]) = color_; dest[10] = uv2.x_; dest[11] = uv2.y_; dest[12] = v3.x_; dest[13] = v3.y_; dest[14] = 0.0f; ((unsigned&)dest[15]) = color_; dest[16] = uv3.x_; dest[17] = uv3.y_; dest[18] = v1.x_; dest[19] = v1.y_; dest[20] = 0.0f; ((unsigned&)dest[21]) = color_; dest[22] = uv1.x_; dest[23] = uv1.y_; dest[24] = v3.x_; dest[25] = v3.y_; dest[26] = 0.0f; ((unsigned&)dest[27]) = color_; dest[28] = uv3.x_; dest[29] = uv3.y_; dest[30] = v4.x_; dest[31] = v4.y_; dest[32] = 0.0f; ((unsigned&)dest[33]) = color_; dest[34] = uv4.x_; dest[35] = uv4.y_; }
void EERIEDrawBitmap2DecalY(Rectf rect, float z, TextureContainer * tex, Color color, float _fDeltaY) { rect.move(-.5f, -.5f); rect.top = rect.top + _fDeltaY * rect.height(); Vec2f uv = (tex) ? tex->uv : Vec2f_ZERO; float sv = uv.y * _fDeltaY; ColorRGBA col = color.toRGBA(); Vec2f uv1(0.f, sv); Vec2f uv2(uv.x, sv); Vec2f uv3(uv.x, uv.y); Vec2f uv4(0.f, uv.y); TexturedVertex v[4]; v[0] = TexturedVertex(Vec3f(rect.topLeft(), z), 1.f, col, uv1); v[1] = TexturedVertex(Vec3f(rect.topRight(), z), 1.f, col, uv2); v[2] = TexturedVertex(Vec3f(rect.bottomRight(), z), 1.f, col, uv3); v[3] = TexturedVertex(Vec3f(rect.bottomLeft(), z), 1.f, col, uv4); SetTextureDrawPrim(tex, v, Renderer::TriangleFan); }
void RenderQuad() { if (quadVAO == 0) { // positions glm::vec3 pos1(-1.0, 1.0, 0.0); glm::vec3 pos2(-1.0, -1.0, 0.0); glm::vec3 pos3(1.0, -1.0, 0.0); glm::vec3 pos4(1.0, 1.0, 0.0); // texture coordinates glm::vec2 uv1(0.0, 1.0); glm::vec2 uv2(0.0, 0.0); glm::vec2 uv3(1.0, 0.0); glm::vec2 uv4(1.0, 1.0); // normal vector glm::vec3 nm(0.0, 0.0, 1.0); // calculate tangent/bitangent vectors of both triangles glm::vec3 tangent1, bitangent1; glm::vec3 tangent2, bitangent2; // - triangle 1 glm::vec3 edge1 = pos2 - pos1; glm::vec3 edge2 = pos3 - pos1; glm::vec2 deltaUV1 = uv2 - uv1; glm::vec2 deltaUV2 = uv3 - uv1; GLfloat f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y); tangent1.x = f * (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x); tangent1.y = f * (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y); tangent1.z = f * (deltaUV2.y * edge1.z - deltaUV1.y * edge2.z); tangent1 = glm::normalize(tangent1); bitangent1.x = f * (-deltaUV2.x * edge1.x + deltaUV1.x * edge2.x); bitangent1.y = f * (-deltaUV2.x * edge1.y + deltaUV1.x * edge2.y); bitangent1.z = f * (-deltaUV2.x * edge1.z + deltaUV1.x * edge2.z); bitangent1 = glm::normalize(bitangent1); // - triangle 2 edge1 = pos3 - pos1; edge2 = pos4 - pos1; deltaUV1 = uv3 - uv1; deltaUV2 = uv4 - uv1; f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y); tangent2.x = f * (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x); tangent2.y = f * (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y); tangent2.z = f * (deltaUV2.y * edge1.z - deltaUV1.y * edge2.z); tangent2 = glm::normalize(tangent2); bitangent2.x = f * (-deltaUV2.x * edge1.x + deltaUV1.x * edge2.x); bitangent2.y = f * (-deltaUV2.x * edge1.y + deltaUV1.x * edge2.y); bitangent2.z = f * (-deltaUV2.x * edge1.z + deltaUV1.x * edge2.z); bitangent2 = glm::normalize(bitangent2); GLfloat quadVertices[] = { // Positions // normal // TexCoords // Tangent // Bitangent pos1.x, pos1.y, pos1.z, nm.x, nm.y, nm.z, uv1.x, uv1.y, tangent1.x, tangent1.y, tangent1.z, bitangent1.x, bitangent1.y, bitangent1.z, pos2.x, pos2.y, pos2.z, nm.x, nm.y, nm.z, uv2.x, uv2.y, tangent1.x, tangent1.y, tangent1.z, bitangent1.x, bitangent1.y, bitangent1.z, pos3.x, pos3.y, pos3.z, nm.x, nm.y, nm.z, uv3.x, uv3.y, tangent1.x, tangent1.y, tangent1.z, bitangent1.x, bitangent1.y, bitangent1.z, pos1.x, pos1.y, pos1.z, nm.x, nm.y, nm.z, uv1.x, uv1.y, tangent2.x, tangent2.y, tangent2.z, bitangent2.x, bitangent2.y, bitangent2.z, pos3.x, pos3.y, pos3.z, nm.x, nm.y, nm.z, uv3.x, uv3.y, tangent2.x, tangent2.y, tangent2.z, bitangent2.x, bitangent2.y, bitangent2.z, pos4.x, pos4.y, pos4.z, nm.x, nm.y, nm.z, uv4.x, uv4.y, tangent2.x, tangent2.y, tangent2.z, bitangent2.x, bitangent2.y, bitangent2.z }; // Setup plane VAO glGenVertexArrays(1, &quadVAO); glGenBuffers(1, &quadVBO); glBindVertexArray(quadVAO); glBindBuffer(GL_ARRAY_BUFFER, quadVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 14 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat))); glEnableVertexAttribArray(3); glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(GLfloat), (GLvoid*)(8 * sizeof(GLfloat))); glEnableVertexAttribArray(4); glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(GLfloat), (GLvoid*)(11 * sizeof(GLfloat))); } glBindVertexArray(quadVAO); glDrawArrays(GL_TRIANGLES, 0, 6); glBindVertexArray(0); }
// 建立矩形的VAO数据 void setupQuadVAO() { // 顶点位置 glm::vec3 pos1(-1.0, 1.0, 0.0); glm::vec3 pos2(-1.0, -1.0, 0.0); glm::vec3 pos3(1.0, -1.0, 0.0); glm::vec3 pos4(1.0, 1.0, 0.0); // 纹理坐标 glm::vec2 uv1(0.0, 1.0); glm::vec2 uv2(0.0, 0.0); glm::vec2 uv3(1.0, 0.0); glm::vec2 uv4(1.0, 1.0); // 法向量 glm::vec3 nm(0.0, 0.0, 1.0); // 计算两个三角形的TB向量 glm::vec3 tangent1, bitangent1; glm::vec3 tangent2, bitangent2; // 三角形1 glm::vec3 edge1 = pos2 - pos1; glm::vec3 edge2 = pos3 - pos1; glm::vec2 deltaUV1 = uv2 - uv1; glm::vec2 deltaUV2 = uv3 - uv1; GLfloat f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y); tangent1.x = f * (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x); tangent1.y = f * (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y); tangent1.z = f * (deltaUV2.y * edge1.z - deltaUV1.y * edge2.z); tangent1 = glm::normalize(tangent1); bitangent1.x = f * (-deltaUV2.x * edge1.x + deltaUV1.x * edge2.x); bitangent1.y = f * (-deltaUV2.x * edge1.y + deltaUV1.x * edge2.y); bitangent1.z = f * (-deltaUV2.x * edge1.z + deltaUV1.x * edge2.z); bitangent1 = glm::normalize(bitangent1); // 三角形2 edge1 = pos3 - pos1; edge2 = pos4 - pos1; deltaUV1 = uv3 - uv1; deltaUV2 = uv4 - uv1; f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y); tangent2.x = f * (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x); tangent2.y = f * (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y); tangent2.z = f * (deltaUV2.y * edge1.z - deltaUV1.y * edge2.z); tangent2 = glm::normalize(tangent2); bitangent2.x = f * (-deltaUV2.x * edge1.x + deltaUV1.x * edge2.x); bitangent2.y = f * (-deltaUV2.x * edge1.y + deltaUV1.x * edge2.y); bitangent2.z = f * (-deltaUV2.x * edge1.z + deltaUV1.x * edge2.z); bitangent2 = glm::normalize(bitangent2); // 每个三角形的TB向量提前计算出来 也可以由Geometry shader计算 GLfloat quadVertices[] = { // 位置 // 法向量 // 纹理 // Tangent 向量 // Bitangent 向量 pos1.x, pos1.y, pos1.z, nm.x, nm.y, nm.z, uv1.x, uv1.y, tangent1.x, tangent1.y, tangent1.z, bitangent1.x, bitangent1.y, bitangent1.z, pos2.x, pos2.y, pos2.z, nm.x, nm.y, nm.z, uv2.x, uv2.y, tangent1.x, tangent1.y, tangent1.z, bitangent1.x, bitangent1.y, bitangent1.z, pos3.x, pos3.y, pos3.z, nm.x, nm.y, nm.z, uv3.x, uv3.y, tangent1.x, tangent1.y, tangent1.z, bitangent1.x, bitangent1.y, bitangent1.z, pos1.x, pos1.y, pos1.z, nm.x, nm.y, nm.z, uv1.x, uv1.y, tangent2.x, tangent2.y, tangent2.z, bitangent2.x, bitangent2.y, bitangent2.z, pos3.x, pos3.y, pos3.z, nm.x, nm.y, nm.z, uv3.x, uv3.y, tangent2.x, tangent2.y, tangent2.z, bitangent2.x, bitangent2.y, bitangent2.z, pos4.x, pos4.y, pos4.z, nm.x, nm.y, nm.z, uv4.x, uv4.y, tangent2.x, tangent2.y, tangent2.z, bitangent2.x, bitangent2.y, bitangent2.z }; glGenVertexArrays(1, &quadVAOId); glGenBuffers(1, &quadVBOId); glBindVertexArray(quadVAOId); glBindBuffer(GL_ARRAY_BUFFER, quadVBOId); glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 14 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat))); glEnableVertexAttribArray(3); glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(GLfloat), (GLvoid*)(8 * sizeof(GLfloat))); glEnableVertexAttribArray(4); glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(GLfloat), (GLvoid*)(11 * sizeof(GLfloat))); glBindVertexArray(0); }