為了後續的IOS程式開發,
因此為基廉列克這個帳號申請了
Facebook
skype
twitter
QQ
等帳號
目前一切都是空的,陸續建構中。
2013年6月1日 星期六
pure virtual function (C++)
有些時後會發生一種情況,我們必須創立許多類似的類別,
而這些類別必須有某些相同且必要的條件,
同樣以遊戲為例,例如資深工程師制訂了NPC的規格,
各工程師照著規格實作遊戲企劃人員構想的各種NPC
這種情況可以用到virtual function來解決各衍生類別的同名異式,
但無法要求衍生類別一定要實作某些類別的內容,
這時可以利用"pure virtual function(純虛擬函式)"
在原型的尾端接上 = 0 ,就可以使其成為純虛擬函數,
若一個類別中含有pure virtual function,它是無法用來產生物件的,
此種類別只能被當作基底類別,即使我們有在實作檔案中定義詳細的內容,
抽象基礎類別(abstract base class)即是這類的應用。
若資深工程師定義了一個詳細的NPC基底類別讓其他工程師繼承,
他除了要將函數宣告為純虛擬函數外,還有一項重點要注意,
他可能必須適時的使用protected關鍵字。
大部份的時間我們只會用到private與public來區分類別成員的保護性,
但所有衍生類別卻只能透過基底類別的公用函數來存取private member
實務上並不方便,也非必要,因為基底類別並沒辦法用來宣告,
所以我們可以將一些member variable宣告為protected成員,
使其成為衍生類別的private member。
一個類別中如果含有純虛擬函式,則該類別為一「抽象類別」(Abstract class),該類別只能被繼承,而不能用來直接生成實例,如果試圖使用一個抽象類別來生成實例,則會發生編譯錯誤。
另外
根据C++语言标准,在C++中,除struct默认成员是公有的,class默认成员是私有的外,struct和class没有区别。
另一個例子
#include
#include
using namespace std;
class Pet {
public:
virtual string speak() const { return "Pet!"; }
};
class Dog : public Pet {
public:
string speak() const { return "Bark!"; }
};
class Cat : public Pet {
public:
string speak() const { return "Miao!"; }
};
void doSpeak(Pet &animal){
cout << animal.speak() << endl;
}
int main() {
Dog dog;
Cat cat;
Pet pet;
//Late binding for both:
doSpeak(dog);
doSpeak(cat);
doSpeak(pet);
return 0;
}
==================
output結果:
Bark!
Miao!
Pet!
==================
若Pet中的speak( ) 不宣告為virtual,則output:
Pet!
Pet!
Pet!
==================
Dog跟Cat是繼承自Pet這個base class,
經由virtual的宣告,可以在doSpeak中藉由傳進來的類別(Dog or Cat)判斷要做誰的doSpeak();
若Dog或Cat中,不去override speak這個function,當然都會output: Pet!
若將Pet中的speak() 改寫成virtual string speak() const = 0;
( = 0是pure virtual funcion的關鍵字)
則該virtual function會變成pure virtual function,
進而讓Pet這個class變成abstract class,
在程式中宣告任何Pet的Instance都會造成compile error,
一定要有derived class才能去宣告該class的instance。
http://openhome.cc/Gossip/CppGossip/PureVirtualFunction.html
http://stackoverflow.com/questions/9029548/abstract-base-struct-in-c
而這些類別必須有某些相同且必要的條件,
同樣以遊戲為例,例如資深工程師制訂了NPC的規格,
各工程師照著規格實作遊戲企劃人員構想的各種NPC
這種情況可以用到virtual function來解決各衍生類別的同名異式,
但無法要求衍生類別一定要實作某些類別的內容,
這時可以利用"pure virtual function(純虛擬函式)"
class CNPC 進而讓CNPC這個class變成abstract class, {
public:
int Attack() const = 0; ( = 0是pure virtual funcion的關鍵字) int input (float inValue) =0 // 不能使用const,使用了const就變成惟讀函數
}; 在原型的尾端接上 = 0 ,就可以使其成為純虛擬函數,
若一個類別中含有pure virtual function,它是無法用來產生物件的,
此種類別只能被當作基底類別,即使我們有在實作檔案中定義詳細的內容,
抽象基礎類別(abstract base class)即是這類的應用。
若資深工程師定義了一個詳細的NPC基底類別讓其他工程師繼承,
他除了要將函數宣告為純虛擬函數外,還有一項重點要注意,
他可能必須適時的使用protected關鍵字。
大部份的時間我們只會用到private與public來區分類別成員的保護性,
但所有衍生類別卻只能透過基底類別的公用函數來存取private member
實務上並不方便,也非必要,因為基底類別並沒辦法用來宣告,
所以我們可以將一些member variable宣告為protected成員,
使其成為衍生類別的private member。
class CNPC
{
private:
int m_nHP;
int m_nMP;
protected:
void Sleep() const = 0;
public:
int Attack() const = 0;
};NPC的休息動作、HP回復速度等內容要求衍生類別必須自行定義,
利用protected宣告此函數,如此衍生NPC即可擁有私有的休息函數,
又可以達到外界又無法呼叫此休息函數,僅由類別內自己控制。
若此Sleep()沒有宣告為protected而是宣告為private member,
那麼CNPC就必須要提供一個public function讓衍生類別間接呼叫休息函數,
可以做到同樣的效果,但較為麻煩且不必要。一個類別中如果含有純虛擬函式,則該類別為一「抽象類別」(Abstract class),該類別只能被繼承,而不能用來直接生成實例,如果試圖使用一個抽象類別來生成實例,則會發生編譯錯誤。
對於需要制訂清楚的規則與關係時,abstract base class設計是個不錯的方法。 析構函數也可以是虛的,甚至是純虛的,但是構造函數不能是虛的
純虛的析構函數並沒有什麼作用,是虛的就夠了。通常只有在希望將一個類變成抽象類(不能實例化的類),而這個類又沒有合適的函數可以被純虛化的時候,可以使用純虛的析構函數來達到目的。構造函數不能是虛的(為什麼?因為在一個構造函數調用期間,虛機制並不工作),但是你可以可能通過虛函數 virtual clone()(對於拷貝構造函數)或虛函數 virtual create()(對於默認構造函數),得到虛構造函數產生的效果。另外
抽象類別 (Abstract classes)也可以使用struct。根据C++语言标准,在C++中,除struct默认成员是公有的,class默认成员是私有的外,struct和class没有区别。
如下:
class Shape { // 這是一個 抽象類別 (Abstract classes) public:
virtual ~Shape() { } // 虛析構函數
virtual void draw() = 0; // 純虛函數
virtual void move() = 0;
// ...
virtual Shape* clone() const = 0; // 使用拷貝構造函數
virtual Shape* create() const = 0; // 使用默認構造函數
};
class Circle : public Shape { // Shape被繼承
public:
Circle* clone() const { return new Circle(*this); }
Circle* create() const { return new Circle(); }
// ...
}; 在 clone() 成員函數中,代碼 new Circle(*this) 調用 Circle 的拷貝構造函數來複製this的狀態到新創建的Circle對象。在 create()成員函數中,代碼 new Circle() 調用Circle的默認構造函數。
在Circle中的clone及create將會覆蓋Shape中的clone及create這兩個Function。因此 呼叫 class Shape 的函數 area() 會用到 Class Circle 的 函數 area()。 此處可參考 http://nknucc.nknu.edu.tw/~jwu/c/cpgch16.htm 查閱抽象類別的說明用戶將它們看作「虛構造函數」來使用它們:
void userCode(Shape& s)
{
Shape* s2 = s.clone();
Shape* s3 = s.create();
// ...
delete s2; // 在此處,你可能需要虛析構函數
delete s3;
} 這個函數將正確工作,而不管 Shape 是一個Circle,Square,或是其他種類的 Shape,甚至它們還並不存在。 另一個例子
#include
#include
using namespace std;
class Pet {
public:
virtual string speak() const { return "Pet!"; }
};
class Dog : public Pet {
public:
string speak() const { return "Bark!"; }
};
class Cat : public Pet {
public:
string speak() const { return "Miao!"; }
};
void doSpeak(Pet &animal){
cout << animal.speak() << endl;
}
int main() {
Dog dog;
Cat cat;
Pet pet;
//Late binding for both:
doSpeak(dog);
doSpeak(cat);
doSpeak(pet);
return 0;
}
==================
output結果:
Bark!
Miao!
Pet!
==================
若Pet中的speak( ) 不宣告為virtual,則output:
Pet!
Pet!
Pet!
==================
Dog跟Cat是繼承自Pet這個base class,
經由virtual的宣告,可以在doSpeak中藉由傳進來的類別(Dog or Cat)判斷要做誰的doSpeak();
若Dog或Cat中,不去override speak這個function,當然都會output: Pet!
若將Pet中的speak() 改寫成virtual string speak() const = 0;
( = 0是pure virtual funcion的關鍵字)
則該virtual function會變成pure virtual function,
進而讓Pet這個class變成abstract class,
在程式中宣告任何Pet的Instance都會造成compile error,
一定要有derived class才能去宣告該class的instance。
參考網址http://ascii-iicsa.blogspot.tw/2010/08/pure-virtual-functionabstract-base.htmlhttp://blog.xuite.net/coolflame/code/16605599http://iceis.pixnet.net/blog/post/2046006-virtual-function-in-c%2B%2Bhttp://openhome.cc/Gossip/CppGossip/PureVirtualFunction.html
http://stackoverflow.com/questions/9029548/abstract-base-struct-in-c
C++中 iterator 和 const_iterator的區別
您可以使用容器類別的begin()方法傳回基於STL的迭代器,它指向容器的第一個元素位址,end()方法則傳回指向容器最後一個元素之後的位址。您可以如下使用基於STL的迭代器:
QList<QString> list;
list << "caterpillar" << "momor" << "bush";
QList<QString>::const_iterator i = list.begin();
while (i != list.end()) {
cout << (*i).toAscii().data() << endl; // 唯讀
++i;
}
STL風格的迭代器一樣有兩種,C<T>::const_iterator形式的迭代器宣告為唯讀,則可以讀取資料,不可修改資料,C<T>::const_iterator形式的迭代器則可以修改資料,例如:
QList<QString> list;
list << "caterpillar" << "momor" << "bush";
QList<QString>::iterator i = list.begin();
while (i != list.end()) {
(*i) = (*i) + ".onlyfun"; // 可修改內容
++i;
}
另一個參考例
indices.resize(GetTriangleIndexCount());
vector<unsigned short>::iterator index = indices.begin();
for (int j = 0, vertex = 0; j < m_slices.y; j++) {
for (int i = 0; i < m_slices.x; i++) {
int next = (i + 1) % m_divisions.x;
*index++ = vertex + i; // 內容被修改
*index++ = vertex + next;
*index++ = vertex + i + m_divisions.x;
*index++ = vertex + next;
*index++ = vertex + next + m_divisions.x;
*index++ = vertex + i + m_divisions.x;
}
vertex += m_divisions.x;
}
OPENGLES 的參考書: iPhone 3D Programming
O'Reilly 無償提供網路閱讀及實作範例下載,對OPENGLES的學習非常有效。
網路書址 http://ofps.oreilly.com/titles/9780596804824/
範例網址 http://examples.oreilly.com/9780596804831/readme.html#ModelViewer.SimpleWireframe
感謝 O'Reilly 無私提供
網路書址 http://ofps.oreilly.com/titles/9780596804824/
範例網址 http://examples.oreilly.com/9780596804831/readme.html#ModelViewer.SimpleWireframe
感謝 O'Reilly 無私提供
2013年5月31日 星期五
OpenGL基本實作(八)
這是一個從iphone 3D
Programm書上第三章上改過來的實作例,改成使用xcode4.6.2,並加入兩個切換的Button,除可讓ES1及ES2兩種模式可以切換,也可切換成VBO模式。為了區別各個模式的不同,投射顏色的顯示也改成不同以示區別。本例可以用手指來轉動圓錐體,算是實作五的一個簡化版本,主要用途是為了瞭解VBO及一般模式的區別。
1. 先開一個專案
2.實作上並未用到storyboard,一切都使用動態模式,數學矩陣運算沿用前一個實作的程式,GLSL也是一樣,本例主要加上VBO的部分。檔案列表如下
3. 由於有手指旋轉的功能,因此在GLView.h/.mm上有需要加上手指接觸的指令,並且也需要加上VBO的接面。原本自動旋轉的功能則予以取消。
GLView.h
#import <UIKit/UIKit.h>
#import "IRenderingEngine.hpp"
#import <QuartzCore/QuartzCore.h>
@interface GLView : UIView {
@private
IRenderingEngine* m_renderingEngine;
EAGLContext* m_context;
float m_timestamp;
@public
BOOL ForceES1 ;
BOOL ForceVBO ;
}
- (void) drawView: (CADisplayLink*) displayLink;
- (id) initSet:(CGRect) frame;
@end
GLView.mm
#import "GLView.h"
@implementation GLView
+ (Class) layerClass
{
return [CAEAGLLayer class];
}
- (id) initWithFrame: (CGRect) frame
{
ForceES1 = NO;
ForceVBO = NO;
if (self = [super initWithFrame:frame])
{
if ([self initSet:frame] == nil)
return nil;
}
return self;
}
- (id) initSet:(CGRect) frame
{
CAEAGLLayer* eaglLayer = (CAEAGLLayer*) self.layer;
eaglLayer.opaque = YES;
EAGLRenderingAPI api;
m_context = nil;
if (ForceES1 == NO){
api= kEAGLRenderingAPIOpenGLES2;
}
else {
api= kEAGLRenderingAPIOpenGLES1;
}
m_context = [[EAGLContext alloc] initWithAPI:api];
if (!m_context) {
api = kEAGLRenderingAPIOpenGLES1;
m_context = [[EAGLContext alloc] initWithAPI:api];
}
if (!m_context || ![EAGLContext setCurrentContext:m_context]) {
return nil;
}
if (api == kEAGLRenderingAPIOpenGLES1) {
NSLog(@"Using OpenGL ES 1.1");
if (ForceVBO == NO)
m_renderingEngine = CreateRenderer1();
else
m_renderingEngine = CreateVboRenderer1();
} else {
NSLog(@"Using OpenGL ES 2.0");
if (ForceVBO == NO)
m_renderingEngine = CreateRenderer2();
else
m_renderingEngine = CreateVboRenderer2();
}
[m_context
renderbufferStorage:GL_RENDERBUFFER
fromDrawable: eaglLayer];
m_renderingEngine->Initialize(CGRectGetWidth(frame), CGRectGetHeight(frame));
[self drawView: nil];
m_timestamp = CACurrentMediaTime();
CADisplayLink* displayLink;
displayLink = [CADisplayLink displayLinkWithTarget:self
selector:@selector(drawView:)];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
return self;
}
- (void) drawView: (CADisplayLink*) displayLink
{
if (displayLink != nil) {
float elapsedSeconds = displayLink.timestamp - m_timestamp;
m_timestamp = displayLink.timestamp;
m_renderingEngine->UpdateAnimation(elapsedSeconds);
}
m_renderingEngine->Render();
[m_context presentRenderbuffer:GL_RENDERBUFFER];
}
- (void) touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event
{
UITouch* touch = [touches anyObject];
CGPoint location = [touch locationInView: self];
m_renderingEngine->OnFingerDown(ivec2(location.x, location.y));
}
- (void) touchesEnded: (NSSet*) touches withEvent: (UIEvent*) event
{
UITouch* touch = [touches anyObject];
CGPoint location = [touch locationInView: self];
m_renderingEngine->OnFingerUp(ivec2(location.x, location.y));
}
- (void) touchesMoved: (NSSet*) touches withEvent: (UIEvent*) event
{
UITouch* touch = [touches anyObject];
CGPoint previous = [touch previousLocationInView: self];
CGPoint current = [touch locationInView: self];
m_renderingEngine->OnFingerMove(ivec2(previous.x, previous.y),
ivec2(current.x, current.y));
}
@end
4. IRenderingEngine.hpp要加上手指運作及VBO的部分
#include "Vector.hpp"
// Physical orientation of a handheld device; equivalent to UIDeviceOrientation
enum DeviceOrientation {
DeviceOrientationUnknown,
DeviceOrientationPortrait,
DeviceOrientationPortraitUpsideDown,
DeviceOrientationLandscapeLeft,
DeviceOrientationLandscapeRight,
DeviceOrientationFaceUp,
DeviceOrientationFaceDown,
};
// Creates an instance of the renderer and sets up various OpenGL state.
struct IRenderingEngine* CreateRenderer1();
struct IRenderingEngine* CreateRenderer2();
struct IRenderingEngine* CreateVboRenderer1();
struct IRenderingEngine* CreateVboRenderer2();
// Interface to the OpenGL ES renderer; consumed by Objective C.
struct IRenderingEngine {
virtual void Initialize(int width, int height) = 0;
virtual void Render() const = 0;
virtual void UpdateAnimation(float timeStep) = 0;
virtual void OnRotate(DeviceOrientation newOrientation) = 0;
virtual void OnFingerUp(ivec2 location) = 0;
virtual void OnFingerDown(ivec2 location) = 0;
virtual void OnFingerMove(ivec2 oldLocation, ivec2 newLocation) = 0;
virtual ~IRenderingEngine() {}
};
#include <OpenGLES/ES1/glext.h>
#include "IRenderingEngine.hpp"
#include <vector>
using namespace std;
struct Vertex {
vec3 Position;
vec4 Color;
};
class RenderingEngine1 : public IRenderingEngine {
public:
RenderingEngine1();
void Initialize(int width, int height);
void Render() const;
void UpdateAnimation(float timeStep) {}
void OnRotate(DeviceOrientation newOrientation) {}
void OnFingerUp(ivec2 location);
void OnFingerDown(ivec2 location);
void OnFingerMove(ivec2 oldLocation, ivec2 newLocation);
private:
vector<Vertex> m_coneVertices;
vector<GLubyte> m_coneIndices;
GLfloat m_rotationAngle;
GLfloat m_scale;
ivec2 m_pivotPoint;
GLuint m_framebuffer;
GLuint m_colorRenderbuffer;
GLuint m_depthRenderbuffer;
int m_diskIndexCount;
int m_bodyIndexCount;
};
IRenderingEngine* CreateRenderer1()
{
return new RenderingEngine1();
}
RenderingEngine1::RenderingEngine1() : m_rotationAngle(0), m_scale(1)
{
// Create & bind the color buffer so that the caller can allocate its space.
glGenRenderbuffersOES(1, &m_colorRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_colorRenderbuffer);
}
void RenderingEngine1::Initialize(int width, int height)
{
m_pivotPoint = ivec2(width / 2, height / 2);
const float coneRadius = 0.8f;
const float coneHeight = 1.866f;
const int coneSlices = 40;
const float dtheta = TwoPi / coneSlices;
const int vertexCount = coneSlices * 2 + 1;
const int diskCenterIndex = vertexCount - 1;
m_bodyIndexCount = coneSlices * 3;
m_diskIndexCount = coneSlices * 3;
m_coneVertices.resize(vertexCount);
vector<Vertex>::iterator vertex = m_coneVertices.begin();
// Cone's body
for (float theta = 0; vertex != m_coneVertices.end() - 1; theta += dtheta) {
// Grayscale gradient
float brightness = abs(sin(theta));
vec4 color(brightness*2, brightness, brightness, 1); // 紅色
// Apex vertex
vertex->Position = vec3(0, 1, 0);
vertex->Color = color;
vertex++;
// Rim vertex
vertex->Position.x = coneRadius * cos(theta);
vertex->Position.y = 1 - coneHeight;
vertex->Position.z = coneRadius * sin(theta);
vertex->Color = color;
vertex++;
}
// Disk center
vertex->Position = vec3(0, 1 - coneHeight, 0);
vertex->Color = vec4(1, 1, 1, 1);
m_coneIndices.resize(m_bodyIndexCount + m_diskIndexCount);
vector<GLubyte>::iterator index = m_coneIndices.begin();
// Body triangles
for (int i = 0; i < coneSlices * 2; i += 2) {
*index++ = i;
*index++ = (i + 1) % (2 * coneSlices);
*index++ = (i + 3) % (2 * coneSlices);
}
// Disk triangles
for (int i = 1; i < coneSlices * 2 + 1; i += 2) {
*index++ = diskCenterIndex;
*index++ = i;
*index++ = (i + 2) % (2 * coneSlices);
}
// Create the depth buffer.
glGenRenderbuffersOES(1, &m_depthRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_depthRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES,
GL_DEPTH_COMPONENT16_OES,
width,
height);
// Create the framebuffer object; attach the depth and color buffers.
glGenFramebuffersOES(1, &m_framebuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_framebuffer);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
GL_COLOR_ATTACHMENT0_OES,
GL_RENDERBUFFER_OES,
m_colorRenderbuffer);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
GL_DEPTH_ATTACHMENT_OES,
GL_RENDERBUFFER_OES,
m_depthRenderbuffer);
// Bind the color buffer for rendering.
glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_colorRenderbuffer);
glViewport(0, 0, width, height);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glFrustumf(-1.6f, 1.6, -2.4, 2.4, 5, 10);
glMatrixMode(GL_MODELVIEW);
glTranslatef(0, 0, -7);
}
void RenderingEngine1::Render() const
{
GLsizei stride = sizeof(Vertex);
const GLvoid* pCoords = &m_coneVertices[0].Position.x;
const GLvoid* pColors = &m_coneVertices[0].Color.x;
glClearColor(0.5f, 0.5f, 0.5f, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(m_rotationAngle, 0, 0, 1);
glScalef(m_scale, m_scale, m_scale);
glVertexPointer(3, GL_FLOAT, stride, pCoords);
glColorPointer(4, GL_FLOAT, stride, pColors);
glEnableClientState(GL_VERTEX_ARRAY);
const GLvoid* bodyIndices = &m_coneIndices[0];
const GLvoid* diskIndices = &m_coneIndices[m_bodyIndexCount];
glEnableClientState(GL_COLOR_ARRAY);
glDrawElements(GL_TRIANGLES, m_bodyIndexCount, GL_UNSIGNED_BYTE, bodyIndices);
glDisableClientState(GL_COLOR_ARRAY);
glColor4f(1, 1, 1, 1);
glDrawElements(GL_TRIANGLES, m_diskIndexCount, GL_UNSIGNED_BYTE, diskIndices);
glDisableClientState(GL_VERTEX_ARRAY);
glPopMatrix();
}
void RenderingEngine1::OnFingerUp(ivec2 location)
{
m_scale = 1.0f;
}
void RenderingEngine1::OnFingerDown(ivec2 location)
{
m_scale = 1.5f;
OnFingerMove(location, location);
}
void RenderingEngine1::OnFingerMove(ivec2 previous, ivec2 location)
{
vec2 direction = vec2(location - m_pivotPoint).Normalized();
// Flip the Y axis because pixel coords increase towards the bottom.
direction.y = -direction.y;
m_rotationAngle = std::acos(direction.y) * 180.0f / 3.14159f;
if (direction.x > 0)
m_rotationAngle = -m_rotationAngle;
}
#include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h>
#include "IRenderingEngine.hpp"
#include "Matrix.hpp"
#include <vector>
#include <iostream>
#define STRINGIFY(A) #A
#include "./Simple.vert"
#include "./Simple.frag"
using namespace std;
struct Vertex {
vec3 Position;
vec4 Color;
};
class RenderingEngine2 : public IRenderingEngine {
public:
RenderingEngine2();
void Initialize(int width, int height);
void Render() const;
void UpdateAnimation(float timeStep) {}
void OnRotate(DeviceOrientation newOrientation) {}
void OnFingerUp(ivec2 location);
void OnFingerDown(ivec2 location);
void OnFingerMove(ivec2 oldLocation, ivec2 newLocation);
private:
GLuint BuildShader(const char* source, GLenum shaderType) const;
GLuint BuildProgram(const char* vShader, const char* fShader) const;
vector<Vertex> m_coneVertices;
vector<GLubyte> m_coneIndices;
GLfloat m_rotationAngle;
GLfloat m_scale;
ivec2 m_pivotPoint; // 樞紐
GLuint m_simpleProgram;
GLuint m_framebuffer;
GLuint m_colorRenderbuffer;
GLuint m_depthRenderbuffer;
int m_diskIndexCount;
int m_bodyIndexCount;
};
IRenderingEngine* CreateRenderer2()
{
return new RenderingEngine2();
}
RenderingEngine2::RenderingEngine2() : m_rotationAngle(0), m_scale(1)
{
// Create & bind the color buffer so that the caller can allocate its space.
glGenRenderbuffers(1, &m_colorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer);
}
void RenderingEngine2::Initialize(int width, int height)
{
m_pivotPoint = ivec2(width / 2, height / 2);
const float coneRadius = 0.5f;
const float coneHeight = 1.866f;
const int coneSlices = 40;
const float dtheta = TwoPi / coneSlices;
const int vertexCount = coneSlices * 2 + 1;
const int diskCenterIndex = vertexCount - 1;
m_bodyIndexCount = coneSlices * 3;
m_diskIndexCount = coneSlices * 3;
m_coneVertices.resize(vertexCount);
vector<Vertex>::iterator vertex = m_coneVertices.begin();
// Cone's body
for (float theta = 0; vertex != m_coneVertices.end() - 1; theta += dtheta) {
// Grayscale gradient
float brightness = abs(sin(theta));
vec4 color(brightness, brightness, brightness, 1); // 灰色,初始值
// Apex vertex
vertex->Position = vec3(0, 1, 0);
vertex->Color = color;
vertex++;
// Rim vertex
vertex->Position.x = coneRadius * cos(theta);
vertex->Position.y = 1 - coneHeight;
vertex->Position.z = coneRadius * sin(theta);
vertex->Color = color;
vertex++;
}
// Disk center
vertex->Position = vec3(0, 1 - coneHeight, 0);
vertex->Color = vec4(1, 1, 1, 1);
m_coneIndices.resize(m_bodyIndexCount + m_diskIndexCount);
vector<GLubyte>::iterator index = m_coneIndices.begin();
// Body triangles
for (int i = 0; i < coneSlices * 2; i += 2) {
*index++ = i;
*index++ = (i + 1) % (2 * coneSlices);
*index++ = (i + 3) % (2 * coneSlices);
}
// Disk triangles
for (int i = 1; i < coneSlices * 2 + 1; i += 2) {
*index++ = diskCenterIndex;
*index++ = i;
*index++ = (i + 2) % (2 * coneSlices);
}
// Create the depth buffer.
glGenRenderbuffers(1, &m_depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, m_depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER,
GL_DEPTH_COMPONENT16,
width,
height);
// Create the framebuffer object; attach the depth and color buffers.
glGenFramebuffers(1, &m_framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER,
m_colorRenderbuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER,
m_depthRenderbuffer);
// Bind the color buffer for rendering.
glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer);
glViewport(0, 0, width, height);
glEnable(GL_DEPTH_TEST);
m_simpleProgram = BuildProgram(SimpleVertexShader, SimpleFragmentShader);
glUseProgram(m_simpleProgram);
// Set the projection matrix.
GLint projectionUniform = glGetUniformLocation(m_simpleProgram, "Projection");
mat4 projectionMatrix = mat4::Frustum(-1.6f, 1.6, -2.4, 2.4, 5, 10);
glUniformMatrix4fv(projectionUniform, 1, 0, projectionMatrix.Pointer());
}
void RenderingEngine2::Render() const
{
GLuint positionSlot = glGetAttribLocation(m_simpleProgram, "Position");
GLuint colorSlot = glGetAttribLocation(m_simpleProgram, "SourceColor");
mat4 rotation = mat4::Rotate(m_rotationAngle);
mat4 scale = mat4::Scale(m_scale);
mat4 translation = mat4::Translate(0, 0, -7);
GLint modelviewUniform = glGetUniformLocation(m_simpleProgram, "Modelview");
mat4 modelviewMatrix = scale * rotation * translation;
GLsizei stride = sizeof(Vertex);
const GLvoid* pCoords = &m_coneVertices[0].Position.x;
const GLvoid* pColors = &m_coneVertices[0].Color.x;
glClearColor(0.5f, 0.5f, 0.5f, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUniformMatrix4fv(modelviewUniform, 1, 0, modelviewMatrix.Pointer());
glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, stride, pCoords);
glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, stride, pColors);
glEnableVertexAttribArray(positionSlot);
const GLvoid* bodyIndices = &m_coneIndices[0];
const GLvoid* diskIndices = &m_coneIndices[m_bodyIndexCount];
glEnableVertexAttribArray(colorSlot);
glDrawElements(GL_TRIANGLES, m_bodyIndexCount, GL_UNSIGNED_BYTE, bodyIndices);
glDisableVertexAttribArray(colorSlot);
glVertexAttrib4f(colorSlot, 1, 1, 1, 1);
glDrawElements(GL_TRIANGLES, m_diskIndexCount, GL_UNSIGNED_BYTE, diskIndices);
glDisableVertexAttribArray(positionSlot);
}
void RenderingEngine2::OnFingerUp(ivec2 location)
{
m_scale = 1.0f;
}
void RenderingEngine2::OnFingerDown(ivec2 location)
{
m_scale = 1.5f;
OnFingerMove(location, location);
}
void RenderingEngine2::OnFingerMove(ivec2 previous, ivec2 location)
{
vec2 direction = vec2(location - m_pivotPoint).Normalized();
// Flip the Y axis because pixel coords increase towards the bottom.
direction.y = -direction.y;
m_rotationAngle = std::acos(direction.y) * 180.0f / 3.14159f;
if (direction.x > 0)
m_rotationAngle = -m_rotationAngle;
}
GLuint RenderingEngine2::BuildShader(const char* source, GLenum shaderType) const
{
GLuint shaderHandle = glCreateShader(shaderType);
glShaderSource(shaderHandle, 1, &source, 0);
glCompileShader(shaderHandle);
GLint compileSuccess;
glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &compileSuccess);
if (compileSuccess == GL_FALSE) {
GLchar messages[256];
glGetShaderInfoLog(shaderHandle, sizeof(messages), 0, &messages[0]);
std::cout << messages;
exit(1);
}
return shaderHandle;
}
GLuint RenderingEngine2::BuildProgram(const char* vertexShaderSource,
const char* fragmentShaderSource) const
{
GLuint vertexShader = BuildShader(vertexShaderSource, GL_VERTEX_SHADER);
GLuint fragmentShader = BuildShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
GLuint programHandle = glCreateProgram();
glAttachShader(programHandle, vertexShader);
glAttachShader(programHandle, fragmentShader);
glLinkProgram(programHandle);
GLint linkSuccess;
glGetProgramiv(programHandle, GL_LINK_STATUS, &linkSuccess);
if (linkSuccess == GL_FALSE) {
GLchar messages[256];
glGetProgramInfoLog(programHandle, sizeof(messages), 0, &messages[0]);
std::cout << messages;
exit(1);
}
return programHandle;
}
#include <OpenGLES/ES1/glext.h>
#include "IRenderingEngine.hpp"
#include <vector>
using namespace std;
struct Vertex {
vec3 Position;
vec4 Color;
};
class VboRenderingEngine1 : public IRenderingEngine {
public:
VboRenderingEngine1();
void Initialize(int width, int height);
void Render() const;
void UpdateAnimation(float timeStep) {}
void OnRotate(DeviceOrientation newOrientation) {}
void OnFingerUp(ivec2 location);
void OnFingerDown(ivec2 location);
void OnFingerMove(ivec2 oldLocation, ivec2 newLocation);
private:
GLuint m_vertexBuffer;
GLuint m_indexBuffer;
GLfloat m_rotationAngle;
GLfloat m_scale;
ivec2 m_pivotPoint;
GLuint m_framebuffer;
GLuint m_colorRenderbuffer;
GLuint m_depthRenderbuffer;
int m_diskIndexCount;
int m_bodyIndexCount;
};
IRenderingEngine* CreateVboRenderer1()
{
return new VboRenderingEngine1();
}
VboRenderingEngine1::VboRenderingEngine1() : m_rotationAngle(0), m_scale(1)
{
// Create & bind the color buffer so that the caller can allocate its space.
glGenRenderbuffersOES(1, &m_colorRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_colorRenderbuffer);
}
void VboRenderingEngine1::Initialize(int width, int height)
{
m_pivotPoint = ivec2(width / 2, height / 2);
const float coneRadius = 0.8f;
const float coneHeight = 1.866f;
const int coneSlices = 40;
const float dtheta = TwoPi / coneSlices;
const int vertexCount = coneSlices * 2 + 1;
const int diskCenterIndex = vertexCount - 1;
m_bodyIndexCount = coneSlices * 3;
m_diskIndexCount = coneSlices * 3;
vector<Vertex> coneVertices(vertexCount);
vector<Vertex>::iterator vertex = coneVertices.begin();
// Cone's body
for (float theta = 0; vertex != coneVertices.end() - 1; theta += dtheta) {
// Grayscale gradient
float brightness = abs(sin(theta));
vec4 color(brightness, brightness, brightness*2, 1); // 藍色
// Apex vertex
vertex->Position = vec3(0, 1, 0);
vertex->Color = color;
vertex++;
// Rim vertex
vertex->Position.x = coneRadius * cos(theta);
vertex->Position.y = 1 - coneHeight;
vertex->Position.z = coneRadius * sin(theta);
vertex->Color = color;
vertex++;
}
// Disk center
vertex->Position = vec3(0, 1 - coneHeight, 0);
vertex->Color = vec4(1, 1, 1, 1);
// Create the VBO for the vertices.
glGenBuffers(1, &m_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glBufferData(GL_ARRAY_BUFFER,
coneVertices.size() * sizeof(coneVertices[0]),
&coneVertices[0],
GL_STATIC_DRAW);
vector<GLubyte> coneIndices(m_bodyIndexCount + m_diskIndexCount);
vector<GLubyte>::iterator index = coneIndices.begin();
// Body triangles
for (int i = 0; i < coneSlices * 2; i += 2) {
*index++ = i;
*index++ = (i + 1) % (2 * coneSlices);
*index++ = (i + 3) % (2 * coneSlices);
}
// Disk triangles
for (int i = 1; i < coneSlices * 2 + 1; i += 2) {
*index++ = diskCenterIndex;
*index++ = i;
*index++ = (i + 2) % (2 * coneSlices);
}
// Create the VBO for the indices.
glGenBuffers(1, &m_indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
coneIndices.size() * sizeof(coneIndices[0]),
&coneIndices[0],
GL_STATIC_DRAW);
// Create the depth buffer.
glGenRenderbuffersOES(1, &m_depthRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_depthRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES,
GL_DEPTH_COMPONENT16_OES,
width,
height);
// Create the framebuffer object; attach the depth and color buffers.
glGenFramebuffersOES(1, &m_framebuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_framebuffer);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
GL_COLOR_ATTACHMENT0_OES,
GL_RENDERBUFFER_OES,
m_colorRenderbuffer);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
GL_DEPTH_ATTACHMENT_OES,
GL_RENDERBUFFER_OES,
m_depthRenderbuffer);
// Bind the color buffer for rendering.
glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_colorRenderbuffer);
glViewport(0, 0, width, height);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glFrustumf(-1.6f, 1.6, -2.4, 2.4, 5, 10);
glMatrixMode(GL_MODELVIEW);
glTranslatef(0, 0, -7);
}
void VboRenderingEngine1::Render() const
{
glClearColor(0.5f, 0.5f, 0.5f, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(m_rotationAngle, 0, 0, 1);
glScalef(m_scale, m_scale, m_scale);
const GLvoid* colorOffset = (GLvoid*) sizeof(vec3);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), 0);
glColorPointer(4, GL_FLOAT, sizeof(Vertex), colorOffset);
glEnableClientState(GL_VERTEX_ARRAY);
const GLvoid* bodyOffset = 0;
const GLvoid* diskOffset = (GLvoid*) m_bodyIndexCount;
glEnableClientState(GL_COLOR_ARRAY);
glDrawElements(GL_TRIANGLES, m_bodyIndexCount, GL_UNSIGNED_BYTE, bodyOffset);
glDisableClientState(GL_COLOR_ARRAY);
glColor4f(1, 1, 1, 1);
glDrawElements(GL_TRIANGLES, m_diskIndexCount, GL_UNSIGNED_BYTE, diskOffset);
glDisableClientState(GL_VERTEX_ARRAY);
glPopMatrix();
}
void VboRenderingEngine1::OnFingerUp(ivec2 location)
{
m_scale = 1.0f;
}
void VboRenderingEngine1::OnFingerDown(ivec2 location)
{
m_scale = 1.5f;
OnFingerMove(location, location);
}
void VboRenderingEngine1::OnFingerMove(ivec2 previous, ivec2 location)
{
vec2 direction = vec2(location - m_pivotPoint).Normalized();
// Flip the Y axis because pixel coords increase towards the bottom.
direction.y = -direction.y;
m_rotationAngle = std::acos(direction.y) * 180.0f / 3.14159f;
if (direction.x > 0)
m_rotationAngle = -m_rotationAngle;
}
#include <OpenGLES/ES2/glext.h>
#include "IRenderingEngine.hpp"
#include "Matrix.hpp"
#include <vector>
#include <iostream>
#define STRINGIFY(A) #A
#include "./Simple.vert"
#include "./Simple.frag"
using namespace std;
struct Vertex {
vec3 Position;
vec4 Color;
};
class VboRenderingEngine2 : public IRenderingEngine {
public:
VboRenderingEngine2();
void Initialize(int width, int height);
void Render() const;
void UpdateAnimation(float timeStep) {}
void OnRotate(DeviceOrientation newOrientation) {}
void OnFingerUp(ivec2 location);
void OnFingerDown(ivec2 location);
void OnFingerMove(ivec2 oldLocation, ivec2 newLocation);
private:
GLuint BuildShader(const char* source, GLenum shaderType) const;
GLuint BuildProgram(const char* vShader, const char* fShader) const;
GLuint m_vertexBuffer; // Object handles for VBO
GLuint m_indexBuffer; // Object handles for VBO
GLfloat m_rotationAngle;
GLfloat m_scale;
ivec2 m_pivotPoint;
GLuint m_simpleProgram;
GLuint m_framebuffer;
GLuint m_colorRenderbuffer;
GLuint m_depthRenderbuffer;
int m_diskIndexCount;
int m_bodyIndexCount;
};
IRenderingEngine* CreateVboRenderer2()
{
return new VboRenderingEngine2();
}
VboRenderingEngine2::VboRenderingEngine2() : m_rotationAngle(0), m_scale(1)
{
// Create & bind the color buffer so that the caller can allocate its space.
glGenRenderbuffers(1, &m_colorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer);
}
void VboRenderingEngine2::Initialize(int width, int height)
{
m_pivotPoint = ivec2(width / 2, height / 2);
const float coneRadius = 0.5f;
const float coneHeight = 1.866f;
const int coneSlices = 40;
const float dtheta = TwoPi / coneSlices;
const int vertexCount = coneSlices * 2 + 1;
const int diskCenterIndex = vertexCount - 1;
m_bodyIndexCount = coneSlices * 3;
m_diskIndexCount = coneSlices * 3;
vector<Vertex> coneVertices(vertexCount);
vector<Vertex>::iterator vertex = coneVertices.begin();
// Cone's body
for (float theta = 0; vertex != coneVertices.end() - 1; theta += dtheta) {
// Grayscale gradient
float brightness = abs(sin(theta));
vec4 color(brightness*2, brightness, brightness*2, 1); // 紫色
// Apex vertex
vertex->Position = vec3(0, 1, 0);
vertex->Color = color;
vertex++;
// Rim vertex
vertex->Position.x = coneRadius * cos(theta);
vertex->Position.y = 1 - coneHeight;
vertex->Position.z = coneRadius * sin(theta);
vertex->Color = color;
vertex++;
}
// Disk center
vertex->Position = vec3(0, 1 - coneHeight, 0);
vertex->Color = vec4(1, 1, 1, 1);
// Create the VBO for the vertices.
glGenBuffers(1, &m_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glBufferData(GL_ARRAY_BUFFER,
coneVertices.size() * sizeof(coneVertices[0]),
&coneVertices[0],
GL_STATIC_DRAW);
vector<GLubyte> coneIndices(m_bodyIndexCount + m_diskIndexCount);
vector<GLubyte>::iterator index = coneIndices.begin();
// Body triangles
for (int i = 0; i < coneSlices * 2; i += 2) {
*index++ = i;
*index++ = (i + 1) % (2 * coneSlices);
*index++ = (i + 3) % (2 * coneSlices);
}
// Disk triangles
for (int i = 1; i < coneSlices * 2 + 1; i += 2) {
*index++ = diskCenterIndex;
*index++ = i;
*index++ = (i + 2) % (2 * coneSlices);
}
// Create the VBO for the indices.
glGenBuffers(1, &m_indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
coneIndices.size() * sizeof(coneIndices[0]),
&coneIndices[0],
GL_STATIC_DRAW);
// Create the depth buffer.
glGenRenderbuffers(1, &m_depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, m_depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER,
GL_DEPTH_COMPONENT16,
width,
height);
// Create the framebuffer object; attach the depth and color buffers.
glGenFramebuffers(1, &m_framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER,
m_colorRenderbuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER,
m_depthRenderbuffer);
// Bind the color buffer for rendering.
glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer);
glViewport(0, 0, width, height);
glEnable(GL_DEPTH_TEST);
m_simpleProgram = BuildProgram(SimpleVertexShader, SimpleFragmentShader);
glUseProgram(m_simpleProgram);
// Set the projection matrix.
GLint projectionUniform = glGetUniformLocation(m_simpleProgram, "Projection");
mat4 projectionMatrix = mat4::Frustum(-1.6f, 1.6, -2.4, 2.4, 5, 10);
glUniformMatrix4fv(projectionUniform, 1, 0, projectionMatrix.Pointer());
}
void VboRenderingEngine2::Render() const
{
GLuint positionSlot = glGetAttribLocation(m_simpleProgram, "Position");
GLuint colorSlot = glGetAttribLocation(m_simpleProgram, "SourceColor");
mat4 rotation = mat4::Rotate(m_rotationAngle);
mat4 scale = mat4::Scale(m_scale);
mat4 translation = mat4::Translate(0, 0, -7);
GLint modelviewUniform = glGetUniformLocation(m_simpleProgram, "Modelview");
mat4 modelviewMatrix = scale * rotation * translation;
GLsizei stride = sizeof(Vertex);
const GLvoid* colorOffset = (GLvoid*) sizeof(vec3);
glClearColor(0.5f, 0.5f, 0.5f, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUniformMatrix4fv(modelviewUniform, 1, 0, modelviewMatrix.Pointer());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, stride, 0);
glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, stride, colorOffset);
glEnableVertexAttribArray(positionSlot);
const GLvoid* bodyOffset = 0;
const GLvoid* diskOffset = (GLvoid*) m_bodyIndexCount;
glEnableVertexAttribArray(colorSlot);
glDrawElements(GL_TRIANGLES, m_bodyIndexCount, GL_UNSIGNED_BYTE, bodyOffset);
glDisableVertexAttribArray(colorSlot);
glVertexAttrib4f(colorSlot, 1, 1, 1, 1);
glDrawElements(GL_TRIANGLES, m_diskIndexCount, GL_UNSIGNED_BYTE, diskOffset);
glDisableVertexAttribArray(positionSlot);
}
void VboRenderingEngine2::OnFingerUp(ivec2 location)
{
m_scale = 1.0f;
}
void VboRenderingEngine2::OnFingerDown(ivec2 location)
{
m_scale = 1.5f;
OnFingerMove(location, location);
}
void VboRenderingEngine2::OnFingerMove(ivec2 previous, ivec2 location)
{
vec2 direction = vec2(location - m_pivotPoint).Normalized();
// Flip the Y axis because pixel coords increase towards the bottom.
direction.y = -direction.y;
m_rotationAngle = std::acos(direction.y) * 180.0f / 3.14159f;
if (direction.x > 0)
m_rotationAngle = -m_rotationAngle;
}
GLuint VboRenderingEngine2::BuildShader(const char* source, GLenum shaderType) const
{
GLuint shaderHandle = glCreateShader(shaderType);
glShaderSource(shaderHandle, 1, &source, 0);
glCompileShader(shaderHandle);
GLint compileSuccess;
glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &compileSuccess);
if (compileSuccess == GL_FALSE) {
GLchar messages[256];
glGetShaderInfoLog(shaderHandle, sizeof(messages), 0, &messages[0]);
std::cout << messages;
exit(1);
}
return shaderHandle;
}
GLuint VboRenderingEngine2::BuildProgram(const char* vertexShaderSource,
const char* fragmentShaderSource) const
{
GLuint vertexShader = BuildShader(vertexShaderSource, GL_VERTEX_SHADER);
GLuint fragmentShader = BuildShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
GLuint programHandle = glCreateProgram();
glAttachShader(programHandle, vertexShader);
glAttachShader(programHandle, fragmentShader);
glLinkProgram(programHandle);
GLint linkSuccess;
glGetProgramiv(programHandle, GL_LINK_STATUS, &linkSuccess);
if (linkSuccess == GL_FALSE) {
GLchar messages[256];
glGetProgramInfoLog(programHandle, sizeof(messages), 0, &messages[0]);
std::cout << messages;
exit(1);
}
return programHandle;
}
#import <UIKit/UIKit.h>
#include "GLView.h"
@interface mainViewController : UIViewController
{
UIWindow* m_window;
GLView* controllView;
}
@end
@interface mainViewController ()
@end
@implementation mainViewController
{
UIButton *swBtn;
UIButton *swBtn2;
}
BOOL mode1;
BOOL isVBO;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
CGRect screenBounds = [[UIScreen mainScreen] bounds];
m_window = [[UIWindow alloc] initWithFrame: screenBounds];
controllView = [[GLView alloc] initWithFrame: screenBounds];
[self setButtonInterface];
[self setButtonInterface2];
[controllView addSubview:swBtn];
[controllView addSubview:swBtn2];
[m_window addSubview: controllView];
[m_window makeKeyAndVisible];
mode1 = NO;
isVBO = NO;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)setButtonInterface // 動態產生一個的Button
{
swBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
//動態產生一個RoundedRect 形式的 Button
swBtn.frame = CGRectMake(0,0, 100, 30); // 大小
[swBtn setCenter:CGPointMake(150, 50)];//位置放在x=150, y=50的位置
[swBtn addTarget:self action:@selector(onSwitch) forControlEvents:UIControlEventTouchUpInside];
//設定Button動作呼叫的function在 onHelloActionButton,方式為按下
//_helloActionButton.= @"Action Button";
[swBtn setTitle:@"ES2 Mode" forState:UIControlStateNormal];
//將動態Button上放置Action Button這兩個字
//[self.view addSubview:swBtn];
//將動態Button放到View上展出
}
- (void)setButtonInterface2 // 動態產生一個的Button
{
swBtn2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
//動態產生一個RoundedRect 形式的 Button
swBtn2.frame = CGRectMake(0,0, 100, 30); // 大小
[swBtn2 setCenter:CGPointMake(350, 50)];//位置放在x=150, y=50的位置
[swBtn2 addTarget:self action:@selector(onSwitch1) forControlEvents:UIControlEventTouchUpInside];
//設定Button動作呼叫的function在 onHelloActionButton,方式為按下
//_helloActionButton.= @"Action Button";
[swBtn2 setTitle:@"Normal Mode" forState:UIControlStateNormal];
//將動態Button上放置Action Button這兩個字
//[self.view addSubview:swBtn2];
//將動態Button放到View上展出
}
- (void) onSwitch
{
mode1 = ~mode1;
controllView->ForceES1 = mode1;
[controllView initSet:m_window.frame];
if (mode1 == 0){
[swBtn setTitle:@"ES2 Mode" forState:UIControlStateNormal];
}
else
[swBtn setTitle:@"ES1 Mode" forState:UIControlStateNormal];
}
- (void) onSwitch1
{
isVBO = ~isVBO;
controllView->ForceVBO = isVBO;
[controllView initSet:m_window.frame];
if (isVBO == 0){
[swBtn2 setTitle:@"Normal Mode" forState:UIControlStateNormal];
}
else
[swBtn2 setTitle:@"VBO Mode" forState:UIControlStateNormal];
}
@end
1. 先開一個專案
2.實作上並未用到storyboard,一切都使用動態模式,數學矩陣運算沿用前一個實作的程式,GLSL也是一樣,本例主要加上VBO的部分。檔案列表如下
3. 由於有手指旋轉的功能,因此在GLView.h/.mm上有需要加上手指接觸的指令,並且也需要加上VBO的接面。原本自動旋轉的功能則予以取消。
GLView.h
#import <UIKit/UIKit.h>
#import "IRenderingEngine.hpp"
#import <QuartzCore/QuartzCore.h>
@interface GLView : UIView {
@private
IRenderingEngine* m_renderingEngine;
EAGLContext* m_context;
float m_timestamp;
@public
BOOL ForceES1 ;
BOOL ForceVBO ;
}
- (void) drawView: (CADisplayLink*) displayLink;
- (id) initSet:(CGRect) frame;
@end
GLView.mm
#import "GLView.h"
@implementation GLView
+ (Class) layerClass
{
return [CAEAGLLayer class];
}
- (id) initWithFrame: (CGRect) frame
{
ForceES1 = NO;
ForceVBO = NO;
if (self = [super initWithFrame:frame])
{
if ([self initSet:frame] == nil)
return nil;
}
return self;
}
- (id) initSet:(CGRect) frame
{
CAEAGLLayer* eaglLayer = (CAEAGLLayer*) self.layer;
eaglLayer.opaque = YES;
EAGLRenderingAPI api;
m_context = nil;
if (ForceES1 == NO){
api= kEAGLRenderingAPIOpenGLES2;
}
else {
api= kEAGLRenderingAPIOpenGLES1;
}
m_context = [[EAGLContext alloc] initWithAPI:api];
if (!m_context) {
api = kEAGLRenderingAPIOpenGLES1;
m_context = [[EAGLContext alloc] initWithAPI:api];
}
if (!m_context || ![EAGLContext setCurrentContext:m_context]) {
return nil;
}
if (api == kEAGLRenderingAPIOpenGLES1) {
NSLog(@"Using OpenGL ES 1.1");
if (ForceVBO == NO)
m_renderingEngine = CreateRenderer1();
else
m_renderingEngine = CreateVboRenderer1();
} else {
NSLog(@"Using OpenGL ES 2.0");
if (ForceVBO == NO)
m_renderingEngine = CreateRenderer2();
else
m_renderingEngine = CreateVboRenderer2();
}
[m_context
renderbufferStorage:GL_RENDERBUFFER
fromDrawable: eaglLayer];
m_renderingEngine->Initialize(CGRectGetWidth(frame), CGRectGetHeight(frame));
[self drawView: nil];
m_timestamp = CACurrentMediaTime();
CADisplayLink* displayLink;
displayLink = [CADisplayLink displayLinkWithTarget:self
selector:@selector(drawView:)];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
return self;
}
- (void) drawView: (CADisplayLink*) displayLink
{
if (displayLink != nil) {
float elapsedSeconds = displayLink.timestamp - m_timestamp;
m_timestamp = displayLink.timestamp;
m_renderingEngine->UpdateAnimation(elapsedSeconds);
}
m_renderingEngine->Render();
[m_context presentRenderbuffer:GL_RENDERBUFFER];
}
- (void) touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event
{
UITouch* touch = [touches anyObject];
CGPoint location = [touch locationInView: self];
m_renderingEngine->OnFingerDown(ivec2(location.x, location.y));
}
- (void) touchesEnded: (NSSet*) touches withEvent: (UIEvent*) event
{
UITouch* touch = [touches anyObject];
CGPoint location = [touch locationInView: self];
m_renderingEngine->OnFingerUp(ivec2(location.x, location.y));
}
- (void) touchesMoved: (NSSet*) touches withEvent: (UIEvent*) event
{
UITouch* touch = [touches anyObject];
CGPoint previous = [touch previousLocationInView: self];
CGPoint current = [touch locationInView: self];
m_renderingEngine->OnFingerMove(ivec2(previous.x, previous.y),
ivec2(current.x, current.y));
}
@end
4. IRenderingEngine.hpp要加上手指運作及VBO的部分
#include "Vector.hpp"
// Physical orientation of a handheld device; equivalent to UIDeviceOrientation
enum DeviceOrientation {
DeviceOrientationUnknown,
DeviceOrientationPortrait,
DeviceOrientationPortraitUpsideDown,
DeviceOrientationLandscapeLeft,
DeviceOrientationLandscapeRight,
DeviceOrientationFaceUp,
DeviceOrientationFaceDown,
};
// Creates an instance of the renderer and sets up various OpenGL state.
struct IRenderingEngine* CreateRenderer1();
struct IRenderingEngine* CreateRenderer2();
struct IRenderingEngine* CreateVboRenderer1();
struct IRenderingEngine* CreateVboRenderer2();
// Interface to the OpenGL ES renderer; consumed by Objective C.
struct IRenderingEngine {
virtual void Initialize(int width, int height) = 0;
virtual void Render() const = 0;
virtual void UpdateAnimation(float timeStep) = 0;
virtual void OnRotate(DeviceOrientation newOrientation) = 0;
virtual void OnFingerUp(ivec2 location) = 0;
virtual void OnFingerDown(ivec2 location) = 0;
virtual void OnFingerMove(ivec2 oldLocation, ivec2 newLocation) = 0;
virtual ~IRenderingEngine() {}
};
5.RenderingEngine1.cpp也是一樣的,還要加上接觸後放大,以及手指帶動旋轉的程式。
#include <OpenGLES/ES1/gl.h>#include <OpenGLES/ES1/glext.h>
#include "IRenderingEngine.hpp"
#include <vector>
using namespace std;
struct Vertex {
vec3 Position;
vec4 Color;
};
class RenderingEngine1 : public IRenderingEngine {
public:
RenderingEngine1();
void Initialize(int width, int height);
void Render() const;
void UpdateAnimation(float timeStep) {}
void OnRotate(DeviceOrientation newOrientation) {}
void OnFingerUp(ivec2 location);
void OnFingerDown(ivec2 location);
void OnFingerMove(ivec2 oldLocation, ivec2 newLocation);
private:
vector<Vertex> m_coneVertices;
vector<GLubyte> m_coneIndices;
GLfloat m_rotationAngle;
GLfloat m_scale;
ivec2 m_pivotPoint;
GLuint m_framebuffer;
GLuint m_colorRenderbuffer;
GLuint m_depthRenderbuffer;
int m_diskIndexCount;
int m_bodyIndexCount;
};
IRenderingEngine* CreateRenderer1()
{
return new RenderingEngine1();
}
RenderingEngine1::RenderingEngine1() : m_rotationAngle(0), m_scale(1)
{
// Create & bind the color buffer so that the caller can allocate its space.
glGenRenderbuffersOES(1, &m_colorRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_colorRenderbuffer);
}
void RenderingEngine1::Initialize(int width, int height)
{
m_pivotPoint = ivec2(width / 2, height / 2);
const float coneRadius = 0.8f;
const float coneHeight = 1.866f;
const int coneSlices = 40;
const float dtheta = TwoPi / coneSlices;
const int vertexCount = coneSlices * 2 + 1;
const int diskCenterIndex = vertexCount - 1;
m_bodyIndexCount = coneSlices * 3;
m_diskIndexCount = coneSlices * 3;
m_coneVertices.resize(vertexCount);
vector<Vertex>::iterator vertex = m_coneVertices.begin();
// Cone's body
for (float theta = 0; vertex != m_coneVertices.end() - 1; theta += dtheta) {
// Grayscale gradient
float brightness = abs(sin(theta));
vec4 color(brightness*2, brightness, brightness, 1); // 紅色
// Apex vertex
vertex->Position = vec3(0, 1, 0);
vertex->Color = color;
vertex++;
// Rim vertex
vertex->Position.x = coneRadius * cos(theta);
vertex->Position.y = 1 - coneHeight;
vertex->Position.z = coneRadius * sin(theta);
vertex->Color = color;
vertex++;
}
// Disk center
vertex->Position = vec3(0, 1 - coneHeight, 0);
vertex->Color = vec4(1, 1, 1, 1);
m_coneIndices.resize(m_bodyIndexCount + m_diskIndexCount);
vector<GLubyte>::iterator index = m_coneIndices.begin();
// Body triangles
for (int i = 0; i < coneSlices * 2; i += 2) {
*index++ = i;
*index++ = (i + 1) % (2 * coneSlices);
*index++ = (i + 3) % (2 * coneSlices);
}
// Disk triangles
for (int i = 1; i < coneSlices * 2 + 1; i += 2) {
*index++ = diskCenterIndex;
*index++ = i;
*index++ = (i + 2) % (2 * coneSlices);
}
// Create the depth buffer.
glGenRenderbuffersOES(1, &m_depthRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_depthRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES,
GL_DEPTH_COMPONENT16_OES,
width,
height);
// Create the framebuffer object; attach the depth and color buffers.
glGenFramebuffersOES(1, &m_framebuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_framebuffer);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
GL_COLOR_ATTACHMENT0_OES,
GL_RENDERBUFFER_OES,
m_colorRenderbuffer);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
GL_DEPTH_ATTACHMENT_OES,
GL_RENDERBUFFER_OES,
m_depthRenderbuffer);
// Bind the color buffer for rendering.
glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_colorRenderbuffer);
glViewport(0, 0, width, height);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glFrustumf(-1.6f, 1.6, -2.4, 2.4, 5, 10);
glMatrixMode(GL_MODELVIEW);
glTranslatef(0, 0, -7);
}
void RenderingEngine1::Render() const
{
GLsizei stride = sizeof(Vertex);
const GLvoid* pCoords = &m_coneVertices[0].Position.x;
const GLvoid* pColors = &m_coneVertices[0].Color.x;
glClearColor(0.5f, 0.5f, 0.5f, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(m_rotationAngle, 0, 0, 1);
glScalef(m_scale, m_scale, m_scale);
glVertexPointer(3, GL_FLOAT, stride, pCoords);
glColorPointer(4, GL_FLOAT, stride, pColors);
glEnableClientState(GL_VERTEX_ARRAY);
const GLvoid* bodyIndices = &m_coneIndices[0];
const GLvoid* diskIndices = &m_coneIndices[m_bodyIndexCount];
glEnableClientState(GL_COLOR_ARRAY);
glDrawElements(GL_TRIANGLES, m_bodyIndexCount, GL_UNSIGNED_BYTE, bodyIndices);
glDisableClientState(GL_COLOR_ARRAY);
glColor4f(1, 1, 1, 1);
glDrawElements(GL_TRIANGLES, m_diskIndexCount, GL_UNSIGNED_BYTE, diskIndices);
glDisableClientState(GL_VERTEX_ARRAY);
glPopMatrix();
}
void RenderingEngine1::OnFingerUp(ivec2 location)
{
m_scale = 1.0f;
}
void RenderingEngine1::OnFingerDown(ivec2 location)
{
m_scale = 1.5f;
OnFingerMove(location, location);
}
void RenderingEngine1::OnFingerMove(ivec2 previous, ivec2 location)
{
vec2 direction = vec2(location - m_pivotPoint).Normalized();
// Flip the Y axis because pixel coords increase towards the bottom.
direction.y = -direction.y;
m_rotationAngle = std::acos(direction.y) * 180.0f / 3.14159f;
if (direction.x > 0)
m_rotationAngle = -m_rotationAngle;
}
6.RenderingEngine2.cpp也是一樣的,同樣要加上接觸後放大,以及手指帶動旋轉的程式。
#include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h>
#include "IRenderingEngine.hpp"
#include "Matrix.hpp"
#include <vector>
#include <iostream>
#define STRINGIFY(A) #A
#include "./Simple.vert"
#include "./Simple.frag"
using namespace std;
struct Vertex {
vec3 Position;
vec4 Color;
};
class RenderingEngine2 : public IRenderingEngine {
public:
RenderingEngine2();
void Initialize(int width, int height);
void Render() const;
void UpdateAnimation(float timeStep) {}
void OnRotate(DeviceOrientation newOrientation) {}
void OnFingerUp(ivec2 location);
void OnFingerDown(ivec2 location);
void OnFingerMove(ivec2 oldLocation, ivec2 newLocation);
private:
GLuint BuildShader(const char* source, GLenum shaderType) const;
GLuint BuildProgram(const char* vShader, const char* fShader) const;
vector<Vertex> m_coneVertices;
vector<GLubyte> m_coneIndices;
GLfloat m_rotationAngle;
GLfloat m_scale;
ivec2 m_pivotPoint; // 樞紐
GLuint m_simpleProgram;
GLuint m_framebuffer;
GLuint m_colorRenderbuffer;
GLuint m_depthRenderbuffer;
int m_diskIndexCount;
int m_bodyIndexCount;
};
IRenderingEngine* CreateRenderer2()
{
return new RenderingEngine2();
}
RenderingEngine2::RenderingEngine2() : m_rotationAngle(0), m_scale(1)
{
// Create & bind the color buffer so that the caller can allocate its space.
glGenRenderbuffers(1, &m_colorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer);
}
void RenderingEngine2::Initialize(int width, int height)
{
m_pivotPoint = ivec2(width / 2, height / 2);
const float coneRadius = 0.5f;
const float coneHeight = 1.866f;
const int coneSlices = 40;
const float dtheta = TwoPi / coneSlices;
const int vertexCount = coneSlices * 2 + 1;
const int diskCenterIndex = vertexCount - 1;
m_bodyIndexCount = coneSlices * 3;
m_diskIndexCount = coneSlices * 3;
m_coneVertices.resize(vertexCount);
vector<Vertex>::iterator vertex = m_coneVertices.begin();
// Cone's body
for (float theta = 0; vertex != m_coneVertices.end() - 1; theta += dtheta) {
// Grayscale gradient
float brightness = abs(sin(theta));
vec4 color(brightness, brightness, brightness, 1); // 灰色,初始值
// Apex vertex
vertex->Position = vec3(0, 1, 0);
vertex->Color = color;
vertex++;
// Rim vertex
vertex->Position.x = coneRadius * cos(theta);
vertex->Position.y = 1 - coneHeight;
vertex->Position.z = coneRadius * sin(theta);
vertex->Color = color;
vertex++;
}
// Disk center
vertex->Position = vec3(0, 1 - coneHeight, 0);
vertex->Color = vec4(1, 1, 1, 1);
m_coneIndices.resize(m_bodyIndexCount + m_diskIndexCount);
vector<GLubyte>::iterator index = m_coneIndices.begin();
// Body triangles
for (int i = 0; i < coneSlices * 2; i += 2) {
*index++ = i;
*index++ = (i + 1) % (2 * coneSlices);
*index++ = (i + 3) % (2 * coneSlices);
}
// Disk triangles
for (int i = 1; i < coneSlices * 2 + 1; i += 2) {
*index++ = diskCenterIndex;
*index++ = i;
*index++ = (i + 2) % (2 * coneSlices);
}
// Create the depth buffer.
glGenRenderbuffers(1, &m_depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, m_depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER,
GL_DEPTH_COMPONENT16,
width,
height);
// Create the framebuffer object; attach the depth and color buffers.
glGenFramebuffers(1, &m_framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER,
m_colorRenderbuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER,
m_depthRenderbuffer);
// Bind the color buffer for rendering.
glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer);
glViewport(0, 0, width, height);
glEnable(GL_DEPTH_TEST);
m_simpleProgram = BuildProgram(SimpleVertexShader, SimpleFragmentShader);
glUseProgram(m_simpleProgram);
// Set the projection matrix.
GLint projectionUniform = glGetUniformLocation(m_simpleProgram, "Projection");
mat4 projectionMatrix = mat4::Frustum(-1.6f, 1.6, -2.4, 2.4, 5, 10);
glUniformMatrix4fv(projectionUniform, 1, 0, projectionMatrix.Pointer());
}
void RenderingEngine2::Render() const
{
GLuint positionSlot = glGetAttribLocation(m_simpleProgram, "Position");
GLuint colorSlot = glGetAttribLocation(m_simpleProgram, "SourceColor");
mat4 rotation = mat4::Rotate(m_rotationAngle);
mat4 scale = mat4::Scale(m_scale);
mat4 translation = mat4::Translate(0, 0, -7);
GLint modelviewUniform = glGetUniformLocation(m_simpleProgram, "Modelview");
mat4 modelviewMatrix = scale * rotation * translation;
GLsizei stride = sizeof(Vertex);
const GLvoid* pCoords = &m_coneVertices[0].Position.x;
const GLvoid* pColors = &m_coneVertices[0].Color.x;
glClearColor(0.5f, 0.5f, 0.5f, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUniformMatrix4fv(modelviewUniform, 1, 0, modelviewMatrix.Pointer());
glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, stride, pCoords);
glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, stride, pColors);
glEnableVertexAttribArray(positionSlot);
const GLvoid* bodyIndices = &m_coneIndices[0];
const GLvoid* diskIndices = &m_coneIndices[m_bodyIndexCount];
glEnableVertexAttribArray(colorSlot);
glDrawElements(GL_TRIANGLES, m_bodyIndexCount, GL_UNSIGNED_BYTE, bodyIndices);
glDisableVertexAttribArray(colorSlot);
glVertexAttrib4f(colorSlot, 1, 1, 1, 1);
glDrawElements(GL_TRIANGLES, m_diskIndexCount, GL_UNSIGNED_BYTE, diskIndices);
glDisableVertexAttribArray(positionSlot);
}
void RenderingEngine2::OnFingerUp(ivec2 location)
{
m_scale = 1.0f;
}
void RenderingEngine2::OnFingerDown(ivec2 location)
{
m_scale = 1.5f;
OnFingerMove(location, location);
}
void RenderingEngine2::OnFingerMove(ivec2 previous, ivec2 location)
{
vec2 direction = vec2(location - m_pivotPoint).Normalized();
// Flip the Y axis because pixel coords increase towards the bottom.
direction.y = -direction.y;
m_rotationAngle = std::acos(direction.y) * 180.0f / 3.14159f;
if (direction.x > 0)
m_rotationAngle = -m_rotationAngle;
}
GLuint RenderingEngine2::BuildShader(const char* source, GLenum shaderType) const
{
GLuint shaderHandle = glCreateShader(shaderType);
glShaderSource(shaderHandle, 1, &source, 0);
glCompileShader(shaderHandle);
GLint compileSuccess;
glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &compileSuccess);
if (compileSuccess == GL_FALSE) {
GLchar messages[256];
glGetShaderInfoLog(shaderHandle, sizeof(messages), 0, &messages[0]);
std::cout << messages;
exit(1);
}
return shaderHandle;
}
GLuint RenderingEngine2::BuildProgram(const char* vertexShaderSource,
const char* fragmentShaderSource) const
{
GLuint vertexShader = BuildShader(vertexShaderSource, GL_VERTEX_SHADER);
GLuint fragmentShader = BuildShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
GLuint programHandle = glCreateProgram();
glAttachShader(programHandle, vertexShader);
glAttachShader(programHandle, fragmentShader);
glLinkProgram(programHandle);
GLint linkSuccess;
glGetProgramiv(programHandle, GL_LINK_STATUS, &linkSuccess);
if (linkSuccess == GL_FALSE) {
GLchar messages[256];
glGetProgramInfoLog(programHandle, sizeof(messages), 0, &messages[0]);
std::cout << messages;
exit(1);
}
return programHandle;
}
7.VboRenderingEngine1.cpp除了是VBO的功能之外,同樣也有接觸後放大,以及手指帶動旋轉的程式。
#include <OpenGLES/ES1/gl.h>#include <OpenGLES/ES1/glext.h>
#include "IRenderingEngine.hpp"
#include <vector>
using namespace std;
struct Vertex {
vec3 Position;
vec4 Color;
};
class VboRenderingEngine1 : public IRenderingEngine {
public:
VboRenderingEngine1();
void Initialize(int width, int height);
void Render() const;
void UpdateAnimation(float timeStep) {}
void OnRotate(DeviceOrientation newOrientation) {}
void OnFingerUp(ivec2 location);
void OnFingerDown(ivec2 location);
void OnFingerMove(ivec2 oldLocation, ivec2 newLocation);
private:
GLuint m_vertexBuffer;
GLuint m_indexBuffer;
GLfloat m_rotationAngle;
GLfloat m_scale;
ivec2 m_pivotPoint;
GLuint m_framebuffer;
GLuint m_colorRenderbuffer;
GLuint m_depthRenderbuffer;
int m_diskIndexCount;
int m_bodyIndexCount;
};
IRenderingEngine* CreateVboRenderer1()
{
return new VboRenderingEngine1();
}
VboRenderingEngine1::VboRenderingEngine1() : m_rotationAngle(0), m_scale(1)
{
// Create & bind the color buffer so that the caller can allocate its space.
glGenRenderbuffersOES(1, &m_colorRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_colorRenderbuffer);
}
void VboRenderingEngine1::Initialize(int width, int height)
{
m_pivotPoint = ivec2(width / 2, height / 2);
const float coneRadius = 0.8f;
const float coneHeight = 1.866f;
const int coneSlices = 40;
const float dtheta = TwoPi / coneSlices;
const int vertexCount = coneSlices * 2 + 1;
const int diskCenterIndex = vertexCount - 1;
m_bodyIndexCount = coneSlices * 3;
m_diskIndexCount = coneSlices * 3;
vector<Vertex> coneVertices(vertexCount);
vector<Vertex>::iterator vertex = coneVertices.begin();
// Cone's body
for (float theta = 0; vertex != coneVertices.end() - 1; theta += dtheta) {
// Grayscale gradient
float brightness = abs(sin(theta));
vec4 color(brightness, brightness, brightness*2, 1); // 藍色
// Apex vertex
vertex->Position = vec3(0, 1, 0);
vertex->Color = color;
vertex++;
// Rim vertex
vertex->Position.x = coneRadius * cos(theta);
vertex->Position.y = 1 - coneHeight;
vertex->Position.z = coneRadius * sin(theta);
vertex->Color = color;
vertex++;
}
// Disk center
vertex->Position = vec3(0, 1 - coneHeight, 0);
vertex->Color = vec4(1, 1, 1, 1);
// Create the VBO for the vertices.
glGenBuffers(1, &m_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glBufferData(GL_ARRAY_BUFFER,
coneVertices.size() * sizeof(coneVertices[0]),
&coneVertices[0],
GL_STATIC_DRAW);
vector<GLubyte> coneIndices(m_bodyIndexCount + m_diskIndexCount);
vector<GLubyte>::iterator index = coneIndices.begin();
// Body triangles
for (int i = 0; i < coneSlices * 2; i += 2) {
*index++ = i;
*index++ = (i + 1) % (2 * coneSlices);
*index++ = (i + 3) % (2 * coneSlices);
}
// Disk triangles
for (int i = 1; i < coneSlices * 2 + 1; i += 2) {
*index++ = diskCenterIndex;
*index++ = i;
*index++ = (i + 2) % (2 * coneSlices);
}
// Create the VBO for the indices.
glGenBuffers(1, &m_indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
coneIndices.size() * sizeof(coneIndices[0]),
&coneIndices[0],
GL_STATIC_DRAW);
// Create the depth buffer.
glGenRenderbuffersOES(1, &m_depthRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_depthRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES,
GL_DEPTH_COMPONENT16_OES,
width,
height);
// Create the framebuffer object; attach the depth and color buffers.
glGenFramebuffersOES(1, &m_framebuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_framebuffer);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
GL_COLOR_ATTACHMENT0_OES,
GL_RENDERBUFFER_OES,
m_colorRenderbuffer);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
GL_DEPTH_ATTACHMENT_OES,
GL_RENDERBUFFER_OES,
m_depthRenderbuffer);
// Bind the color buffer for rendering.
glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_colorRenderbuffer);
glViewport(0, 0, width, height);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glFrustumf(-1.6f, 1.6, -2.4, 2.4, 5, 10);
glMatrixMode(GL_MODELVIEW);
glTranslatef(0, 0, -7);
}
void VboRenderingEngine1::Render() const
{
glClearColor(0.5f, 0.5f, 0.5f, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(m_rotationAngle, 0, 0, 1);
glScalef(m_scale, m_scale, m_scale);
const GLvoid* colorOffset = (GLvoid*) sizeof(vec3);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), 0);
glColorPointer(4, GL_FLOAT, sizeof(Vertex), colorOffset);
glEnableClientState(GL_VERTEX_ARRAY);
const GLvoid* bodyOffset = 0;
const GLvoid* diskOffset = (GLvoid*) m_bodyIndexCount;
glEnableClientState(GL_COLOR_ARRAY);
glDrawElements(GL_TRIANGLES, m_bodyIndexCount, GL_UNSIGNED_BYTE, bodyOffset);
glDisableClientState(GL_COLOR_ARRAY);
glColor4f(1, 1, 1, 1);
glDrawElements(GL_TRIANGLES, m_diskIndexCount, GL_UNSIGNED_BYTE, diskOffset);
glDisableClientState(GL_VERTEX_ARRAY);
glPopMatrix();
}
void VboRenderingEngine1::OnFingerUp(ivec2 location)
{
m_scale = 1.0f;
}
void VboRenderingEngine1::OnFingerDown(ivec2 location)
{
m_scale = 1.5f;
OnFingerMove(location, location);
}
void VboRenderingEngine1::OnFingerMove(ivec2 previous, ivec2 location)
{
vec2 direction = vec2(location - m_pivotPoint).Normalized();
// Flip the Y axis because pixel coords increase towards the bottom.
direction.y = -direction.y;
m_rotationAngle = std::acos(direction.y) * 180.0f / 3.14159f;
if (direction.x > 0)
m_rotationAngle = -m_rotationAngle;
}
8.VboRenderingEngine2.cpp除了是VBO的功能之外,同樣也有接觸後放大,以及手指帶動旋轉的程式。
#include <OpenGLES/ES2/gl.h>#include <OpenGLES/ES2/glext.h>
#include "IRenderingEngine.hpp"
#include "Matrix.hpp"
#include <vector>
#include <iostream>
#define STRINGIFY(A) #A
#include "./Simple.vert"
#include "./Simple.frag"
using namespace std;
struct Vertex {
vec3 Position;
vec4 Color;
};
class VboRenderingEngine2 : public IRenderingEngine {
public:
VboRenderingEngine2();
void Initialize(int width, int height);
void Render() const;
void UpdateAnimation(float timeStep) {}
void OnRotate(DeviceOrientation newOrientation) {}
void OnFingerUp(ivec2 location);
void OnFingerDown(ivec2 location);
void OnFingerMove(ivec2 oldLocation, ivec2 newLocation);
private:
GLuint BuildShader(const char* source, GLenum shaderType) const;
GLuint BuildProgram(const char* vShader, const char* fShader) const;
GLuint m_vertexBuffer; // Object handles for VBO
GLuint m_indexBuffer; // Object handles for VBO
GLfloat m_rotationAngle;
GLfloat m_scale;
ivec2 m_pivotPoint;
GLuint m_simpleProgram;
GLuint m_framebuffer;
GLuint m_colorRenderbuffer;
GLuint m_depthRenderbuffer;
int m_diskIndexCount;
int m_bodyIndexCount;
};
IRenderingEngine* CreateVboRenderer2()
{
return new VboRenderingEngine2();
}
VboRenderingEngine2::VboRenderingEngine2() : m_rotationAngle(0), m_scale(1)
{
// Create & bind the color buffer so that the caller can allocate its space.
glGenRenderbuffers(1, &m_colorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer);
}
void VboRenderingEngine2::Initialize(int width, int height)
{
m_pivotPoint = ivec2(width / 2, height / 2);
const float coneRadius = 0.5f;
const float coneHeight = 1.866f;
const int coneSlices = 40;
const float dtheta = TwoPi / coneSlices;
const int vertexCount = coneSlices * 2 + 1;
const int diskCenterIndex = vertexCount - 1;
m_bodyIndexCount = coneSlices * 3;
m_diskIndexCount = coneSlices * 3;
vector<Vertex> coneVertices(vertexCount);
vector<Vertex>::iterator vertex = coneVertices.begin();
// Cone's body
for (float theta = 0; vertex != coneVertices.end() - 1; theta += dtheta) {
// Grayscale gradient
float brightness = abs(sin(theta));
vec4 color(brightness*2, brightness, brightness*2, 1); // 紫色
// Apex vertex
vertex->Position = vec3(0, 1, 0);
vertex->Color = color;
vertex++;
// Rim vertex
vertex->Position.x = coneRadius * cos(theta);
vertex->Position.y = 1 - coneHeight;
vertex->Position.z = coneRadius * sin(theta);
vertex->Color = color;
vertex++;
}
// Disk center
vertex->Position = vec3(0, 1 - coneHeight, 0);
vertex->Color = vec4(1, 1, 1, 1);
// Create the VBO for the vertices.
glGenBuffers(1, &m_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glBufferData(GL_ARRAY_BUFFER,
coneVertices.size() * sizeof(coneVertices[0]),
&coneVertices[0],
GL_STATIC_DRAW);
vector<GLubyte> coneIndices(m_bodyIndexCount + m_diskIndexCount);
vector<GLubyte>::iterator index = coneIndices.begin();
// Body triangles
for (int i = 0; i < coneSlices * 2; i += 2) {
*index++ = i;
*index++ = (i + 1) % (2 * coneSlices);
*index++ = (i + 3) % (2 * coneSlices);
}
// Disk triangles
for (int i = 1; i < coneSlices * 2 + 1; i += 2) {
*index++ = diskCenterIndex;
*index++ = i;
*index++ = (i + 2) % (2 * coneSlices);
}
// Create the VBO for the indices.
glGenBuffers(1, &m_indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
coneIndices.size() * sizeof(coneIndices[0]),
&coneIndices[0],
GL_STATIC_DRAW);
// Create the depth buffer.
glGenRenderbuffers(1, &m_depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, m_depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER,
GL_DEPTH_COMPONENT16,
width,
height);
// Create the framebuffer object; attach the depth and color buffers.
glGenFramebuffers(1, &m_framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER,
m_colorRenderbuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER,
m_depthRenderbuffer);
// Bind the color buffer for rendering.
glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer);
glViewport(0, 0, width, height);
glEnable(GL_DEPTH_TEST);
m_simpleProgram = BuildProgram(SimpleVertexShader, SimpleFragmentShader);
glUseProgram(m_simpleProgram);
// Set the projection matrix.
GLint projectionUniform = glGetUniformLocation(m_simpleProgram, "Projection");
mat4 projectionMatrix = mat4::Frustum(-1.6f, 1.6, -2.4, 2.4, 5, 10);
glUniformMatrix4fv(projectionUniform, 1, 0, projectionMatrix.Pointer());
}
void VboRenderingEngine2::Render() const
{
GLuint positionSlot = glGetAttribLocation(m_simpleProgram, "Position");
GLuint colorSlot = glGetAttribLocation(m_simpleProgram, "SourceColor");
mat4 rotation = mat4::Rotate(m_rotationAngle);
mat4 scale = mat4::Scale(m_scale);
mat4 translation = mat4::Translate(0, 0, -7);
GLint modelviewUniform = glGetUniformLocation(m_simpleProgram, "Modelview");
mat4 modelviewMatrix = scale * rotation * translation;
GLsizei stride = sizeof(Vertex);
const GLvoid* colorOffset = (GLvoid*) sizeof(vec3);
glClearColor(0.5f, 0.5f, 0.5f, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUniformMatrix4fv(modelviewUniform, 1, 0, modelviewMatrix.Pointer());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, stride, 0);
glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, stride, colorOffset);
glEnableVertexAttribArray(positionSlot);
const GLvoid* bodyOffset = 0;
const GLvoid* diskOffset = (GLvoid*) m_bodyIndexCount;
glEnableVertexAttribArray(colorSlot);
glDrawElements(GL_TRIANGLES, m_bodyIndexCount, GL_UNSIGNED_BYTE, bodyOffset);
glDisableVertexAttribArray(colorSlot);
glVertexAttrib4f(colorSlot, 1, 1, 1, 1);
glDrawElements(GL_TRIANGLES, m_diskIndexCount, GL_UNSIGNED_BYTE, diskOffset);
glDisableVertexAttribArray(positionSlot);
}
void VboRenderingEngine2::OnFingerUp(ivec2 location)
{
m_scale = 1.0f;
}
void VboRenderingEngine2::OnFingerDown(ivec2 location)
{
m_scale = 1.5f;
OnFingerMove(location, location);
}
void VboRenderingEngine2::OnFingerMove(ivec2 previous, ivec2 location)
{
vec2 direction = vec2(location - m_pivotPoint).Normalized();
// Flip the Y axis because pixel coords increase towards the bottom.
direction.y = -direction.y;
m_rotationAngle = std::acos(direction.y) * 180.0f / 3.14159f;
if (direction.x > 0)
m_rotationAngle = -m_rotationAngle;
}
GLuint VboRenderingEngine2::BuildShader(const char* source, GLenum shaderType) const
{
GLuint shaderHandle = glCreateShader(shaderType);
glShaderSource(shaderHandle, 1, &source, 0);
glCompileShader(shaderHandle);
GLint compileSuccess;
glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &compileSuccess);
if (compileSuccess == GL_FALSE) {
GLchar messages[256];
glGetShaderInfoLog(shaderHandle, sizeof(messages), 0, &messages[0]);
std::cout << messages;
exit(1);
}
return shaderHandle;
}
GLuint VboRenderingEngine2::BuildProgram(const char* vertexShaderSource,
const char* fragmentShaderSource) const
{
GLuint vertexShader = BuildShader(vertexShaderSource, GL_VERTEX_SHADER);
GLuint fragmentShader = BuildShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
GLuint programHandle = glCreateProgram();
glAttachShader(programHandle, vertexShader);
glAttachShader(programHandle, fragmentShader);
glLinkProgram(programHandle);
GLint linkSuccess;
glGetProgramiv(programHandle, GL_LINK_STATUS, &linkSuccess);
if (linkSuccess == GL_FALSE) {
GLchar messages[256];
glGetProgramInfoLog(programHandle, sizeof(messages), 0, &messages[0]);
std::cout << messages;
exit(1);
}
return programHandle;
}
9.mainViewController.h主控區定義與前一個實作相同。
#import <UIKit/UIKit.h>
#include "GLView.h"
@interface mainViewController : UIViewController
{
UIWindow* m_window;
GLView* controllView;
}
@end
10.mainViewController.mm主控區程式與前一個實作大致相同,只是多了一個VBO切換的Button。
#import "mainViewController.h"@interface mainViewController ()
@end
@implementation mainViewController
{
UIButton *swBtn;
UIButton *swBtn2;
}
BOOL mode1;
BOOL isVBO;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
CGRect screenBounds = [[UIScreen mainScreen] bounds];
m_window = [[UIWindow alloc] initWithFrame: screenBounds];
controllView = [[GLView alloc] initWithFrame: screenBounds];
[self setButtonInterface];
[self setButtonInterface2];
[controllView addSubview:swBtn];
[controllView addSubview:swBtn2];
[m_window addSubview: controllView];
[m_window makeKeyAndVisible];
mode1 = NO;
isVBO = NO;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)setButtonInterface // 動態產生一個的Button
{
swBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
//動態產生一個RoundedRect 形式的 Button
swBtn.frame = CGRectMake(0,0, 100, 30); // 大小
[swBtn setCenter:CGPointMake(150, 50)];//位置放在x=150, y=50的位置
[swBtn addTarget:self action:@selector(onSwitch) forControlEvents:UIControlEventTouchUpInside];
//設定Button動作呼叫的function在 onHelloActionButton,方式為按下
//_helloActionButton.= @"Action Button";
[swBtn setTitle:@"ES2 Mode" forState:UIControlStateNormal];
//將動態Button上放置Action Button這兩個字
//[self.view addSubview:swBtn];
//將動態Button放到View上展出
}
- (void)setButtonInterface2 // 動態產生一個的Button
{
swBtn2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
//動態產生一個RoundedRect 形式的 Button
swBtn2.frame = CGRectMake(0,0, 100, 30); // 大小
[swBtn2 setCenter:CGPointMake(350, 50)];//位置放在x=150, y=50的位置
[swBtn2 addTarget:self action:@selector(onSwitch1) forControlEvents:UIControlEventTouchUpInside];
//設定Button動作呼叫的function在 onHelloActionButton,方式為按下
//_helloActionButton.= @"Action Button";
[swBtn2 setTitle:@"Normal Mode" forState:UIControlStateNormal];
//將動態Button上放置Action Button這兩個字
//[self.view addSubview:swBtn2];
//將動態Button放到View上展出
}
- (void) onSwitch
{
mode1 = ~mode1;
controllView->ForceES1 = mode1;
[controllView initSet:m_window.frame];
if (mode1 == 0){
[swBtn setTitle:@"ES2 Mode" forState:UIControlStateNormal];
}
else
[swBtn setTitle:@"ES1 Mode" forState:UIControlStateNormal];
}
- (void) onSwitch1
{
isVBO = ~isVBO;
controllView->ForceVBO = isVBO;
[controllView initSet:m_window.frame];
if (isVBO == 0){
[swBtn2 setTitle:@"Normal Mode" forState:UIControlStateNormal];
}
else
[swBtn2 setTitle:@"VBO Mode" forState:UIControlStateNormal];
}
@end
11. 顯示結果
2013年5月29日 星期三
OpenGL基本瞭解(十三) (OPENGLES definitions)
在OPENGL中經常會遇到專用的Define 詞,要找很麻煩,就將他們貼出來。
以下是OpenGLES/ES2/gl.h下的Define
/*-------------------------------------------------------------------------
* Data type definitions
*-----------------------------------------------------------------------*/
typedef void GLvoid;
typedef char GLchar;
typedef unsigned int GLenum;
typedef unsigned char GLboolean;
typedef unsigned int GLbitfield;
typedef signed char GLbyte;
typedef short GLshort;
typedef int GLint;
typedef int GLsizei;
typedef unsigned char GLubyte;
typedef unsigned short GLushort;
typedef unsigned int GLuint;
typedef float GLfloat;
typedef float GLclampf;
typedef int GLfixed;
typedef int GLclampx;
/* GL types for handling large vertex buffer objects */
typedef long GLintptr;
typedef long GLsizeiptr;
/* OpenGL ES core versions */
#define GL_ES_VERSION_2_0 1
/* ClearBufferMask */
#define GL_DEPTH_BUFFER_BIT 0x00000100
#define GL_STENCIL_BUFFER_BIT 0x00000400
#define GL_COLOR_BUFFER_BIT 0x00004000
/* Boolean */
#define GL_FALSE 0
#define GL_TRUE 1
/* BeginMode */
#define GL_POINTS 0x0000
#define GL_LINES 0x0001
#define GL_LINE_LOOP 0x0002
#define GL_LINE_STRIP 0x0003
#define GL_TRIANGLES 0x0004
#define GL_TRIANGLE_STRIP 0x0005
#define GL_TRIANGLE_FAN 0x0006
/* AlphaFunction (not supported in ES20) */
/* GL_NEVER */
/* GL_LESS */
/* GL_EQUAL */
/* GL_LEQUAL */
/* GL_GREATER */
/* GL_NOTEQUAL */
/* GL_GEQUAL */
/* GL_ALWAYS */
/* BlendingFactorDest */
#define GL_ZERO 0
#define GL_ONE 1
#define GL_SRC_COLOR 0x0300
#define GL_ONE_MINUS_SRC_COLOR 0x0301
#define GL_SRC_ALPHA 0x0302
#define GL_ONE_MINUS_SRC_ALPHA 0x0303
#define GL_DST_ALPHA 0x0304
#define GL_ONE_MINUS_DST_ALPHA 0x0305
/* BlendingFactorSrc */
/* GL_ZERO */
/* GL_ONE */
#define GL_DST_COLOR 0x0306
#define GL_ONE_MINUS_DST_COLOR 0x0307
#define GL_SRC_ALPHA_SATURATE 0x0308
/* GL_SRC_ALPHA */
/* GL_ONE_MINUS_SRC_ALPHA */
/* GL_DST_ALPHA */
/* GL_ONE_MINUS_DST_ALPHA */
/* BlendEquationSeparate */
#define GL_FUNC_ADD 0x8006
#define GL_BLEND_EQUATION 0x8009
#define GL_BLEND_EQUATION_RGB 0x8009 /* same as BLEND_EQUATION */
#define GL_BLEND_EQUATION_ALPHA 0x883D
/* BlendSubtract */
#define GL_FUNC_SUBTRACT 0x800A
#define GL_FUNC_REVERSE_SUBTRACT 0x800B
/* Separate Blend Functions */
#define GL_BLEND_DST_RGB 0x80C8
#define GL_BLEND_SRC_RGB 0x80C9
#define GL_BLEND_DST_ALPHA 0x80CA
#define GL_BLEND_SRC_ALPHA 0x80CB
#define GL_CONSTANT_COLOR 0x8001
#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
#define GL_CONSTANT_ALPHA 0x8003
#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
#define GL_BLEND_COLOR 0x8005
/* Buffer Objects */
#define GL_ARRAY_BUFFER 0x8892
#define GL_ELEMENT_ARRAY_BUFFER 0x8893
#define GL_ARRAY_BUFFER_BINDING 0x8894
#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
#define GL_STREAM_DRAW 0x88E0
#define GL_STATIC_DRAW 0x88E4
#define GL_DYNAMIC_DRAW 0x88E8
#define GL_BUFFER_SIZE 0x8764
#define GL_BUFFER_USAGE 0x8765
#define GL_CURRENT_VERTEX_ATTRIB 0x8626
/* CullFaceMode */
#define GL_FRONT 0x0404
#define GL_BACK 0x0405
#define GL_FRONT_AND_BACK 0x0408
/* DepthFunction */
/* GL_NEVER */
/* GL_LESS */
/* GL_EQUAL */
/* GL_LEQUAL */
/* GL_GREATER */
/* GL_NOTEQUAL */
/* GL_GEQUAL */
/* GL_ALWAYS */
/* EnableCap */
#define GL_TEXTURE_2D 0x0DE1
#define GL_CULL_FACE 0x0B44
#define GL_BLEND 0x0BE2
#define GL_DITHER 0x0BD0
#define GL_STENCIL_TEST 0x0B90
#define GL_DEPTH_TEST 0x0B71
#define GL_SCISSOR_TEST 0x0C11
#define GL_POLYGON_OFFSET_FILL 0x8037
#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
#define GL_SAMPLE_COVERAGE 0x80A0
/* ErrorCode */
#define GL_NO_ERROR 0
#define GL_INVALID_ENUM 0x0500
#define GL_INVALID_VALUE 0x0501
#define GL_INVALID_OPERATION 0x0502
#define GL_OUT_OF_MEMORY 0x0505
/* FrontFaceDirection */
#define GL_CW 0x0900
#define GL_CCW 0x0901
/* GetPName */
#define GL_LINE_WIDTH 0x0B21
#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
#define GL_CULL_FACE_MODE 0x0B45
#define GL_FRONT_FACE 0x0B46
#define GL_DEPTH_RANGE 0x0B70
#define GL_DEPTH_WRITEMASK 0x0B72
#define GL_DEPTH_CLEAR_VALUE 0x0B73
#define GL_DEPTH_FUNC 0x0B74
#define GL_STENCIL_CLEAR_VALUE 0x0B91
#define GL_STENCIL_FUNC 0x0B92
#define GL_STENCIL_FAIL 0x0B94
#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
#define GL_STENCIL_REF 0x0B97
#define GL_STENCIL_VALUE_MASK 0x0B93
#define GL_STENCIL_WRITEMASK 0x0B98
#define GL_STENCIL_BACK_FUNC 0x8800
#define GL_STENCIL_BACK_FAIL 0x8801
#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
#define GL_STENCIL_BACK_REF 0x8CA3
#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
#define GL_VIEWPORT 0x0BA2
#define GL_SCISSOR_BOX 0x0C10
/* GL_SCISSOR_TEST */
#define GL_COLOR_CLEAR_VALUE 0x0C22
#define GL_COLOR_WRITEMASK 0x0C23
#define GL_UNPACK_ALIGNMENT 0x0CF5
#define GL_PACK_ALIGNMENT 0x0D05
#define GL_MAX_TEXTURE_SIZE 0x0D33
#define GL_MAX_VIEWPORT_DIMS 0x0D3A
#define GL_SUBPIXEL_BITS 0x0D50
#define GL_RED_BITS 0x0D52
#define GL_GREEN_BITS 0x0D53
#define GL_BLUE_BITS 0x0D54
#define GL_ALPHA_BITS 0x0D55
#define GL_DEPTH_BITS 0x0D56
#define GL_STENCIL_BITS 0x0D57
#define GL_POLYGON_OFFSET_UNITS 0x2A00
/* GL_POLYGON_OFFSET_FILL */
#define GL_POLYGON_OFFSET_FACTOR 0x8038
#define GL_TEXTURE_BINDING_2D 0x8069
#define GL_SAMPLE_BUFFERS 0x80A8
#define GL_SAMPLES 0x80A9
#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
/* GetTextureParameter */
/* GL_TEXTURE_MAG_FILTER */
/* GL_TEXTURE_MIN_FILTER */
/* GL_TEXTURE_WRAP_S */
/* GL_TEXTURE_WRAP_T */
#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
/* HintMode */
#define GL_DONT_CARE 0x1100
#define GL_FASTEST 0x1101
#define GL_NICEST 0x1102
/* HintTarget */
#define GL_GENERATE_MIPMAP_HINT 0x8192
/* DataType */
#define GL_BYTE 0x1400
#define GL_UNSIGNED_BYTE 0x1401
#define GL_SHORT 0x1402
#define GL_UNSIGNED_SHORT 0x1403
#define GL_INT 0x1404
#define GL_UNSIGNED_INT 0x1405
#define GL_FLOAT 0x1406
#define GL_FIXED 0x140C
/* PixelFormat */
#define GL_DEPTH_COMPONENT 0x1902
#define GL_ALPHA 0x1906
#define GL_RGB 0x1907
#define GL_RGBA 0x1908
#define GL_LUMINANCE 0x1909
#define GL_LUMINANCE_ALPHA 0x190A
/* PixelType */
/* GL_UNSIGNED_BYTE */
#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
#define GL_UNSIGNED_SHORT_5_6_5 0x8363
/* Shaders */
#define GL_FRAGMENT_SHADER 0x8B30
#define GL_VERTEX_SHADER 0x8B31
#define GL_MAX_VERTEX_ATTRIBS 0x8869
#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
#define GL_MAX_VARYING_VECTORS 0x8DFC
#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
#define GL_SHADER_TYPE 0x8B4F
#define GL_DELETE_STATUS 0x8B80
#define GL_LINK_STATUS 0x8B82
#define GL_VALIDATE_STATUS 0x8B83
#define GL_ATTACHED_SHADERS 0x8B85
#define GL_ACTIVE_UNIFORMS 0x8B86
#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
#define GL_ACTIVE_ATTRIBUTES 0x8B89
#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
#define GL_CURRENT_PROGRAM 0x8B8D
/* StencilFunction */
#define GL_NEVER 0x0200
#define GL_LESS 0x0201
#define GL_EQUAL 0x0202
#define GL_LEQUAL 0x0203
#define GL_GREATER 0x0204
#define GL_NOTEQUAL 0x0205
#define GL_GEQUAL 0x0206
#define GL_ALWAYS 0x0207
/* StencilOp */
/* GL_ZERO */
#define GL_KEEP 0x1E00
#define GL_REPLACE 0x1E01
#define GL_INCR 0x1E02
#define GL_DECR 0x1E03
#define GL_INVERT 0x150A
#define GL_INCR_WRAP 0x8507
#define GL_DECR_WRAP 0x8508
/* StringName */
#define GL_VENDOR 0x1F00
#define GL_RENDERER 0x1F01
#define GL_VERSION 0x1F02
#define GL_EXTENSIONS 0x1F03
/* TextureMagFilter */
#define GL_NEAREST 0x2600
#define GL_LINEAR 0x2601
/* TextureMinFilter */
/* GL_NEAREST */
/* GL_LINEAR */
#define GL_NEAREST_MIPMAP_NEAREST 0x2700
#define GL_LINEAR_MIPMAP_NEAREST 0x2701
#define GL_NEAREST_MIPMAP_LINEAR 0x2702
#define GL_LINEAR_MIPMAP_LINEAR 0x2703
/* TextureParameterName */
#define GL_TEXTURE_MAG_FILTER 0x2800
#define GL_TEXTURE_MIN_FILTER 0x2801
#define GL_TEXTURE_WRAP_S 0x2802
#define GL_TEXTURE_WRAP_T 0x2803
/* TextureTarget */
/* GL_TEXTURE_2D */
#define GL_TEXTURE 0x1702
#define GL_TEXTURE_CUBE_MAP 0x8513
#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
/* TextureUnit */
#define GL_TEXTURE0 0x84C0
#define GL_TEXTURE1 0x84C1
#define GL_TEXTURE2 0x84C2
#define GL_TEXTURE3 0x84C3
#define GL_TEXTURE4 0x84C4
#define GL_TEXTURE5 0x84C5
#define GL_TEXTURE6 0x84C6
#define GL_TEXTURE7 0x84C7
#define GL_TEXTURE8 0x84C8
#define GL_TEXTURE9 0x84C9
#define GL_TEXTURE10 0x84CA
#define GL_TEXTURE11 0x84CB
#define GL_TEXTURE12 0x84CC
#define GL_TEXTURE13 0x84CD
#define GL_TEXTURE14 0x84CE
#define GL_TEXTURE15 0x84CF
#define GL_TEXTURE16 0x84D0
#define GL_TEXTURE17 0x84D1
#define GL_TEXTURE18 0x84D2
#define GL_TEXTURE19 0x84D3
#define GL_TEXTURE20 0x84D4
#define GL_TEXTURE21 0x84D5
#define GL_TEXTURE22 0x84D6
#define GL_TEXTURE23 0x84D7
#define GL_TEXTURE24 0x84D8
#define GL_TEXTURE25 0x84D9
#define GL_TEXTURE26 0x84DA
#define GL_TEXTURE27 0x84DB
#define GL_TEXTURE28 0x84DC
#define GL_TEXTURE29 0x84DD
#define GL_TEXTURE30 0x84DE
#define GL_TEXTURE31 0x84DF
#define GL_ACTIVE_TEXTURE 0x84E0
/* TextureWrapMode */
#define GL_REPEAT 0x2901
#define GL_CLAMP_TO_EDGE 0x812F
#define GL_MIRRORED_REPEAT 0x8370
/* Uniform Types */
#define GL_FLOAT_VEC2 0x8B50
#define GL_FLOAT_VEC3 0x8B51
#define GL_FLOAT_VEC4 0x8B52
#define GL_INT_VEC2 0x8B53
#define GL_INT_VEC3 0x8B54
#define GL_INT_VEC4 0x8B55
#define GL_BOOL 0x8B56
#define GL_BOOL_VEC2 0x8B57
#define GL_BOOL_VEC3 0x8B58
#define GL_BOOL_VEC4 0x8B59
#define GL_FLOAT_MAT2 0x8B5A
#define GL_FLOAT_MAT3 0x8B5B
#define GL_FLOAT_MAT4 0x8B5C
#define GL_SAMPLER_2D 0x8B5E
#define GL_SAMPLER_CUBE 0x8B60
/* Vertex Arrays */
#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
/* Read Format */
#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
/* Shader Source */
#define GL_COMPILE_STATUS 0x8B81
#define GL_INFO_LOG_LENGTH 0x8B84
#define GL_SHADER_SOURCE_LENGTH 0x8B88
#define GL_SHADER_COMPILER 0x8DFA
/* Shader Binary */
#define GL_SHADER_BINARY_FORMATS 0x8DF8
#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
/* Shader Precision-Specified Types */
#define GL_LOW_FLOAT 0x8DF0
#define GL_MEDIUM_FLOAT 0x8DF1
#define GL_HIGH_FLOAT 0x8DF2
#define GL_LOW_INT 0x8DF3
#define GL_MEDIUM_INT 0x8DF4
#define GL_HIGH_INT 0x8DF5
/* Framebuffer Object. */
#define GL_FRAMEBUFFER 0x8D40
#define GL_RENDERBUFFER 0x8D41
#define GL_RGBA4 0x8056
#define GL_RGB5_A1 0x8057
#define GL_RGB565 0x8D62
#define GL_DEPTH_COMPONENT16 0x81A5
#define GL_STENCIL_INDEX 0x1901
#define GL_STENCIL_INDEX8 0x8D48
#define GL_RENDERBUFFER_WIDTH 0x8D42
#define GL_RENDERBUFFER_HEIGHT 0x8D43
#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
#define GL_RENDERBUFFER_RED_SIZE 0x8D50
#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
#define GL_COLOR_ATTACHMENT0 0x8CE0
#define GL_DEPTH_ATTACHMENT 0x8D00
#define GL_STENCIL_ATTACHMENT 0x8D20
#define GL_NONE 0
#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
#define GL_FRAMEBUFFER_BINDING 0x8CA6
#define GL_RENDERBUFFER_BINDING 0x8CA7
#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
以下是OpenGLES/ES2/gl.h下的Define
/*-------------------------------------------------------------------------
* Data type definitions
*-----------------------------------------------------------------------*/
typedef void GLvoid;
typedef char GLchar;
typedef unsigned int GLenum;
typedef unsigned char GLboolean;
typedef unsigned int GLbitfield;
typedef signed char GLbyte;
typedef short GLshort;
typedef int GLint;
typedef int GLsizei;
typedef unsigned char GLubyte;
typedef unsigned short GLushort;
typedef unsigned int GLuint;
typedef float GLfloat;
typedef float GLclampf;
typedef int GLfixed;
typedef int GLclampx;
/* GL types for handling large vertex buffer objects */
typedef long GLintptr;
typedef long GLsizeiptr;
/* OpenGL ES core versions */
#define GL_ES_VERSION_2_0 1
/* ClearBufferMask */
#define GL_DEPTH_BUFFER_BIT 0x00000100
#define GL_STENCIL_BUFFER_BIT 0x00000400
#define GL_COLOR_BUFFER_BIT 0x00004000
/* Boolean */
#define GL_FALSE 0
#define GL_TRUE 1
/* BeginMode */
#define GL_POINTS 0x0000
#define GL_LINES 0x0001
#define GL_LINE_LOOP 0x0002
#define GL_LINE_STRIP 0x0003
#define GL_TRIANGLES 0x0004
#define GL_TRIANGLE_STRIP 0x0005
#define GL_TRIANGLE_FAN 0x0006
/* AlphaFunction (not supported in ES20) */
/* GL_NEVER */
/* GL_LESS */
/* GL_EQUAL */
/* GL_LEQUAL */
/* GL_GREATER */
/* GL_NOTEQUAL */
/* GL_GEQUAL */
/* GL_ALWAYS */
/* BlendingFactorDest */
#define GL_ZERO 0
#define GL_ONE 1
#define GL_SRC_COLOR 0x0300
#define GL_ONE_MINUS_SRC_COLOR 0x0301
#define GL_SRC_ALPHA 0x0302
#define GL_ONE_MINUS_SRC_ALPHA 0x0303
#define GL_DST_ALPHA 0x0304
#define GL_ONE_MINUS_DST_ALPHA 0x0305
/* BlendingFactorSrc */
/* GL_ZERO */
/* GL_ONE */
#define GL_DST_COLOR 0x0306
#define GL_ONE_MINUS_DST_COLOR 0x0307
#define GL_SRC_ALPHA_SATURATE 0x0308
/* GL_SRC_ALPHA */
/* GL_ONE_MINUS_SRC_ALPHA */
/* GL_DST_ALPHA */
/* GL_ONE_MINUS_DST_ALPHA */
/* BlendEquationSeparate */
#define GL_FUNC_ADD 0x8006
#define GL_BLEND_EQUATION 0x8009
#define GL_BLEND_EQUATION_RGB 0x8009 /* same as BLEND_EQUATION */
#define GL_BLEND_EQUATION_ALPHA 0x883D
/* BlendSubtract */
#define GL_FUNC_SUBTRACT 0x800A
#define GL_FUNC_REVERSE_SUBTRACT 0x800B
/* Separate Blend Functions */
#define GL_BLEND_DST_RGB 0x80C8
#define GL_BLEND_SRC_RGB 0x80C9
#define GL_BLEND_DST_ALPHA 0x80CA
#define GL_BLEND_SRC_ALPHA 0x80CB
#define GL_CONSTANT_COLOR 0x8001
#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
#define GL_CONSTANT_ALPHA 0x8003
#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
#define GL_BLEND_COLOR 0x8005
/* Buffer Objects */
#define GL_ARRAY_BUFFER 0x8892
#define GL_ELEMENT_ARRAY_BUFFER 0x8893
#define GL_ARRAY_BUFFER_BINDING 0x8894
#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
#define GL_STREAM_DRAW 0x88E0
#define GL_STATIC_DRAW 0x88E4
#define GL_DYNAMIC_DRAW 0x88E8
#define GL_BUFFER_SIZE 0x8764
#define GL_BUFFER_USAGE 0x8765
#define GL_CURRENT_VERTEX_ATTRIB 0x8626
/* CullFaceMode */
#define GL_FRONT 0x0404
#define GL_BACK 0x0405
#define GL_FRONT_AND_BACK 0x0408
/* DepthFunction */
/* GL_NEVER */
/* GL_LESS */
/* GL_EQUAL */
/* GL_LEQUAL */
/* GL_GREATER */
/* GL_NOTEQUAL */
/* GL_GEQUAL */
/* GL_ALWAYS */
/* EnableCap */
#define GL_TEXTURE_2D 0x0DE1
#define GL_CULL_FACE 0x0B44
#define GL_BLEND 0x0BE2
#define GL_DITHER 0x0BD0
#define GL_STENCIL_TEST 0x0B90
#define GL_DEPTH_TEST 0x0B71
#define GL_SCISSOR_TEST 0x0C11
#define GL_POLYGON_OFFSET_FILL 0x8037
#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
#define GL_SAMPLE_COVERAGE 0x80A0
/* ErrorCode */
#define GL_NO_ERROR 0
#define GL_INVALID_ENUM 0x0500
#define GL_INVALID_VALUE 0x0501
#define GL_INVALID_OPERATION 0x0502
#define GL_OUT_OF_MEMORY 0x0505
/* FrontFaceDirection */
#define GL_CW 0x0900
#define GL_CCW 0x0901
/* GetPName */
#define GL_LINE_WIDTH 0x0B21
#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
#define GL_CULL_FACE_MODE 0x0B45
#define GL_FRONT_FACE 0x0B46
#define GL_DEPTH_RANGE 0x0B70
#define GL_DEPTH_WRITEMASK 0x0B72
#define GL_DEPTH_CLEAR_VALUE 0x0B73
#define GL_DEPTH_FUNC 0x0B74
#define GL_STENCIL_CLEAR_VALUE 0x0B91
#define GL_STENCIL_FUNC 0x0B92
#define GL_STENCIL_FAIL 0x0B94
#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
#define GL_STENCIL_REF 0x0B97
#define GL_STENCIL_VALUE_MASK 0x0B93
#define GL_STENCIL_WRITEMASK 0x0B98
#define GL_STENCIL_BACK_FUNC 0x8800
#define GL_STENCIL_BACK_FAIL 0x8801
#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
#define GL_STENCIL_BACK_REF 0x8CA3
#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
#define GL_VIEWPORT 0x0BA2
#define GL_SCISSOR_BOX 0x0C10
/* GL_SCISSOR_TEST */
#define GL_COLOR_CLEAR_VALUE 0x0C22
#define GL_COLOR_WRITEMASK 0x0C23
#define GL_UNPACK_ALIGNMENT 0x0CF5
#define GL_PACK_ALIGNMENT 0x0D05
#define GL_MAX_TEXTURE_SIZE 0x0D33
#define GL_MAX_VIEWPORT_DIMS 0x0D3A
#define GL_SUBPIXEL_BITS 0x0D50
#define GL_RED_BITS 0x0D52
#define GL_GREEN_BITS 0x0D53
#define GL_BLUE_BITS 0x0D54
#define GL_ALPHA_BITS 0x0D55
#define GL_DEPTH_BITS 0x0D56
#define GL_STENCIL_BITS 0x0D57
#define GL_POLYGON_OFFSET_UNITS 0x2A00
/* GL_POLYGON_OFFSET_FILL */
#define GL_POLYGON_OFFSET_FACTOR 0x8038
#define GL_TEXTURE_BINDING_2D 0x8069
#define GL_SAMPLE_BUFFERS 0x80A8
#define GL_SAMPLES 0x80A9
#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
/* GetTextureParameter */
/* GL_TEXTURE_MAG_FILTER */
/* GL_TEXTURE_MIN_FILTER */
/* GL_TEXTURE_WRAP_S */
/* GL_TEXTURE_WRAP_T */
#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
/* HintMode */
#define GL_DONT_CARE 0x1100
#define GL_FASTEST 0x1101
#define GL_NICEST 0x1102
/* HintTarget */
#define GL_GENERATE_MIPMAP_HINT 0x8192
/* DataType */
#define GL_BYTE 0x1400
#define GL_UNSIGNED_BYTE 0x1401
#define GL_SHORT 0x1402
#define GL_UNSIGNED_SHORT 0x1403
#define GL_INT 0x1404
#define GL_UNSIGNED_INT 0x1405
#define GL_FLOAT 0x1406
#define GL_FIXED 0x140C
/* PixelFormat */
#define GL_DEPTH_COMPONENT 0x1902
#define GL_ALPHA 0x1906
#define GL_RGB 0x1907
#define GL_RGBA 0x1908
#define GL_LUMINANCE 0x1909
#define GL_LUMINANCE_ALPHA 0x190A
/* PixelType */
/* GL_UNSIGNED_BYTE */
#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
#define GL_UNSIGNED_SHORT_5_6_5 0x8363
/* Shaders */
#define GL_FRAGMENT_SHADER 0x8B30
#define GL_VERTEX_SHADER 0x8B31
#define GL_MAX_VERTEX_ATTRIBS 0x8869
#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
#define GL_MAX_VARYING_VECTORS 0x8DFC
#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
#define GL_SHADER_TYPE 0x8B4F
#define GL_DELETE_STATUS 0x8B80
#define GL_LINK_STATUS 0x8B82
#define GL_VALIDATE_STATUS 0x8B83
#define GL_ATTACHED_SHADERS 0x8B85
#define GL_ACTIVE_UNIFORMS 0x8B86
#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
#define GL_ACTIVE_ATTRIBUTES 0x8B89
#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
#define GL_CURRENT_PROGRAM 0x8B8D
/* StencilFunction */
#define GL_NEVER 0x0200
#define GL_LESS 0x0201
#define GL_EQUAL 0x0202
#define GL_LEQUAL 0x0203
#define GL_GREATER 0x0204
#define GL_NOTEQUAL 0x0205
#define GL_GEQUAL 0x0206
#define GL_ALWAYS 0x0207
/* StencilOp */
/* GL_ZERO */
#define GL_KEEP 0x1E00
#define GL_REPLACE 0x1E01
#define GL_INCR 0x1E02
#define GL_DECR 0x1E03
#define GL_INVERT 0x150A
#define GL_INCR_WRAP 0x8507
#define GL_DECR_WRAP 0x8508
/* StringName */
#define GL_VENDOR 0x1F00
#define GL_RENDERER 0x1F01
#define GL_VERSION 0x1F02
#define GL_EXTENSIONS 0x1F03
/* TextureMagFilter */
#define GL_NEAREST 0x2600
#define GL_LINEAR 0x2601
/* TextureMinFilter */
/* GL_NEAREST */
/* GL_LINEAR */
#define GL_NEAREST_MIPMAP_NEAREST 0x2700
#define GL_LINEAR_MIPMAP_NEAREST 0x2701
#define GL_NEAREST_MIPMAP_LINEAR 0x2702
#define GL_LINEAR_MIPMAP_LINEAR 0x2703
/* TextureParameterName */
#define GL_TEXTURE_MAG_FILTER 0x2800
#define GL_TEXTURE_MIN_FILTER 0x2801
#define GL_TEXTURE_WRAP_S 0x2802
#define GL_TEXTURE_WRAP_T 0x2803
/* TextureTarget */
/* GL_TEXTURE_2D */
#define GL_TEXTURE 0x1702
#define GL_TEXTURE_CUBE_MAP 0x8513
#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
/* TextureUnit */
#define GL_TEXTURE0 0x84C0
#define GL_TEXTURE1 0x84C1
#define GL_TEXTURE2 0x84C2
#define GL_TEXTURE3 0x84C3
#define GL_TEXTURE4 0x84C4
#define GL_TEXTURE5 0x84C5
#define GL_TEXTURE6 0x84C6
#define GL_TEXTURE7 0x84C7
#define GL_TEXTURE8 0x84C8
#define GL_TEXTURE9 0x84C9
#define GL_TEXTURE10 0x84CA
#define GL_TEXTURE11 0x84CB
#define GL_TEXTURE12 0x84CC
#define GL_TEXTURE13 0x84CD
#define GL_TEXTURE14 0x84CE
#define GL_TEXTURE15 0x84CF
#define GL_TEXTURE16 0x84D0
#define GL_TEXTURE17 0x84D1
#define GL_TEXTURE18 0x84D2
#define GL_TEXTURE19 0x84D3
#define GL_TEXTURE20 0x84D4
#define GL_TEXTURE21 0x84D5
#define GL_TEXTURE22 0x84D6
#define GL_TEXTURE23 0x84D7
#define GL_TEXTURE24 0x84D8
#define GL_TEXTURE25 0x84D9
#define GL_TEXTURE26 0x84DA
#define GL_TEXTURE27 0x84DB
#define GL_TEXTURE28 0x84DC
#define GL_TEXTURE29 0x84DD
#define GL_TEXTURE30 0x84DE
#define GL_TEXTURE31 0x84DF
#define GL_ACTIVE_TEXTURE 0x84E0
/* TextureWrapMode */
#define GL_REPEAT 0x2901
#define GL_CLAMP_TO_EDGE 0x812F
#define GL_MIRRORED_REPEAT 0x8370
/* Uniform Types */
#define GL_FLOAT_VEC2 0x8B50
#define GL_FLOAT_VEC3 0x8B51
#define GL_FLOAT_VEC4 0x8B52
#define GL_INT_VEC2 0x8B53
#define GL_INT_VEC3 0x8B54
#define GL_INT_VEC4 0x8B55
#define GL_BOOL 0x8B56
#define GL_BOOL_VEC2 0x8B57
#define GL_BOOL_VEC3 0x8B58
#define GL_BOOL_VEC4 0x8B59
#define GL_FLOAT_MAT2 0x8B5A
#define GL_FLOAT_MAT3 0x8B5B
#define GL_FLOAT_MAT4 0x8B5C
#define GL_SAMPLER_2D 0x8B5E
#define GL_SAMPLER_CUBE 0x8B60
/* Vertex Arrays */
#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
/* Read Format */
#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
/* Shader Source */
#define GL_COMPILE_STATUS 0x8B81
#define GL_INFO_LOG_LENGTH 0x8B84
#define GL_SHADER_SOURCE_LENGTH 0x8B88
#define GL_SHADER_COMPILER 0x8DFA
/* Shader Binary */
#define GL_SHADER_BINARY_FORMATS 0x8DF8
#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
/* Shader Precision-Specified Types */
#define GL_LOW_FLOAT 0x8DF0
#define GL_MEDIUM_FLOAT 0x8DF1
#define GL_HIGH_FLOAT 0x8DF2
#define GL_LOW_INT 0x8DF3
#define GL_MEDIUM_INT 0x8DF4
#define GL_HIGH_INT 0x8DF5
/* Framebuffer Object. */
#define GL_FRAMEBUFFER 0x8D40
#define GL_RENDERBUFFER 0x8D41
#define GL_RGBA4 0x8056
#define GL_RGB5_A1 0x8057
#define GL_RGB565 0x8D62
#define GL_DEPTH_COMPONENT16 0x81A5
#define GL_STENCIL_INDEX 0x1901
#define GL_STENCIL_INDEX8 0x8D48
#define GL_RENDERBUFFER_WIDTH 0x8D42
#define GL_RENDERBUFFER_HEIGHT 0x8D43
#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
#define GL_RENDERBUFFER_RED_SIZE 0x8D50
#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
#define GL_COLOR_ATTACHMENT0 0x8CE0
#define GL_DEPTH_ATTACHMENT 0x8D00
#define GL_STENCIL_ATTACHMENT 0x8D20
#define GL_NONE 0
#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
#define GL_FRAMEBUFFER_BINDING 0x8CA6
#define GL_RENDERBUFFER_BINDING 0x8CA7
#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
訂閱:
文章 (Atom)





