光照贴图


漫反射贴图(Diffuse texture)

我们希望通过某种方式对每个原始像素独立设置diffuse颜色。它基本就是一个纹理:使用一张图片覆盖住物体,以便我们为每个原始像素索引独立颜色值。在光照场景中,通过纹理来呈现一个物体的diffuse颜色,这个做法被称做漫反射贴图(Diffuse texture)。

贴图:


在片段着色器中,我们创建一个结构体(Struct),来储存物体的材质属性。
struct Material
{
    sampler2D diffuse; //移除amibient材质颜色向量,因为ambient颜色绝大多数情况等于diffuse颜色,所以不需要分别去储存它
    sampler2D specular;
    float shininess;
}; //材质结构体
uniform Material mater;
要记住的是sampler2D也叫做模糊类型,这意味着我们不能以某种类型对它实例化,只能用uniform定义它们。如果我们用结构体而不是uniform实例化(就像函数的参数那样),GLSL会抛出奇怪的错误;这同样也适用于其他模糊类型。

注意,在片段着色器中我们将会再次需要纹理坐标,所以我们声明一个额外输入变量。然后我们简单地从纹理采样,来获得原始像素的diffuse颜色值:
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));

同样,不要忘记把ambient材质的颜色设置为diffuse材质的颜色:
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));


全部fragment shader:
//lightmap.fsh, 物体的fragment shader, 实现光照贴图

varying vec3 v_normal; //需要把法向量由顶点着色器传递到片段着色器
varying vec3 v_fragpos; //片段的位置,用以计算每个片段的法向量
varying vec2 v_texCoord; //纹理坐标

//uniform vec3 objectColor;
//uniform vec3 lightColor;
uniform vec3 lightpos; //传入灯光的位置
uniform vec3 viewPos; //摄像机位置, 观察者的世界空间坐标,我们简单地使用摄像机对象的位置坐标代替(它就是观察者)

struct Material
{
    sampler2D diffuse; //移除amibient材质颜色向量,因为ambient颜色绝大多数情况等于diffuse颜色,所以不需要分别去储存它
    sampler2D specular;
    float shininess;
}; //材质结构体
uniform Material mater;

struct LightStrength
{
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
}; //光照强度
uniform LightStrength lsth;

void main()
{
    vec3 texdiffuse = vec3(texture2D(mater.diffuse, v_texCoord));

    //环境光
    vec3 ambient = lsth.ambient * texdiffuse;
    
    //漫反射
    vec3 norm = normalize(v_normal);
    vec3 lightdir = normalize(lightpos - v_fragpos);
    float diff = max(dot(norm, lightdir), 0.0);
    vec3 diffuse = lsth.diffuse * diff * texdiffuse;
    
    //镜面反射
    float specularStrenth = 0.5; //镜面强度
    vec3 viewDir = normalize(viewPos - v_fragpos);
    vec3 reflectDir = reflect(-lightdir, norm);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), mater.shininess); //这个32是高光的发光值(Shininess)。一个物体的发光值越高,反射光的能力越强,散射得越少,高光点越小。
    vec3 specular = lsth.specular * spec * vec3(texture2D(mater.specular, v_texCoord));
    
    vec3 result = ambient + diffuse + specular;
    gl_FragColor = vec4(result, 1.0);
}


顶点数据现在包括了顶点位置,法线向量和纹理坐标,每个立方体的顶点都有这些属性。让我们更新顶点着色器来接受纹理坐标作为顶点属性,然后发送到片段着色器:

GLfloat vertices[] = {
        // Positions           // Normals           // Texture Coords
        -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 0.0f,
        0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 0.0f,
        0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 1.0f,
        0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 1.0f,
        -0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 0.0f,
        
        -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   0.0f, 0.0f,
        0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   1.0f, 0.0f,
        0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   1.0f, 1.0f,
        0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   1.0f, 1.0f,
        -0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   0.0f, 0.0f,
        
        -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  1.0f, 0.0f,
        -0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  1.0f, 1.0f,
        -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  0.0f, 0.0f,
        -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  1.0f, 0.0f,
        
        0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f, 0.0f,
        0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  1.0f, 1.0f,
        0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
        0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
        0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  0.0f, 0.0f,
        0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f, 0.0f,
        
        -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  0.0f, 1.0f,
        0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  1.0f, 1.0f,
        0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  1.0f, 0.0f,
        0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  1.0f, 0.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  0.0f, 0.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  0.0f, 1.0f,
        
        -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f, 1.0f,
        0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  1.0f, 1.0f,
        0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  1.0f, 0.0f,
        0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  1.0f, 0.0f,
        -0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  0.0f, 0.0f,
        -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f, 1.0f
    };

