显示列表
打包所有状态到显存 不需要每次都调用那么多函数
创建显示列表
_cubeDisplay = 1;
glNewList(_cubeDisplay,GL_COMPILE);
renderCube();
结束指令
glEndList();
绘制
glCallList(_cubeDisplay);
一个指令完成之前的绘制命令
也可以将显示列表放在一个数组里面 unsigned char list[] = {_cubeDisplay,_maskDisplay};
绘制时候使用 glCallLists(2,GL_UNSIGNED_BYTE,list);
#include "OpenGLWindow.h"
#include <mmsystem.h>
#include "freeimage.h"
#include "CELLMath.hpp"
using namespace CELL;
struct Vertex
{
float x, y, z;
float u, v;
};
class Sprite :public OpenGLWindow
{
public:
GLuint _texture1;
GLuint _texture2;
GLuint _texture3;
GLuint _cubeDisplay;
GLuint _maskDisplay;
public:
unsigned createTexture(int w, int h, const void* data, GLenum type)
{
unsigned texId;
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, type, w, h, 0, type, GL_UNSIGNED_BYTE, data);
return texId;
}
/**
* ʹ��FreeImage����ͼƬ
*/
unsigned createTextureFromImage(const char* fileName)
{
//1 ��ȡͼƬ��ʽ
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0);
if (fifmt == FIF_UNKNOWN)
{
return 0;
}
//2 ����ͼƬ
FIBITMAP *dib = FreeImage_Load(fifmt, fileName, 0);
FREE_IMAGE_COLOR_TYPE type = FreeImage_GetColorType(dib);
//! ��ȡ����ָ��
FIBITMAP* temp = dib;
dib = FreeImage_ConvertTo32Bits(dib);
FreeImage_Unload(temp);
BYTE* pixels = (BYTE*)FreeImage_GetBits(dib);
int width = FreeImage_GetWidth(dib);
int height = FreeImage_GetHeight(dib);
for (int i = 0; i < width * height * 4; i += 4)
{
BYTE temp = pixels[i];
pixels[i] = pixels[i + 2];
pixels[i + 2] = temp;
}
unsigned res = createTexture(width, height, pixels, GL_RGBA);
FreeImage_Unload(dib);
return res;
}
public:
virtual void onInitGL()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, double(_width) / double(_height), 0.1f, 100.0f);
_texture1 = createTextureFromImage("floor.bmp");
_texture2 = createTextureFromImage("CrossHair.bmp");
_texture3 = createTextureFromImage("CrossHairMask.bmp");
_cubeDisplay = 1;
glNewList(_cubeDisplay,GL_COMPILE);
renderCube();
glEndList();
_maskDisplay = 2;
glNewList(_maskDisplay,GL_COMPILE);
renderOrth();
glEndList();
}
virtual void onShutdownGL()
{
glDeleteTextures(1, &_texture1);
glDeleteTextures(1, &_texture2);
glDeleteTextures(1, &_texture3);
glDeleteLists(_cubeDisplay,1);
glDeleteLists(_maskDisplay, 1);
}
void renderCube()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, double(_width) / double(_height), 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -5);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
// Bind the wall texture to the wall quads
glBindTexture(GL_TEXTURE_2D, _texture1);
// Display a 4 long quads to represent walls
glBegin(GL_QUADS);
// BACK WALL ///
glTexCoord2f(0.0f, 2.0f); glVertex3f(-15, 1, -15);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-15, -1, -15);
glTexCoord2f(12.0f, 0.0f); glVertex3f(15, -1, -15);
glTexCoord2f(12.0f, 2.0f); glVertex3f(15, 1, -15);
// FRONT WALL ///
glTexCoord2f(0.0f, 2.0f); glVertex3f(-15, 1, 15);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-15, -1, 15);
glTexCoord2f(12.0f, 0.0f); glVertex3f(15, -1, 15);
glTexCoord2f(12.0f, 2.0f); glVertex3f(15, 1, 15);
// LEFT WALL ///
glTexCoord2f(0.0f, 2.0f); glVertex3f(-15, 1, -15);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-15, -1, -15);
glTexCoord2f(12.0f, 0.0f); glVertex3f(-15, -1, 15);
glTexCoord2f(12.0f, 2.0f); glVertex3f(-15, 1, 15);
// RIGHT WALL ///
glTexCoord2f(0.0f, 2.0f); glVertex3f(15, 1, -15);
glTexCoord2f(0.0f, 0.0f); glVertex3f(15, -1, -15);
glTexCoord2f(12.0f, 0.0f); glVertex3f(15, -1, 15);
glTexCoord2f(12.0f, 2.0f); glVertex3f(15, 1, 15);
// Stop drawing the walls
glEnd();
// Bind this texture to the floor quad
glBindTexture(GL_TEXTURE_2D, _texture1);
// Display a huge quad to represent a floor
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 16.0f); glVertex3f(-15, -1, -15);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-15, -1, 15);
glTexCoord2f(16.0f, 0.0f); glVertex3f(15, -1, 15);
glTexCoord2f(16.0f, 16.0f); glVertex3f(15, -1, -15);
// Stop drawing the floor
glEnd();
}
void renderOrth()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, _width, _height, 0, -100, 100);
Vertex vert[] =
{
{ 0, 0 , 0, 0.0f, 1.0f },
{ 0, _height , 0, 0.0f, 0.0f },
{ _width, _height , 0, 1.0f, 0.0f },
{ _width, 0 , 0, 1.0f, 1.0f },
};
glDisable(GL_DEPTH_TEST);
glBlendFunc(GL_DST_COLOR, GL_ZERO);
glEnable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, _texture3);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &vert[0].x);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &vert[0].u);
glDrawArrays(GL_QUADS, 0, 4);
glBlendFunc(GL_ONE, GL_ONE);
glBindTexture(GL_TEXTURE_2D, _texture2);
glDrawArrays(GL_QUADS, 0, 4);
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
}
virtual void render(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//renderCube();
unsigned char list[] = {_cubeDisplay,_maskDisplay};
glCallLists(2,GL_UNSIGNED_BYTE,list);
//glCallList(_cubeDisplay);
//renderOrth();
//glCallList(_maskDisplay);
}
};
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
Sprite context;
context.main(640, 480);
return 0;
}
VBO 顶点缓存对象
应用程序客户端 opengl是服务端
每一次都要从传递数据给显卡
直接将数据放在显卡 减少了数据从内存到显存的传递 提升了效率
创建
glGenBuffers(1,&_vbo); //生成vbo句柄
glBindBuffer(GL_ARRAY_BUFFER,_vbo); //绑定 告诉buffer是用来做什么的
传送
glBufferData(GL_ARRAY_BUFFER,sizeof(g_cubeVertices),g_cubeVertices,GL_STATIC_DRAW); //传送到显存 参数 顶点缓存类型 数据大小 数据 数据的用途
glBindBuffer(GL_ARRAY_BUFFER,0); //防止对后续的绘制影响 重置缓存
使用
绘制之前开始
glBindBuffer(GL_ARRAY_BUFFER,_vbo);
告诉使用VBO绘制
opengl根据元素之间的内存偏移来计算下一个元素的位置 1个float 4个字节
float* addrVertex = (float*)0;
float* uvAddress = (float*)12;
float* colorAddress = (float*)20;
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), addrVertex);
glColorPointer(3, GL_FLOAT, sizeof(Vertex), colorAddress);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), uvAddress);
glBufferSubData 可以用来更新数据 显示列表没这个功能
#include "OpenGLWindow.h"
#include <mmsystem.h>
#include "freeimage.h"
#include "CELLMath.hpp"
using namespace CELL;
#pragma comment(lib,"winmm.lib")
struct Vertex
{
float x, y, z;
float u, v;
float r, g, b;
}
Vertex g_cubeVertices[] =
{
{ -1.0f,-1.0f, 1.0f,0.0f, 0.0f,1.0f, 0.0f, 0.0f },
{ 1.0f,-1.0f, 1.0f,1.0f, 0.0f,1.0f, 0.0f, 0.0f },
{ 1.0f, 1.0f, 1.0f,1.0f, 1.0f,1.0f, 0.0f, 0.0f },
{ -1.0f, 1.0f, 1.0f,0.0f, 1.0f,1.0f, 0.0f, 0.0f },
{ -1.0f,-1.0f,-1.0f,1.0f, 0.0f,0.0f, 1.0f, 0.0f },
{ -1.0f, 1.0f,-1.0f,1.0f, 1.0f,0.0f, 1.0f, 0.0f },
{ 1.0f, 1.0f,-1.0f,0.0f, 1.0f,0.0f, 1.0f, 0.0f },
{ 1.0f,-1.0f,-1.0f,0.0f, 0.0f,0.0f, 1.0f, 0.0f },
{ -1.0f, 1.0f,-1.0f,0.0f, 1.0f,0.0f, 0.0f, 1.0f },
{ -1.0f, 1.0f, 1.0f,0.0f, 0.0f,0.0f, 0.0f, 1.0f },
{ 1.0f, 1.0f, 1.0f,1.0f, 0.0f,0.0f, 0.0f, 1.0f },
{ 1.0f, 1.0f,-1.0f,1.0f, 1.0f,0.0f, 0.0f, 1.0f },
{ -1.0f,-1.0f,-1.0f,1.0f, 1.0f,1.0f, 1.0f, 0.0f },
{ 1.0f,-1.0f,-1.0f,0.0f, 1.0f,1.0f, 1.0f, 0.0f },
{ 1.0f,-1.0f, 1.0f,0.0f, 0.0f,1.0f, 1.0f, 0.0f },
{ -1.0f,-1.0f, 1.0f,1.0f, 0.0f,1.0f, 1.0f, 0.0f },
{ 1.0f,-1.0f,-1.0f,1.0f, 0.0f,1.0f, 0.0f, 1.0f },
{ 1.0f, 1.0f,-1.0f,1.0f, 1.0f,1.0f, 0.0f, 1.0f },
{ 1.0f, 1.0f, 1.0f,0.0f, 1.0f,1.0f, 0.0f, 1.0f },
{ 1.0f,-1.0f, 1.0f,0.0f, 0.0f,1.0f, 0.0f, 1.0f },
{ -1.0f,-1.0f,-1.0f,0.0f, 0.0f,0.0f, 1.0f, 1.0f },
{ -1.0f,-1.0f, 1.0f,1.0f, 0.0f,0.0f, 1.0f, 1.0f },
{ -1.0f, 1.0f, 1.0f,1.0f, 1.0f,0.0f, 1.0f, 1.0f },
{ -1.0f, 1.0f,-1.0f,0.0f, 1.0f,0.0f, 1.0f, 1.0f }
};
class VertexBufferObject :public OpenGLWindow
{
public:
GLuint _texture;
GLuint _vbo;
public:
unsigned createTexture(int w, int h, const void* data, GLenum type)
{
unsigned texId;
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, type, w, h, 0, type, GL_UNSIGNED_BYTE, data);
return texId;
}
/**
* ʹ��FreeImage����ͼƬ
*/
unsigned createTextureFromImage(const char* fileName)
{
//1 ��ȡͼƬ��ʽ
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0);
if (fifmt == FIF_UNKNOWN)
{
return 0;
}
//2 ����ͼƬ
FIBITMAP *dib = FreeImage_Load(fifmt, fileName, 0);
FREE_IMAGE_COLOR_TYPE type = FreeImage_GetColorType(dib);
//! ��ȡ����ָ��
FIBITMAP* temp = dib;
dib = FreeImage_ConvertTo32Bits(dib);
FreeImage_Unload(temp);
BYTE* pixels = (BYTE*)FreeImage_GetBits(dib);
int width = FreeImage_GetWidth(dib);
int height = FreeImage_GetHeight(dib);
for (int i = 0; i < width * height * 4; i += 4)
{
BYTE temp = pixels[i];
pixels[i] = pixels[i + 2];
pixels[i + 2] = temp;
}
unsigned res = createTexture(width, height, pixels, GL_RGBA);
FreeImage_Unload(dib);
return res;
}
public:
virtual void onInitGL()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, double(_width) / double(_height), 0.1f, 100.0f);
_texture = createTextureFromImage("floor.bmp");
glGenBuffers(1,&_vbo);
glBindBuffer(GL_ARRAY_BUFFER,_vbo);
glBufferData(GL_ARRAY_BUFFER,sizeof(g_cubeVertices),g_cubeVertices,GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER,0);
}
virtual void onShutdownGL()
{
glDeleteBuffers(1,&_vbo);
}
void renderCube()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, double(_width) / double(_height), 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -5);
glBindTexture(GL_TEXTURE_2D, _texture);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER,_vbo);
//glEnable(GL_DEPTH_TEST);
/**
* �����ҿ����������
*/
float* addrVertex = (float*)0;
float* uvAddress = (float*)12;
float* colorAddress = (float*)20;
//--------------Ԫ�ظ���---Ԫ������---Ԫ��֮����ڴ�ƫ��---���ݵ�ַ
//OpenGL����Ԫ��֮����ڴ�ƫ����������һ��Ԫ�ص�λ�á�
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), addrVertex);
glColorPointer(3, GL_FLOAT, sizeof(Vertex), colorAddress);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), uvAddress);
glDrawArrays(GL_QUADS, 0, 24);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
virtual void render(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//! ������
renderCube();
}
};
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
VertexBufferObject context;
context.main(640, 480);
return 0;
}
索引缓冲 减少重复顶点
1.创建顶点缓冲区 索引缓冲区
glGenBuffers(1,&_vbo);
glBindBuffer(GL_ARRAY_BUFFER,_vbo);
glBufferData(GL_ARRAY_BUFFER,sizeof(g_cubeVertices),g_cubeVertices,GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER,0);
glGenBuffers(1,&_ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,_ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(g_cubeIndices),g_cubeIndices,GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
绘制之前绑定缓冲区
glBindBuffer(GL_ARRAY_BUFFER,_vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,_ibo);
绘制方法修改
float* addrVertex = (float*)12;
float* colorAddress = (float*)0;
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), addrVertex);
glColorPointer(3, GL_FLOAT, sizeof(Vertex), colorAddress);
glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, 0);
#include "OpenGLWindow.h"
#include <mmsystem.h>
#include "freeimage.h"
#include "CELLMath.hpp"
using namespace CELL;
#pragma comment(lib,"winmm.lib")
struct Vertex
{
float r, g, b;
float x, y, z;
};
Vertex g_cubeVertices[] =
{
{ 1.0f,0.0f,0.0f, -1.0f,-1.0f, 1.0f }, // 0
{ 0.0f,1.0f,0.0f, 1.0f,-1.0f, 1.0f }, // 1
{ 0.0f,0.0f,1.0f, 1.0f, 1.0f, 1.0f }, // 2
{ 1.0f,1.0f,0.0f, -1.0f, 1.0f, 1.0f }, // 3
{ 1.0f,0.0f,1.0f, -1.0f,-1.0f,-1.0f }, // 4
{ 0.0f,1.0f,1.0f, -1.0f, 1.0f,-1.0f }, // 5
{ 1.0f,1.0f,1.0f, 1.0f, 1.0f,-1.0f }, // 6
{ 1.0f,0.0f,0.0f, 1.0f,-1.0f,-1.0f }, // 7
};
GLubyte g_cubeIndices[] =
{
0, 1, 2, 3, // Quad 0
4, 5, 6, 7, // Quad 1
5, 3, 2, 6, // Quad 2
4, 7, 1, 0, // Quad 3
7, 6, 2, 1, // Quad 4
4, 0, 3, 5 // Quad 5
};
class IndexBufferObject :public OpenGLWindow
{
public:
GLuint _texture;
GLuint _vbo;
GLuint _ibo;
public:
unsigned createTexture(int w, int h, const void* data, GLenum type)
{
unsigned texId;
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, type, w, h, 0, type, GL_UNSIGNED_BYTE, data);
return texId;
}
/**
* ʹ��FreeImage����ͼƬ
*/
unsigned createTextureFromImage(const char* fileName)
{
//1 ��ȡͼƬ��ʽ
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0);
if (fifmt == FIF_UNKNOWN)
{
return 0;
}
//2 ����ͼƬ
FIBITMAP *dib = FreeImage_Load(fifmt, fileName, 0);
FREE_IMAGE_COLOR_TYPE type = FreeImage_GetColorType(dib);
//! ��ȡ����ָ��
FIBITMAP* temp = dib;
dib = FreeImage_ConvertTo32Bits(dib);
FreeImage_Unload(temp);
BYTE* pixels = (BYTE*)FreeImage_GetBits(dib);
int width = FreeImage_GetWidth(dib);
int height = FreeImage_GetHeight(dib);
for (int i = 0; i < width * height * 4; i += 4)
{
BYTE temp = pixels[i];
pixels[i] = pixels[i + 2];
pixels[i + 2] = temp;
}
unsigned res = createTexture(width, height, pixels, GL_RGBA);
FreeImage_Unload(dib);
return res;
}
public:
virtual void onInitGL()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, double(_width) / double(_height), 0.1f, 100.0f);
glGenBuffers(1,&_vbo);
glBindBuffer(GL_ARRAY_BUFFER,_vbo);
glBufferData(GL_ARRAY_BUFFER,sizeof(g_cubeVertices),g_cubeVertices,GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER,0);
glGenBuffers(1,&_ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,_ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(g_cubeIndices),g_cubeIndices,GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
}
virtual void onShutdownGL()
{
}
void renderCube()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, double(_width) / double(_height), 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -5);
glBindBuffer(GL_ARRAY_BUFFER,_vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,_ibo);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
float* addrVertex = (float*)12;
float* colorAddress = (float*)0;
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), addrVertex);
glColorPointer(3, GL_FLOAT, sizeof(Vertex), colorAddress);
glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
virtual void render(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//! ������
renderCube();
}
};
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
IndexBufferObject context;
context.main(640, 480);
return 0;
}
离屏渲染
pbuffer opengl扩展 一个应用程序建立多个opengl对象
建立一个opengl对象在后台绘制
封装pbuffer类
存储数据用于后台绘制
两个opengl对象 一个主窗口 一个后台的pbuffer
wglsharelists 两个对象共享资源
窗口不显示也可以渲染 叫做离屏渲染
1.创建pbuffer
2.改变上下问 将pbuffer设置为当前对象 将主窗口渲染结果 输出到贴图
3.使用pbuffer后台的渲染结果 再对主窗口进行渲染
#include "OpenGLWindow.h"
#include <mmsystem.h>
#include "freeimage.h"
#include "CELLMath.hpp"
#include "PixelBuffer.h"
using namespace CELL;
#pragma comment(lib,"winmm.lib")
struct Vertex
{
float x, y, z;
float u, v;
float r, g, b;
};
class PBOWindow :public OpenGLWindow
{
public:
GLuint _texture;
PixelBuffer _pbuffer;
GLuint _dynamic;
public:
unsigned createTexture(int w, int h, const void* data, GLenum type)
{
unsigned texId;
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, type, w, h, 0, type, GL_UNSIGNED_BYTE, data);
return texId;
}
/**
* ʹ��FreeImage����ͼƬ
*/
unsigned createTextureFromImage(const char* fileName)
{
//1 ��ȡͼƬ��ʽ
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0);
if (fifmt == FIF_UNKNOWN)
{
return 0;
}
//2 ����ͼƬ
FIBITMAP *dib = FreeImage_Load(fifmt, fileName, 0);
FREE_IMAGE_COLOR_TYPE type = FreeImage_GetColorType(dib);
//! ��ȡ����ָ��
FIBITMAP* temp = dib;
dib = FreeImage_ConvertTo32Bits(dib);
FreeImage_Unload(temp);
BYTE* pixels = (BYTE*)FreeImage_GetBits(dib);
int width = FreeImage_GetWidth(dib);
int height = FreeImage_GetHeight(dib);
for (int i = 0; i < width * height * 4; i += 4)
{
BYTE temp = pixels[i];
pixels[i] = pixels[i + 2];
pixels[i + 2] = temp;
}
unsigned res = createTexture(width, height, pixels, GL_RGBA);
FreeImage_Unload(dib);
return res;
}
public:
virtual void onInitGL()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, double(_width) / double(_height), 0.1f, 100.0f);
_texture = createTextureFromImage("floor.bmp");
_pbuffer.setup(_hWnd,_hDC,_hRC,640,480);
glEnable(GL_TEXTURE_2D);
_dynamic = createTexture(_pbuffer._width, _pbuffer._height,0,GL_RGBA);
}
virtual void onShutdownGL()
{
}
void renderCube(GLuint tex,bool rot)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, double(_width) / double(_height), 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -5);
static float angle = 0;
if (rot)
{
glRotated(angle,1,1,1);
++angle;
}
glBindTexture(GL_TEXTURE_2D, tex);
Vertex g_cubeVertices[] =
{
{ -1.0f,-1.0f, 1.0f,0.0f, 0.0f,1.0f, 0.0f, 0.0f },
{ 1.0f,-1.0f, 1.0f,1.0f, 0.0f,1.0f, 0.0f, 0.0f },
{ 1.0f, 1.0f, 1.0f,1.0f, 1.0f,1.0f, 0.0f, 0.0f },
{ -1.0f, 1.0f, 1.0f,0.0f, 1.0f,1.0f, 0.0f, 0.0f },
{ -1.0f,-1.0f,-1.0f,1.0f, 0.0f,0.0f, 1.0f, 0.0f },
{ -1.0f, 1.0f,-1.0f,1.0f, 1.0f,0.0f, 1.0f, 0.0f },
{ 1.0f, 1.0f,-1.0f,0.0f, 1.0f,0.0f, 1.0f, 0.0f },
{ 1.0f,-1.0f,-1.0f,0.0f, 0.0f,0.0f, 1.0f, 0.0f },
{ -1.0f, 1.0f,-1.0f,0.0f, 1.0f,0.0f, 0.0f, 1.0f },
{ -1.0f, 1.0f, 1.0f,0.0f, 0.0f,0.0f, 0.0f, 1.0f },
{ 1.0f, 1.0f, 1.0f,1.0f, 0.0f,0.0f, 0.0f, 1.0f },
{ 1.0f, 1.0f,-1.0f,1.0f, 1.0f,0.0f, 0.0f, 1.0f },
{ -1.0f,-1.0f,-1.0f,1.0f, 1.0f,1.0f, 1.0f, 0.0f },
{ 1.0f,-1.0f,-1.0f,0.0f, 1.0f,1.0f, 1.0f, 0.0f },
{ 1.0f,-1.0f, 1.0f,0.0f, 0.0f,1.0f, 1.0f, 0.0f },
{ -1.0f,-1.0f, 1.0f,1.0f, 0.0f,1.0f, 1.0f, 0.0f },
{ 1.0f,-1.0f,-1.0f,1.0f, 0.0f,1.0f, 0.0f, 1.0f },
{ 1.0f, 1.0f,-1.0f,1.0f, 1.0f,1.0f, 0.0f, 1.0f },
{ 1.0f, 1.0f, 1.0f,0.0f, 1.0f,1.0f, 0.0f, 1.0f },
{ 1.0f,-1.0f, 1.0f,0.0f, 0.0f,1.0f, 0.0f, 1.0f },
{ -1.0f,-1.0f,-1.0f,0.0f, 0.0f,0.0f, 1.0f, 1.0f },
{ -1.0f,-1.0f, 1.0f,1.0f, 0.0f,0.0f, 1.0f, 1.0f },
{ -1.0f, 1.0f, 1.0f,1.0f, 1.0f,0.0f, 1.0f, 1.0f },
{ -1.0f, 1.0f,-1.0f,0.0f, 1.0f,0.0f, 1.0f, 1.0f }
};
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
/**
* �����ҿ����������
*/
float* addrVertex = (float*)g_cubeVertices;
float* uvAddress = (float*)&g_cubeVertices[0].u;
float* colorAddress = (float*)&g_cubeVertices[0].r;
//--------------Ԫ�ظ���---Ԫ������---Ԫ��֮����ڴ�ƫ��---���ݵ�ַ
//OpenGL����Ԫ��֮����ڴ�ƫ����������һ��Ԫ�ص�λ�á�
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), addrVertex);
glColorPointer(3, GL_FLOAT, sizeof(Vertex), colorAddress);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), uvAddress);
glDrawArrays(GL_QUADS, 0, 24);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
virtual void render(void)
{
_pbuffer.makeCurrent();
//glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
renderCube(_texture,true);
glBindTexture(GL_TEXTURE_2D, _dynamic);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, _pbuffer._width, _pbuffer._height);
makeCurrent();
//glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// //! ������
renderCube(_dynamic,false);
}
};
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
PBOWindow context;
context.main(640, 480);
return 0;
}
FBO 帧缓冲对象 另外一种离屏渲染方式 比pbuffer要好 pbuffer需要两个opengl对象 交替当前对象
FBO 缓存一帧的对象
建立 FrameBuffer
glGenFramebuffers(1, &_FBOID); //产生一个对象 不分配空间
glBindFramebuffer(GL_FRAMEBUFFER, _FBOID);
glGenRenderbuffers(1, &_RBOID);
glBindRenderbuffer(GL_RENDERBUFFER, _RBOID);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, _width, _height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
//关联 只有深度没有颜色
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _RBOID);
//颜色使用纹理
void begin(GLuint textureId)
{
glBindFramebuffer(GL_FRAMEBUFFER, _FBOID);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _RBOID );
}
virtual void render(void)
{
_fbo.begin(_textureId);
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
renderCube(_texture);
_fbo.end();
}
上面操作都是在fbo进行 看不到渲染的结果
结果缓存在纹理
切换渲染到主窗口
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
renderCube(_textureId,false);
跟pbuffer相比 占用内存更小 不保存状态 不需要创建另一个对象
读取屏幕数据 pbuffer或者fbo
glReadPixels
RECT rect;
GetClientRect(_hWnd,&rect);
int w = rect.right - rect.left;
int h = rect.bottom - rect.top;
unsigned char* data= new unsigned char[w * h * 4];
memset(data,0,w * h * 4);
glReadPixels(0,0,w,h,GL_RGBA,GL_UNSIGNED_BYTE,data);