2812人阅读 评论(13)

复合变换

背景

Mn * Mn-1 * ... * M0 * V = (Mn* Mn-1 * ... * M0) * V

N = Mn * Mn-1 * ... * M0

Mn * Mn-1 * ... * M0 * V = (Mn * Mn-1 * ... * M0) * V = N * V

源代码详解

(1)
#define ToRadian(x) ((x) * M_PI / 180.0f)

#define ToDegree(x) ((x) * 180.0f / M_PI)

(2)

inline Matrix4f operator*(const Matrix4f& Right) const
{
Matrix4f Ret;
for (unsigned int i = 0 ; i < 4 ; i++) {
for (unsigned int j = 0 ; j < 4 ; j++) {
Ret.m[i][j] = m[i][0] * Right.m[0][j] +
m[i][1] * Right.m[1][j] +
m[i][2] * Right.m[2][j] +
m[i][3] * Right.m[3][j];
}
}

return Ret;
}

(3)


class Pipeline
{
public:
Pipeline() { ... }
void Scale(float ScaleX, float ScaleY, float ScaleZ) { ... }
void WorldPos(float x, float y, float z) { ... }
void Rotate(float RotateX, float RotateY, float RotateZ) { ... }
const Matrix4f* GetTrans();
private:
Vector3f m_scale;
Vector3f m_worldPos;
Vector3f m_rotateInfo;
Matrix4f m_transformation;
};


(4)

const Matrix4f* Pipeline::GetTrans()
{
Matrix4f ScaleTrans, RotateTrans, TranslationTrans;
InitScaleTransform(ScaleTrans);
InitRotateTransform(RotateTrans);
InitTranslationTransform(TranslationTrans);
m_transformation = TranslationTrans * RotateTrans * ScaleTrans;
return &m_transformation;
}


(5)

Pipeline p;
p.Scale(sinf(Scale * 0.1f), sinf(Scale * 0.1f), sinf(Scale * 0.1f));
p.WorldPos(sinf(Scale), 0.0f, 0.0f);
p.Rotate(sinf(Scale) * 90.0f, sinf(Scale) * 90.0f, sinf(Scale) * 90.0f);
glUniformMatrix4fv(gWorldLocation, 1, GL_TRUE, (const GLfloat*)p.GetTrans());


示例Demo


#include <stdio.h>
#include <string.h>

#include <math.h>
#include <GL/glew.h>
#include <GL/freeglut.h>

#include "ogldev_util.h"
#include "ogldev_pipeline.h"

GLuint VBO;
GLuint IBO;
GLuint gWorldLocation;

static void RenderSceneCB()
{
glClear(GL_COLOR_BUFFER_BIT);

static float Scale = 0.0f;

Scale += 0.001f;

Pipeline p;
p.Scale(sinf(Scale * 0.1f), sinf(Scale * 0.1f), sinf(Scale * 0.1f));
p.WorldPos(sinf(Scale), 0.0f, 0.0f);
p.Rotate(sinf(Scale) * 90.0f, sinf(Scale) * 90.0f, sinf(Scale) * 90.0f);
glUniformMatrix4fv(gWorldLocation, 1, GL_TRUE, (const GLfloat*)p.GetWorldTrans());

glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);

glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_INT, 0);

glDisableVertexAttribArray(0);

glutSwapBuffers();
}

static void InitializeGlutCallbacks()
{
glutDisplayFunc(RenderSceneCB);
glutIdleFunc(RenderSceneCB);
}

static void CreateVertexBuffer()
{
Vector3f Vertices[4];
Vertices[0] = Vector3f(-1.0f, -1.0f, 0.0f);
Vertices[1] = Vector3f(0.0f, -1.0f, 1.0f);
Vertices[2] = Vector3f(1.0f, -1.0f, 0.0f);
Vertices[3] = Vector3f(0.0f, 1.0f, 0.0f);

glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
}

static void CreateIndexBuffer()
{
unsigned int Indices[] = { 0, 3, 1,
1, 3, 2,
2, 3, 0,
0, 1, 2 };

glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
}

{

exit(1);
}

const GLchar* p[1];
GLint Lengths[1];
GLint success;
if (!success) {
GLchar InfoLog[1024];
exit(1);
}

}

{

exit(1);
}

string vs, fs;

exit(1);
};

exit(1);
};

GLint Success = 0;
GLchar ErrorLog[1024] = { 0 };

if (Success == 0) {
exit(1);
}

if (!Success) {
fprintf(stderr, "Invalid shader program: '%s'\n", ErrorLog);
exit(1);
}

assert(gWorldLocation != 0xFFFFFFFF);
}

int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowSize(1024, 768);
glutInitWindowPosition(100, 100);
glutCreateWindow("Tutorial 11");

InitializeGlutCallbacks();

// Must be done after glut is initialized!
GLenum res = glewInit();
if (res != GLEW_OK) {
fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));
return 1;
}

printf("GL version: %s\n", glGetString(GL_VERSION));

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

CreateVertexBuffer();
CreateIndexBuffer();

glutMainLoop();

return 0;
}



#version 330

layout (location = 0) in vec3 Position;

uniform mat4 gWorld;

out vec4 Color;

void main()
{
gl_Position = gWorld * vec4(Position, 1.0);
Color = vec4(clamp(Position, 0.0, 1.0), 1.0);
}



#version 330

in vec4 Color;

out vec4 FragColor;

void main()
{
FragColor = Color;
}


运行效果

2
0

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：452622次
• 积分：4943
• 等级：
• 排名：第6680名
• 原创：91篇
• 转载：17篇
• 译文：30篇
• 评论：229条
关于我
人生苦短，道阻且艰；修行不易，且行且努力。

【专业兴趣】：
游戏开发，图形学，图像处理与计算机视觉，iOS平台

【专业技能】：
iOS，游戏开发

【个人主页】：信厚的独立博客
【个人项目】：个人项目
【GitHub】：jiangxh1992
【邮箱】：jiangxinhou艾特outlook点com
我的微博
时空隧道
博客专栏
 iOS沉思录 文章：49篇 阅读：84157
 一步步学OpenGL3.3+ 文章：30篇 阅读：122294
世界在看我>_<
把广告压下去