顶点着色器:
//lightmap.vsh, 物体的vertex shader
attribute vec3 a_position;
attribute vec3 a_normal;
attribute vec2 a_texCoord; //纹理坐标

varying vec3 v_normal; //把法向量传给 fragment shader
varying vec3 v_fragpos; //片段的位置
varying vec2 v_texCoord; //纹理坐标

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main(){
    gl_Position = projection * view * model * vec4(a_position, 1.0);
    v_fragpos = vec3(model * vec4(a_position, 1.0));
    v_normal = a_normal;
    v_texCoord = a_texCoord;
}

给fragment shader 的 纹理传值:

    GL::bindTexture2DN(0, diffuseTexture);
    glUniform1i(glGetUniformLocation(program->getProgram(), "mater.diffuse"), 0);

镜面贴图(specular map)

我们同样用一个纹理贴图,来获得镜面高光。这意味着我们需要生成一个黑白(或者你喜欢的颜色)纹理来定义specular亮度,把它应用到物体的每个部分。贴图:


一个specular高光的亮度可以通过图片中每个纹理的亮度来获得。specular贴图的每个像素可以显示为一个颜色向量,比如:在那里黑色代表颜色向量vec3(0.0f),灰色是vec3(0.5f)。在片段着色器中,我们采样相应的颜色值,把它乘以光的specular亮度。像素越“白”,乘积的结果越大,物体的specualr部分越亮。

由于箱子几乎是由木头组成,木头作为一个材质不会有镜面高光,整个木头部分的diffuse纹理被用黑色覆盖:黑色部分不会包含任何specular高光。箱子的铁边有一个修改的specular亮度,它自身更容易受到镜面高光影响,木纹部分则不会。

从技术上来讲,木头也有镜面高光,尽管这个闪亮值很小(更多的光被散射),影响很小,但是为了学习目的,我们可以假装木头不会有任何specular光反射。

使用Photoshop或Gimp之类的工具,通过将图片进行裁剪,将某部分调整成黑白图样,并调整亮度/对比度的做法,可以非常容易将一个diffuse纹理贴图处理为specular贴图。

全部代码:

//
//  OpenGLLightingMap.cpp
//  shaderTest
//  
//  Created by MacSBL on 2017/1/10.
//
//

#include "OpenGLLightingMap.h"

