Added texture update example.

This commit is contained in:
bkaradzic 2013-01-06 17:53:45 -08:00
parent 637ab129d3
commit 7ec5de1ad1
23 changed files with 472 additions and 19 deletions

View file

@ -135,6 +135,9 @@ Loading textures.
Implementing application specific callbacks for taking screen shots, caching
OpenGL binary shaders, and video capture.
### 08-update
Updating textures.
Internals
---------

View file

@ -338,11 +338,11 @@ int _main_(int _argc, char** _argv)
// Load diffuse texture.
mem = loadTexture("fieldstone-rgba.dds");
bgfx::TextureHandle texture_rgba = bgfx::createTexture(mem);
bgfx::TextureHandle textureColor = bgfx::createTexture(mem);
// Load normal texture.
mem = loadTexture("fieldstone-n.dds");
bgfx::TextureHandle texture_n = bgfx::createTexture(mem);
bgfx::TextureHandle textureNormal = bgfx::createTexture(mem);
while (true)
{
@ -437,8 +437,8 @@ int _main_(int _argc, char** _argv)
bgfx::setInstanceDataBuffer(idb, numInstances);
// Bind textures.
bgfx::setTexture(0, u_texColor, texture_rgba);
bgfx::setTexture(1, u_texNormal, texture_n);
bgfx::setTexture(0, u_texColor, textureColor);
bgfx::setTexture(1, u_texNormal, textureNormal);
// Set render states.
bgfx::setState(BGFX_STATE_RGB_WRITE
@ -459,8 +459,8 @@ int _main_(int _argc, char** _argv)
bgfx::destroyIndexBuffer(ibh);
bgfx::destroyVertexBuffer(vbh);
bgfx::destroyProgram(program);
bgfx::destroyTexture(texture_rgba);
bgfx::destroyTexture(texture_n);
bgfx::destroyTexture(textureColor);
bgfx::destroyTexture(textureNormal);
bgfx::destroyUniform(u_texColor);
bgfx::destroyUniform(u_texNormal);

View file

@ -0,0 +1,15 @@
$input v_texcoord0
/*
* Copyright 2011-2012 Branimir Karadzic. All rights reserved.
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#include "../common/common.sh"
SAMPLERCUBE(u_texCube, 0);
void main()
{
gl_FragColor = textureCube(u_texCube, v_texcoord0);
}

View file

@ -0,0 +1,17 @@
#
# Copyright 2011-2012 Branimir Karadzic. All rights reserved.
# License: http://www.opensource.org/licenses/BSD-2-Clause
#
BGFX_DIR=../..
RUNTIME_DIR=$(BGFX_DIR)/examples/runtime
BUILD_DIR=../../.build
include $(BGFX_DIR)/premake/shader.mk
rebuild:
@make -s --no-print-directory TARGET=0 clean all
@make -s --no-print-directory TARGET=1 clean all
@make -s --no-print-directory TARGET=2 clean all
@make -s --no-print-directory TARGET=3 clean all
@make -s --no-print-directory TARGET=4 clean all

View file

@ -0,0 +1,336 @@
/*
* Copyright 2011-2012 Branimir Karadzic. All rights reserved.
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#include <bgfx.h>
#include <bx/bx.h>
#include <bx/timer.h>
#include "../common/dbg.h"
#include "../common/math.h"
#include <stdio.h>
#include <string.h>
struct PosColorVertex
{
float m_x;
float m_y;
float m_z;
float m_u;
float m_v;
float m_w;
};
static bgfx::VertexDecl s_PosTexcoordDecl;
static PosColorVertex s_cubeVertices[24] =
{
{-1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f },
{ 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f },
{-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f },
{ 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f },
{-1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f },
{ 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f },
{-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f },
{ 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f },
{-1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f },
{-1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f },
{-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f },
{-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f },
{ 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f },
{ 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f },
{ 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f },
{ 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f },
{-1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f },
{ 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f },
{-1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f },
{ 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f },
{-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f },
{-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f },
{ 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f },
{ 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f },
};
static const uint16_t s_cubeIndices[36] =
{
0, 2, 1, // 0
1, 2, 3,
4, 5, 6, // 2
5, 7, 6,
8, 9, 10, // 4
9, 11, 10,
12, 13, 14, // 6
14, 13, 15,
16, 17, 18, // 8
18, 17, 19,
20, 21, 22, // 10
21, 23, 22,
};
static const char* s_shaderPath = NULL;
static void shaderFilePath(char* _out, const char* _name)
{
strcpy(_out, s_shaderPath);
strcat(_out, _name);
strcat(_out, ".bin");
}
long int fsize(FILE* _file)
{
long int pos = ftell(_file);
fseek(_file, 0L, SEEK_END);
long int size = ftell(_file);
fseek(_file, pos, SEEK_SET);
return size;
}
static const bgfx::Memory* load(const char* _filePath)
{
FILE* file = fopen(_filePath, "rb");
if (NULL != file)
{
uint32_t size = (uint32_t)fsize(file);
const bgfx::Memory* mem = bgfx::alloc(size+1);
size_t ignore = fread(mem->data, 1, size, file);
BX_UNUSED(ignore);
fclose(file);
mem->data[mem->size-1] = '\0';
return mem;
}
return NULL;
}
static const bgfx::Memory* loadShader(const char* _name)
{
char filePath[512];
shaderFilePath(filePath, _name);
return load(filePath);
}
int _main_(int _argc, char** _argv)
{
bgfx::init();
bgfx::reset(1280, 720);
// Enable debug text.
bgfx::setDebug(BGFX_DEBUG_TEXT);
// Set view 0 default viewport.
bgfx::setViewRect(0, 0, 0, 1280, 720);
// Set view 0 clear state.
bgfx::setViewClear(0
, BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT
, 0x303030ff
, 1.0f
, 0
);
// Setup root path for binary shaders. Shader binaries are different
// for each renderer.
switch (bgfx::getRendererType() )
{
default:
case bgfx::RendererType::Direct3D9:
s_shaderPath = "shaders/dx9/";
break;
case bgfx::RendererType::Direct3D11:
s_shaderPath = "shaders/dx11/";
break;
case bgfx::RendererType::OpenGL:
s_shaderPath = "shaders/glsl/";
break;
case bgfx::RendererType::OpenGLES2:
case bgfx::RendererType::OpenGLES3:
s_shaderPath = "shaders/gles/";
break;
}
// Create vertex stream declaration.
s_PosTexcoordDecl.begin();
s_PosTexcoordDecl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float);
s_PosTexcoordDecl.add(bgfx::Attrib::TexCoord0, 3, bgfx::AttribType::Float);
s_PosTexcoordDecl.end();
const bgfx::Memory* mem;
// Create static vertex buffer.
mem = bgfx::makeRef(s_cubeVertices, sizeof(s_cubeVertices) );
bgfx::VertexBufferHandle vbh = bgfx::createVertexBuffer(mem, s_PosTexcoordDecl);
// Create static index buffer.
mem = bgfx::makeRef(s_cubeIndices, sizeof(s_cubeIndices) );
bgfx::IndexBufferHandle ibh = bgfx::createIndexBuffer(mem);
// Create texture sampler uniforms.
bgfx::UniformHandle u_texCube = bgfx::createUniform("u_texCube", bgfx::UniformType::Uniform1iv);
// Load vertex shader.
mem = loadShader("vs_update");
bgfx::VertexShaderHandle vsh = bgfx::createVertexShader(mem);
// Load fragment shader.
mem = loadShader("fs_update");
bgfx::FragmentShaderHandle fsh = bgfx::createFragmentShader(mem);
// Create program from shaders.
bgfx::ProgramHandle program = bgfx::createProgram(vsh, fsh);
// We can destroy vertex and fragment shader here since
// their reference is kept inside bgfx after calling createProgram.
// Vertex and fragment shader will be destroyed once program is
// destroyed.
bgfx::destroyVertexShader(vsh);
bgfx::destroyFragmentShader(fsh);
uint32_t blockSide = 0;
uint32_t blockX = 0;
uint32_t blockY = 0;
const uint32_t blockWidth = 8;
const uint32_t blockHeight = 8;
const uint32_t textureSide = 256;
bgfx::TextureHandle textureCube =
bgfx::createTextureCube(6
, textureSide
, 1
, bgfx::TextureFormat::BGRA8
, BGFX_TEXTURE_MIN_POINT|BGFX_TEXTURE_MAG_POINT|BGFX_TEXTURE_MIP_POINT
);
bgfx::TextureInfo ti;
bgfx::calcTextureSize(ti, blockWidth, blockHeight, 1, 1, bgfx::TextureFormat::BGRA8);
uint8_t rr = rand()%255;
uint8_t gg = rand()%255;
uint8_t bb = rand()%255;
int64_t updateTime = 0;
while (true)
{
// This dummy draw call is here to make sure that view 0 is cleared
// if no other draw calls are submitted to view 0.
bgfx::submit(0);
int64_t now = bx::getHPCounter();
static int64_t last = now;
const int64_t frameTime = now - last;
last = now;
const int64_t freq = bx::getHPFrequency();
const double toMs = 1000.0/double(freq);
// Use debug font to print information about this example.
bgfx::dbgTextClear();
bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/08-update");
bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Updating textures.");
bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
if (now > updateTime)
{
// updateTime = now + freq/100;
const bgfx::Memory* mem = bgfx::alloc(ti.storageSize);
uint8_t* data = (uint8_t*)mem->data;
for (uint32_t ii = 0, num = ti.storageSize*8/ti.bitsPerPixel; ii < num; ++ii)
{
data[0] = bb;
data[1] = rr;
data[2] = gg;
data[3] = 0xff;
data += 4;
}
bgfx::updateTextureCube(textureCube, blockSide, 0, blockX, blockY, blockWidth, blockHeight, mem);
blockX += 8;
if (blockX > textureSide-1)
{
blockX = 0;
blockY += 8;
if (blockY > textureSide-1)
{
rr = rand()%255;
gg = rand()%255;
bb = rand()%255;
blockY = 0;
++blockSide;
if (blockSide > 5)
{
blockSide = 0;
}
}
}
}
float at[3] = { 0.0f, 0.0f, 0.0f };
float eye[3] = { 0.0f, 0.0f, -5.0f };
float view[16];
float proj[16];
mtxLookAt(view, eye, at);
mtxProj(proj, 60.0f, 16.0f/9.0f, 0.1f, 100.0f);
// Set view and projection matrix for view 0.
bgfx::setViewTransform(0, view, proj);
float time = (float)(bx::getHPCounter()/double(bx::getHPFrequency() ) );
float mtx[16];
mtxRotateXY(mtx, time, time*0.37f);
// Set model matrix for rendering.
bgfx::setTransform(mtx);
// Set vertex and fragment shaders.
bgfx::setProgram(program);
// Set vertex and index buffer.
bgfx::setVertexBuffer(vbh);
bgfx::setIndexBuffer(ibh);
// Bind texture.
bgfx::setTexture(0, u_texCube, textureCube);
// Set render states.
bgfx::setState(BGFX_STATE_RGB_WRITE
|BGFX_STATE_DEPTH_WRITE
|BGFX_STATE_DEPTH_TEST_LESS
);
// Submit primitive for rendering to view 0.
bgfx::submit(0);
// Advance to next frame. Rendering thread will be kicked to
// process submitted rendering primitives.
bgfx::frame();
}
// Cleanup.
bgfx::destroyIndexBuffer(ibh);
bgfx::destroyVertexBuffer(vbh);
bgfx::destroyProgram(program);
// Shutdown bgfx.
bgfx::shutdown();
return 0;
}

View file

@ -0,0 +1,4 @@
vec3 v_texcoord0 : TEXCOORD0 = vec3(9.0, 0.0, 0.0);
vec3 a_position : POSITION;
vec3 a_texcoord0 : TEXCOORD0;

View file

@ -0,0 +1,15 @@
$input a_position, a_texcoord0
$output v_texcoord0
/*
* Copyright 2011-2012 Branimir Karadzic. All rights reserved.
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#include "../common/common.sh"
void main()
{
gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0) );
v_texcoord0 = a_texcoord0;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -630,6 +630,7 @@ namespace bgfx
void updateTexture3D(TextureHandle _handle, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _z, uint16_t _width, uint16_t _height, uint16_t _depth, const Memory* _mem);
/// Update Cube texture.
/// @param _side Cubemap side, where 0 is +X, 1 is -X, 2 is +Y, 3 is -Y, 4 is +Z, and 5 is -Z.
void updateTextureCube(TextureHandle _handle, uint8_t _side, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const Memory* _mem);
/// Destroy texture.

View file

@ -0,0 +1,39 @@
project "example-08-update"
uuid "e011e246-5862-11e2-b202-b7cb257a7926"
kind "WindowedApp"
debugdir (BGFX_DIR .. "examples/runtime/")
includedirs {
BX_DIR .. "include",
BGFX_DIR .. "include",
}
files {
BGFX_DIR .. "examples/common/**.cpp",
BGFX_DIR .. "examples/common/**.h",
BGFX_DIR .. "examples/08-update/**.cpp",
BGFX_DIR .. "examples/08-update/**.h",
}
links {
"bgfx",
}
configuration { "emscripten" }
targetextension ".bc"
configuration { "nacl" }
targetextension ".nexe"
configuration { "nacl", "Release" }
postbuildcommands {
"@echo Stripping symbols.",
"@$(NACL)/bin/x86_64-nacl-strip -s \"$(TARGET)\""
}
configuration { "linux" }
links {
"GL",
"pthread",
}

View file

@ -41,3 +41,4 @@ dofile "example-04-mesh.lua"
dofile "example-05-instancing.lua"
dofile "example-06-bump.lua"
dofile "example-07-callback.lua"
dofile "example-08-update.lua"

View file

@ -921,6 +921,11 @@ namespace bgfx
void calcTextureSize(TextureInfo& _info, uint16_t _width, uint16_t _height, uint16_t _depth, uint8_t _numMips, TextureFormat::Enum _format)
{
_width = uint32_max(1, _width);
_height = uint32_max(1, _height);
_depth = uint32_max(1, _depth);
_numMips = uint32_max(1, _numMips);
uint32_t width = _width;
uint32_t height = _height;
uint32_t depth = _depth;
@ -985,6 +990,7 @@ namespace bgfx
tc.m_flags = _flags;
tc.m_width = _width;
tc.m_height = _height;
tc.m_sides = 0;
tc.m_depth = 0;
tc.m_numMips = _numMips;
tc.m_format = uint8_t(_format);
@ -1023,6 +1029,7 @@ namespace bgfx
tc.m_flags = _flags;
tc.m_width = _width;
tc.m_height = _height;
tc.m_sides = 0;
tc.m_depth = _depth;
tc.m_numMips = _numMips;
tc.m_format = uint8_t(_format);
@ -1060,6 +1067,7 @@ namespace bgfx
TextureCreate tc;
tc.m_flags = _flags;
tc.m_width = _width;
tc.m_height = _width;
tc.m_sides = _sides;
tc.m_depth = 0;
tc.m_numMips = _numMips;

View file

@ -164,11 +164,8 @@ namespace bgfx
{
uint32_t m_flags;
uint16_t m_width;
union
{
uint16_t m_height;
uint16_t m_sides;
};
uint16_t m_height;
uint16_t m_sides;
uint16_t m_depth;
uint8_t m_numMips;
uint8_t m_format;

View file

@ -1645,7 +1645,7 @@ namespace bgfx
, ...
);
#else
deviceCtx->UpdateSubresource(m_ptr, subres, &box, _mem->data, _rect.m_width, 0);
deviceCtx->UpdateSubresource(m_ptr, subres, &box, _mem->data, _rect.m_width*4, 0);
#endif // 0
}

View file

@ -1291,11 +1291,25 @@ namespace bgfx
case TextureCube:
{
D3DLOCKED_RECT rect;
DX_CHECK(m_textureCube->LockRect(D3DCUBEMAP_FACES(_side), _lod, &rect, NULL, 0) );
_pitch = rect.Pitch;
D3DLOCKED_RECT lockedRect;
if (NULL != _rect)
{
RECT rect;
rect.left = _rect->m_x;
rect.top = _rect->m_y;
rect.right = rect.left + _rect->m_width;
rect.bottom = rect.top + _rect->m_height;
DX_CHECK(m_textureCube->LockRect(D3DCUBEMAP_FACES(_side), _lod, &lockedRect, &rect, 0) );
}
else
{
DX_CHECK(m_textureCube->LockRect(D3DCUBEMAP_FACES(_side), _lod, &lockedRect, NULL, 0) );
}
_pitch = lockedRect.Pitch;
_slicePitch = 0;
return (uint8_t*)rect.pBits;
return (uint8_t*)lockedRect.pBits;
}
}
@ -1343,6 +1357,7 @@ namespace bgfx
if (parseDds(dds, _mem) )
{
m_format = dds.m_type;
const TextureFormatInfo& tfi = s_textureFormat[dds.m_type];
bool decompress = false;
@ -1448,6 +1463,7 @@ namespace bgfx
{
TextureCreate tc;
bx::read(&reader, tc);
m_format = (TextureFormat::Enum)tc.m_format;
if (tc.m_cubeMap)
{
@ -1507,9 +1523,9 @@ namespace bgfx
{
uint32_t pitch;
uint32_t slicePitch;
uint8_t* bits = lock(0, _mip, pitch, slicePitch, &_rect);
uint8_t* bits = lock(_side, _mip, pitch, slicePitch, &_rect);
uint32_t srcpitch = _rect.m_width;
uint32_t srcpitch = _rect.m_width*s_textureFormat[m_format].m_bpp/8;
uint32_t dstpitch = pitch;
for (uint32_t yy = 0, height = _rect.m_height; yy < height; ++yy)
{
@ -1518,7 +1534,7 @@ namespace bgfx
memcpy(dst, src, srcpitch);
}
unlock(0, _mip);
unlock(_side, _mip);
}
void Texture::commit(uint8_t _stage)

View file

@ -345,6 +345,7 @@ namespace bgfx
D3DTEXTUREADDRESS m_tau;
D3DTEXTUREADDRESS m_tav;
D3DTEXTUREADDRESS m_taw;
TextureFormat::Enum m_format;
Enum m_type;
bool m_srgb;
};