diff --git a/res/chapter9/cube_map.frag b/res/chapter9/cube_map.frag new file mode 100644 index 0000000..0ba884d --- /dev/null +++ b/res/chapter9/cube_map.frag @@ -0,0 +1,12 @@ +#ifdef GL_ES +precision mediump float; +#endif + +varying vec3 v_reflect; +uniform samplerCube u_cubeTex; +uniform vec4 u_color; + +void main(void) +{ + gl_FragColor = textureCube(u_cubeTex, v_reflect) * u_color; +} diff --git a/res/chapter9/cube_map.vert b/res/chapter9/cube_map.vert new file mode 100644 index 0000000..61f2d15 --- /dev/null +++ b/res/chapter9/cube_map.vert @@ -0,0 +1,16 @@ +attribute vec4 a_position; +attribute vec3 a_normal; + +varying vec3 v_reflect; + +void main(void) +{ + gl_Position = CC_MVPMatrix * a_position; + + // compute reflect + vec4 positionWorldViewSpace = CC_MVMatrix * a_position;; + vec3 vEyeVertex = normalize(positionWorldViewSpace.xyz); + + vec3 v_normalVector = CC_NormalMatrix * a_normal; + v_reflect = normalize(reflect(-vEyeVertex, v_normalVector)); +} diff --git a/res/chapter9/skybox/back.jpg b/res/chapter9/skybox/back.jpg new file mode 100644 index 0000000..22842e5 Binary files /dev/null and b/res/chapter9/skybox/back.jpg differ diff --git a/res/chapter9/skybox/bottom.jpg b/res/chapter9/skybox/bottom.jpg new file mode 100644 index 0000000..e344ddb Binary files /dev/null and b/res/chapter9/skybox/bottom.jpg differ diff --git a/res/chapter9/skybox/front.jpg b/res/chapter9/skybox/front.jpg new file mode 100644 index 0000000..6e084e9 Binary files /dev/null and b/res/chapter9/skybox/front.jpg differ diff --git a/res/chapter9/skybox/left.jpg b/res/chapter9/skybox/left.jpg new file mode 100644 index 0000000..5ca9da9 Binary files /dev/null and b/res/chapter9/skybox/left.jpg differ diff --git a/res/chapter9/skybox/right.jpg b/res/chapter9/skybox/right.jpg new file mode 100644 index 0000000..074e198 Binary files /dev/null and b/res/chapter9/skybox/right.jpg differ diff --git a/res/chapter9/skybox/top.jpg b/res/chapter9/skybox/top.jpg new file mode 100644 index 0000000..d0047ad Binary files /dev/null and b/res/chapter9/skybox/top.jpg differ diff --git a/res/chapter9/teapot.c3b b/res/chapter9/teapot.c3b new file mode 100755 index 0000000..a16097d Binary files /dev/null and b/res/chapter9/teapot.c3b differ diff --git a/res/chapter9/teapot.png b/res/chapter9/teapot.png new file mode 100755 index 0000000..65c3aae Binary files /dev/null and b/res/chapter9/teapot.png differ diff --git a/src/chapter9/Chapter9.cpp b/src/chapter9/Chapter9.cpp index d861efb..ff0ce04 100644 --- a/src/chapter9/Chapter9.cpp +++ b/src/chapter9/Chapter9.cpp @@ -9,6 +9,7 @@ #include "Chapter9_8.h" #include "Chapter9_9.h" #include "Chapter9_10.h" +#include "Chapter9_11.h" USING_NS_CC; @@ -184,6 +185,17 @@ bool Chapter9::init() mainmenu->addChild(menuItem,2); mainmenu->setPosition(Vec2::ZERO); + // add "Skybox and CubeMap" + itemlabel = LabelTTF::create("Skybox and CubeMap", "Arial", 24); + menuItem = MenuItemLabel::create(itemlabel); + menuItem->setCallback([&](cocos2d::Ref *sender) { + Director::getInstance()->replaceScene(Chapter9_11::createScene()); + }); + menuItem->setPosition(Vec2(origin.x+visibleSize.width/2, origin.y+visibleSize.height/2).x, + (Vec2(origin.x+visibleSize.width/2, origin.y+visibleSize.height).y - (++index) * 40)); + + mainmenu->addChild(menuItem); + // add main menu this->addChild(mainmenu, 1); diff --git a/src/chapter9/Chapter9_11.cpp b/src/chapter9/Chapter9_11.cpp new file mode 100755 index 0000000..5e2cb4c --- /dev/null +++ b/src/chapter9/Chapter9_11.cpp @@ -0,0 +1,113 @@ +#include "Chapter9_11.h" +#include "Chapter9.h" + +#include "3d/CCSprite3D.h" +#include "3d/CCTextureCube.h" +#include "3d/CCSkybox.h" + + +USING_NS_CC; + +static int TeapotTag = 100; +static int PlayerTag = 101; + +Scene* Chapter9_11::createScene() +{ + Size visibleSize = Director::getInstance()->getVisibleSize(); + Vec2 origin = Director::getInstance()->getVisibleOrigin(); + auto winSize = Director::getInstance()->getWinSize(); + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // create a scene + // 'scene' is an autorelease object + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + auto scene = Scene::create(); + + // add title + auto label = LabelTTF::create("Skybox and CubeMap", "Arial", 24); + label->setPosition(Vec2(origin.x+visibleSize.width/2, origin.y+visibleSize.height/2).x, + Vec2(origin.x+visibleSize.width/2, origin.y+visibleSize.height).y - 30); + + scene->addChild(label, -1); + + //add the menu item for back to main menu + label = LabelTTF::create("MainMenu", "Arial", 24); + auto menuItem = MenuItemLabel::create(label); + menuItem->setCallback([&](cocos2d::Ref *sender) { + Director::getInstance()->replaceScene(Chapter9::createScene()); + }); + auto menu = Menu::create(menuItem, nullptr); + menu->setPosition( Vec2::ZERO ); + menuItem->setPosition( Vec2(origin.x+visibleSize.width - 80, origin.y + 25) ); + scene->addChild(menu, 1); + + auto layer = Layer::create(); + scene->addChild(layer); + + auto _camera = Camera::createPerspective(60, visibleSize.width / visibleSize.height, 10, 1000); + _camera->setPosition3D(Vec3(0.f, 0.f, 50.f)); + _camera->setCameraFlag(CameraFlag::USER1); + + //create and set our custom shader + auto shader = GLProgram::createWithFilenames("chapter9/cube_map.vert", "chapter9/cube_map.frag"); + auto state = GLProgramState::create(shader); + + // create the second texture for cylinder + auto _textureCube = TextureCube::create("chapter9/skybox/left.jpg", "chapter9/skybox/right.jpg", + "chapter9/skybox/top.jpg", "chapter9/skybox/bottom.jpg", + "chapter9/skybox/front.jpg", "chapter9/skybox/back.jpg"); + + //set texture parameters + Texture2D::TexParams tRepeatParams; + tRepeatParams.magFilter = GL_LINEAR; + tRepeatParams.minFilter = GL_LINEAR; + tRepeatParams.wrapS = GL_MIRRORED_REPEAT; + tRepeatParams.wrapT = GL_MIRRORED_REPEAT; + _textureCube->setTexParameters(tRepeatParams); + + // pass the texture sampler to our custom shader + state->setUniformTexture("u_cubeTex", _textureCube); + + // create a teapot + auto _teapot = Sprite3D::create("chapter9/teapot.c3b"); + _teapot->setGLProgramState(state); + _teapot->setPosition3D(Vec3(0, -5, 0)); + _teapot->setRotation3D(Vec3(-90, 180, 0)); + + auto rotate_action = RotateBy::create(1.5, Vec3(0, 30, 0)); + _teapot->runAction(RepeatForever::create(rotate_action)); + + //pass mesh's attribute to shader + long offset = 0; + auto attributeCount = _teapot->getMesh()->getMeshVertexAttribCount(); + for (auto i = 0; i < attributeCount; i++) + { + auto meshattribute = _teapot->getMesh()->getMeshVertexAttribute(i); + state->setVertexAttribPointer(s_attributeNames[meshattribute.vertexAttrib], + meshattribute.size, + meshattribute.type, + GL_FALSE, + _teapot->getMesh()->getVertexSizeInBytes(), + (GLvoid*)offset); + + offset += meshattribute.attribSizeBytes; + } + + layer->addChild(_teapot, 0, TeapotTag); + + { + // config skybox + auto _skyBox = Skybox::create(); + + _skyBox->setTexture(_textureCube); + _skyBox->setScale(700.f); + + layer->addChild(_skyBox); + } + + layer->addChild(_camera); + layer->setCameraMask(2); + + // return the scene + return scene; +} diff --git a/src/chapter9/Chapter9_11.h b/src/chapter9/Chapter9_11.h new file mode 100755 index 0000000..42a1d65 --- /dev/null +++ b/src/chapter9/Chapter9_11.h @@ -0,0 +1,21 @@ +#ifndef __CHAPTER_9_11_H__ +#define __CHAPTER_9_11_H__ + +#include "cocos2d.h" + +USING_NS_CC; + +namespace cocos2d +{ + class TextureCube; + class Skybox; + class Sprite3D; +} + +class Chapter9_11 : public Ref +{ +public: + static cocos2d::Scene* createScene(); +}; + +#endif // __CHAPTER_9_9_H__ \ No newline at end of file