bool OpenGLLightingMap::init()
{
    if (!Layer::init()) {
        return false;
    }
    origin = Director::getInstance()->getVisibleOrigin();
    vsize = Director::getInstance()->getVisibleSize();
    
    GLfloat vertices[] = {
        // Positions           // Normals           // Texture Coords
        -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 0.0f,
        0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 0.0f,
        0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 1.0f,
        0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 1.0f,
        -0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 0.0f,
        
        -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   0.0f, 0.0f,
        0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   1.0f, 0.0f,
        0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   1.0f, 1.0f,
        0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   1.0f, 1.0f,
        -0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   0.0f, 0.0f,
        
        -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  1.0f, 0.0f,
        -0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  1.0f, 1.0f,
        -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  0.0f, 0.0f,
        -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  1.0f, 0.0f,
        
        0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f, 0.0f,
        0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  1.0f, 1.0f,
        0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
        0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
        0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  0.0f, 0.0f,
        0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f, 0.0f,
        
        -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  0.0f, 1.0f,
        0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  1.0f, 1.0f,
        0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  1.0f, 0.0f,
        0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  1.0f, 0.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  0.0f, 0.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  0.0f, 1.0f,
        
        -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f, 1.0f,
        0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  1.0f, 1.0f,
        0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  1.0f, 0.0f,
        0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  1.0f, 0.0f,
        -0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  0.0f, 0.0f,
        -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f, 1.0f
    };
//    auto difsprite = Sprite::create("container2.png");
//    diffuseTexture = difsprite->getTexture()->getName();
    
    auto spcsprite = Sprite::create("container2_specular.png");
    specularTexture = spcsprite->getTexture()->getName();
    
    //以下方法绑定纹理失败,原因: glTexImage2D 中的2个 GL_RGB 都改为 GL_RGBA即可。 跟图片是否有alpha通道有关??
    //绑定纹理
    glGenTextures(1, &diffuseTexture);
    glBindTexture(GL_TEXTURE_2D, diffuseTexture);
    
   
    //纹理环绕方式
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    //纹理过滤
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

     //加载纹理
    Image* img = new Image();
    img->initWithImageFile("container2.png");
    GLsizei width = img->getWidth();
    GLsizei height = img->getHeight();
    unsigned char* imgdata = img->getData();
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgdata);
    glGenerateMipmap(GL_TEXTURE_2D);
    //释放内存,解绑texture
    CC_SAFE_DELETE(img);
    glBindTexture(GL_TEXTURE_2D, 0);
 
    //——————————————————————————————————————————————————————————————————————————————————————————————
    //设置 glprogram
    auto program = new GLProgram();
    program->initWithFilenames("lightmap.vsh", "lightmap.fsh");
    program->link();
    this->setGLProgram(program);
    //——————————————————————————————————————————————————————————————————————————————————————————————
    
    //物体的vao
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    
    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
    //把顶点数据传给 object.vsh vertex shader 的第一个属性(索引为0)
    GLuint posloc = glGetAttribLocation(program->getProgram(), "a_position");
    glVertexAttribPointer(posloc, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(posloc);
    
    //把法向量传给 object.vsh 的a_normal属性,注意:这里不能想当然的认为vertex shader中第2个attribute就是索引为1,必须通过program实事求是的取出它的location
    GLuint normloc = glGetAttribLocation(program->getProgram(), "a_normal");
    glEnableVertexAttribArray(normloc);
    glVertexAttribPointer(normloc, 3, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (GLvoid*)(3*sizeof(GLfloat)));
    
    //纹理坐标传给 vertex shader
    GLuint texloc = glGetAttribLocation(program->getProgram(), "a_texCoord");
    glEnableVertexAttribArray(texloc);
    glVertexAttribPointer(texloc, 2, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (GLvoid*)(6*sizeof(GLfloat)));
    
    glBindVertexArray(0);
    
    
    //灯光的vao, vbo 跟上边一样,灯光和物体使用同一个顶点数组
    glGenVertexArrays(1, &lightvao);
    glBindVertexArray(lightvao);
    
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    
    //把顶点数据传给 light.vsh vertex shader 的第一个属性(索引为0)
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);
    
    glBindVertexArray(0);
    //——————————————————————————————————————————————————————————————————————————————————————————————
    
    lamProgram = new GLProgram();
    lamProgram->initWithFilenames("lamp.vsh", "lamp.fsh");
    lamProgram->link();
    
    //——————————————————————————————————————————————————————————————————————————————————————————————
    //设置转换矩阵
    model = new Mat4();
//    model->rotate(Vec3(1, 1, 0), CC_DEGREES_TO_RADIANS(60));
    
    //camera
    cam = new MyCamera(Vec3(0, 0, 3));
    view = cam->GetViewMatrix();
    
    projection = new Mat4();
    Mat4::createPerspective(cam->Zoom, vsize.width / vsize.height, 0.1, 1000, projection);
    
    lightpos = Vec3(0.6, 0.5, 0.7);
    
    Director::getInstance()->setDepthTest(true);
    

    
    //touch事件
    auto elistener = EventListenerTouchOneByOne::create();
    elistener->onTouchBegan = CC_CALLBACK_2(OpenGLLightingMap::onTouchBegan, this);
    elistener->onTouchMoved = CC_CALLBACK_2(OpenGLLightingMap::onTouchMoved, this);
    elistener->onTouchEnded = CC_CALLBACK_2(OpenGLLightingMap::onTouchEnded, this);
    _eventDispatcher->addEventListenerWithSceneGraphPriority(elistener, this);
    
    return true;
}

void OpenGLLightingMap::visit(cocos2d::Renderer *render, const cocos2d::Mat4 &parentTransform, uint32_t parentflag)
{
    Layer::visit(render, parentTransform, parentflag);
    _command.init(_globalZOrder);
    _command.func = CC_CALLBACK_0(OpenGLLightingMap::onDraw, this);
    Director::getInstance()->getRenderer()->addCommand(&_command);
}

void OpenGLLightingMap::onDraw()
{
    auto program = this->getGLProgram();
    program->use();
    
   
    
    //物体的 model、view、project 矩阵
    model->scale(1);
    view = cam->GetViewMatrix();
    Mat4::createPerspective(cam->Zoom, vsize.width / vsize.height, 0.1, 1000, projection);
    
    GLuint modeloc = glGetUniformLocation(program->getProgram(), "model");
    glUniformMatrix4fv(modeloc, 1, GL_FALSE, model->m);
    
    GLuint viewloc = glGetUniformLocation(program->getProgram(), "view");
    glUniformMatrix4fv(viewloc, 1, GL_FALSE, view->m);
    
    GLuint proloc = glGetUniformLocation(program->getProgram(), "projection");
    glUniformMatrix4fv(proloc, 1, GL_FALSE, projection->m);
    
   

    glUniform3f(glGetUniformLocation(program->getProgram(), "lsth.ambient"), 0.2, 0.2, 0.2);
    glUniform3f(glGetUniformLocation(program->getProgram(), "lsth.diffuse"), 0.5, 0.5, 0.5);
    glUniform3f(glGetUniformLocation(program->getProgram(), "lsth.specular"), 1.0, 1.0, 1.0);
    
    GL::bindTexture2DN(0, diffuseTexture);
    glUniform1i(glGetUniformLocation(program->getProgram(), "mater.diffuse"), 0);
    GL::bindTexture2DN(1, specularTexture);
    glUniform1i(glGetUniformLocation(program->getProgram(), "mater.specular"), 1);
    glUniform1f(glGetUniformLocation(program->getProgram(), "mater.shininess"), 64.0);
    
    GLuint lightposLoc = glGetUniformLocation(program->getProgram(), "lightpos");
    glUniform3f(lightposLoc, lightpos.x, lightpos.y, lightpos.z);
    
    GLuint viewposloc = glGetUniformLocation(program->getProgram(), "viewPos");
    glUniform3f(viewposloc, cam->Position.x, cam->Position.y, cam->Position.z);
    
    
    glBindVertexArray(vao);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glBindVertexArray(0);
    
    //灯光的model、view、project 矩阵
    lamProgram->use();
    modeloc = glGetUniformLocation(lamProgram->getProgram(), "model");
    auto lightmodel = new Mat4();
    lightmodel->translate(lightpos);
    lightmodel->rotate(Vec3(0, 1, 1), CC_DEGREES_TO_RADIANS(30));
    lightmodel->scale(0.2);
    glUniformMatrix4fv(modeloc, 1, GL_FALSE, lightmodel->m);
    
    viewloc = glGetUniformLocation(lamProgram->getProgram(), "view");
    glUniformMatrix4fv(viewloc, 1, GL_FALSE, view->m);
    
    proloc = glGetUniformLocation(lamProgram->getProgram(), "projection");
    glUniformMatrix4fv(proloc, 1, GL_FALSE, projection->m);
    
    glBindVertexArray(lightvao);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glBindVertexArray(0);
}
#pragma mark touch

bool OpenGLLightingMap::onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *evt)
{
    return true;
}

void OpenGLLightingMap::onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *evt)
{
    Vec2 curpos = touch->getLocationInView();
    Vec2 prepos = touch->getPreviousLocationInView();
    GLfloat dx = curpos.x - prepos.x;
    GLfloat dy = curpos.y - prepos.y;
    
    //移动摄像机
    GLfloat camspeed = 0.05f;
        if (curpos.y - prepos.y > 0) { //w
            cam->ProcessKeyboard(Cam_Move::FORWARD, camspeed);
        }else if (curpos.y - prepos.y < 0){ //s
            cam->ProcessKeyboard(Cam_Move::BACKWARD, camspeed);
        }
        else if (curpos.x - prepos.x < 0){ //a
             cam->ProcessKeyboard(Cam_Move::LEFT, camspeed);
        }else if (curpos.x - prepos.x > 0){ //d
            cam->ProcessKeyboard(Cam_Move::RIGHT, camspeed);
        }
    //(3)旋转摄像机
    
//    cam->ProcessMouseMovement(dx, dy);
           //(4)缩放
//    if(fov >= 1 && fov <= 45){
//        fov -= dx * camspeed;
//    }
//    if(fov <= 1){
//        fov = 1;
//    }
//    if(fov >= 45){
//        fov = 45;
//    }
}

void OpenGLLightingMap::onTouchEnded(cocos2d::Touch *touch, cocos2d::Event *evt)
{
    
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值