unsigned int GlslSource::Build(const char* defines[], int numDefines) { int vertexShader = compile(m_vertexSource, defines, numDefines, true); int fragmentShader = compile(m_fragmentSource, defines, numDefines, false); unsigned int program = glCreateProgram(); glAttachShader(program, vertexShader); glAttachShader(program, fragmentShader); glLinkProgram(program); int result; glGetProgramiv(program, GL_LINK_STATUS, &result); char buffer[256]; int len; glGetProgramInfoLog(program, 255, &len, buffer); buffer[255] = 0; if (result != GL_TRUE) { throw GraphicsException(std::string("Error while linking GLSL program: ") + buffer); } GLenum err = glGetError(); if (err != GL_NO_ERROR) throw GraphicsException("Error while loading GLSL effect"); return program; }
int GlslSource::compile(const char* source, const char* defines[], int numDefines, bool isVertexShader) { int shader; if (isVertexShader) { shader = glCreateShader(GL_VERTEX_SHADER); } else { shader = glCreateShader(GL_FRAGMENT_SHADER); } if (shader == 0) throw GraphicsException("Unable to create shader"); // setup the source int totalDefines = 0; m_defines[totalDefines++] = m_versionDefinition; m_defines[totalDefines++] = m_versionConstant; if (m_glslVersion == 100) m_defines[totalDefines++] ="#define HIGHP highp\n"; else m_defines[totalDefines++] = "#define HIGHP\n"; if (m_glslVersion < 130) { if (isVertexShader) { m_defines[totalDefines++] = "#define in attribute\n"; m_defines[totalDefines++] = "#define out varying\n"; } else { m_defines[totalDefines++] = "#define in varying\n"; } } for (int i = 0; i < numDefines; i++) m_defines[totalDefines++] = defines[i]; m_defines[totalDefines++] = source; glShaderSource(shader, totalDefines, m_defines, nullptr); glCompileShader(shader); int logLength; char logBuffer[256]; glGetShaderInfoLog(shader, 255, &logLength, logBuffer); logBuffer[255] = 0; int result; glGetShaderiv(shader, GL_COMPILE_STATUS, &result); if (result != GL_TRUE) throw GraphicsException(std::string("Unable to compile shader: ") + logBuffer); return shader; }
ShaderProgram::ShaderProgram() { this->_checkError("Errors before create shader program"); this->_shaderProgramID = glCreateProgram(); if (this->_shaderProgramID == 0) { throw GraphicsException("Failed to create shader program"); } else if (glIsProgram(this->_shaderProgramID) != GL_TRUE) { throw GraphicsException("Failed to create shader program, shader program is not a shader program"); } this->_checkError("Failed to create shader program"); }
GLuint ShaderProgram::_getShader(const char *shaderFilePath, GLenum shaderType) { std::string shaderNameString = Logger::toLoggable(shaderFilePath); Logger::log("Shader Manager", "Making shader " + shaderNameString); /* Read file */ Logger::log("Shader Manager", "Reading shader file"); std::ifstream shaderFile; shaderFile.open(shaderFilePath, std::ios_base::in); if (!shaderFile) { throw GraphicsException("Shader file not found"); } std::string line; std::string shaderData; while (std::getline(shaderFile, line)) { shaderData += line + NEWLINE; } shaderFile.close(); /* Create shader */ Logger::log("Shader Manager", "Compiling shader"); GLuint shaderID = glCreateShader(shaderType); if (shaderID == 0) { throw GraphicsException("Failed to create shader, id 0 returned"); } const char *shaderStr = shaderData.c_str(); glShaderSource(shaderID, 1, &shaderStr, nullptr); glCompileShader(shaderID); /* Check compile status */ GLint status; glGetShaderiv(shaderID, GL_COMPILE_STATUS, &status); if (status != GL_TRUE) { GLint logLength; glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &logLength); GLchar *infoLog = new GLchar[logLength + 1]; glGetShaderInfoLog(shaderID, logLength, nullptr, infoLog); throw GraphicsException("Failed to compile shader: " + Logger::toLoggable(infoLog)); } this->_checkError("Failed making shader program"); return shaderID; }
void* BufferBase::map() { void* ret = NULL; BufferConfig::BUFFER_USAGE usage = m_config->usage; if(usage == BufferConfig::BUFFER_CPU_WRITE || usage == BufferConfig::BUFFER_CPU_READ || usage == BufferConfig::BUFFER_CPU_WRITE_DISCARD) { D3D11_MAPPED_SUBRESOURCE MappedResource; UINT32 mapType = 0; if(usage == BufferConfig::BUFFER_CPU_READ){ mapType = D3D11_MAP_READ; } else if(usage == BufferConfig::BUFFER_CPU_WRITE){ mapType = D3D11_MAP_WRITE; } else if(usage == BufferConfig::BUFFER_CPU_WRITE_DISCARD){ mapType = D3D11_MAP_WRITE_DISCARD; } HRESULT hr = S_OK; if(FAILED(hr = m_deviceContext->Map( m_buffer, 0, (D3D11_MAP)mapType, 0, &MappedResource))) { throw GraphicsException(hr,__FILE__,__FUNCTION__,__LINE__); } else { ret = MappedResource.pData; } } return ret; }
void BufferD3D11::initBuffer(const void* data, uint32 size) { memset(&mBufferDesc, 0, sizeof(mBufferDesc)); switch (mBufferType) { case BufferType::Const: mBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; break; case BufferType::Index: mBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; break; case BufferType::Vertex: mBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; break; } mBufferDesc.ByteWidth = size; mBufferDesc.CPUAccessFlags = 0; mBufferDesc.MiscFlags = 0; mBufferDesc.StructureByteStride = 0; mBufferDesc.Usage = D3D11_USAGE_DEFAULT; auto devptr = mDevice.lock(); Device::GxDeviceD3D11Ptr dev = std::static_pointer_cast<Device::GxDeviceD3D11>(devptr); D3D11_SUBRESOURCE_DATA resData; resData.pSysMem = data; resData.SysMemPitch = size; resData.SysMemSlicePitch = 0; auto res = dev->getDevice()->CreateBuffer(&mBufferDesc, data != nullptr ? &resData : nullptr, mBuffer); if (FAILED(res)) { throw GraphicsException("Failed to create buffer"); } }
void GraphicsVk::AppendLayer(std::vector<char const *> &layers, std::vector<vk::LayerProperties> const &availableLayers, std::string const &layerName) { auto layer = GetLayer(availableLayers, layerName); if (!layer) throw GraphicsException("GraphicsVk::AppendLayer() failed to find layer " + layerName, VK_RESULT_MAX_ENUM); layers.push_back(layer->layerName); }
void SamplerStateD3D11::setAddressV(AddressMode mode) { switch (mode) { case AddressMode::Wrap: mDescription.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; break; case AddressMode::Border: mDescription.AddressV = D3D11_TEXTURE_ADDRESS_BORDER; break; case AddressMode::Clamp: mDescription.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; break; case AddressMode::Mirror: mDescription.AddressV = D3D11_TEXTURE_ADDRESS_MIRROR; break; default: throw std::invalid_argument("Invalid address mode"); } auto device = mDevice.lock(); auto dev11 = std::static_pointer_cast<Device::GxDeviceD3D11>(device); ID3D11SamplerState* state; auto res = dev11->getDevice()->CreateSamplerState(&mDescription, &state); if (FAILED(res)) { throw GraphicsException("Failed to create sampler state"); } mSamplerState = state; }
static GLenum GetDataType(VertexArrayObject::DataType type) { switch (type) { case VertexArrayObject::HalfFloat: return GL_HALF_FLOAT; case VertexArrayObject::Float: return GL_FLOAT; case VertexArrayObject::Double: return GL_DOUBLE; case VertexArrayObject::Fixed: return GL_FIXED; case VertexArrayObject::Byte: return GL_BYTE; case VertexArrayObject::UByte: return GL_UNSIGNED_BYTE; case VertexArrayObject::Short: return GL_SHORT; case VertexArrayObject::UShort: return GL_UNSIGNED_SHORT; case VertexArrayObject::Int: return GL_INT; case VertexArrayObject::UInt: return GL_UNSIGNED_INT; default: throw GraphicsException(GL_INVALID_ENUM, "Invalid VertexArrayObject Type"); } }
void GraphicsVk::AppendExtension(std::vector<char const *> &extensions, std::vector<vk::ExtensionProperties> const &availableExtensions, std::string const &extensionName) { auto ext = GetExtension(availableExtensions, extensionName); if (!ext) throw GraphicsException("GraphicsVk::AppendExtension() failed to find extension " + extensionName, VK_RESULT_MAX_ENUM); extensions.push_back(ext->extensionName); }
void SamplerStateD3D11::setFilter(FilterMode mode, float anisotropy) { switch (mode) { case FilterMode::Bilinear: mDescription.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT; break; case FilterMode::Trilinear: mDescription.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; break; case FilterMode::Anisotropic: mDescription.Filter = D3D11_FILTER_ANISOTROPIC; mDescription.MaxAnisotropy = (uint32) anisotropy; break; default: throw std::invalid_argument("Invalid texture filter"); } auto device = mDevice.lock(); auto dev11 = std::static_pointer_cast<Device::GxDeviceD3D11>(device); ID3D11SamplerState* state; auto res = dev11->getDevice()->CreateSamplerState(&mDescription, &state); if (FAILED(res)) { throw GraphicsException("Failed to create sampler state"); } mSamplerState = state; }
void ShaderProgram::_checkError(const char* strIfError) { GLenum error = glGetError(); if(error != GL_NO_ERROR) { throw GraphicsException(Logger::toLoggable(strIfError) + ". Error: " + Logger::toLoggable(error) + ": " + Logger::toLoggable(glewGetErrorString(error))); } }
void GraphicsDevice::setWindowMode( bool p_windowed ) { m_windowMode=p_windowed; HRESULT hr = S_OK; hr = m_swapChain->SetFullscreenState((BOOL)!p_windowed,nullptr); if( FAILED(hr)) throw GraphicsException(hr,__FILE__,__FUNCTION__,__LINE__); }
int ObjectRoster::IdGenerator::new_id(){ int id; if(m_unused.empty()){ id = m_next++; if(id > max_id) throw GraphicsException("ObjectRoster::IdGenerator new id above max"); } else{ id = m_unused.top(); m_unused.pop(); } return id; }
void GraphicsDevice::initHardware() { HRESULT hr = S_OK; UINT createDeviceFlags = 0; #ifdef _DEBUG createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_DRIVER_TYPE driverTypes[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_REFERENCE, }; UINT numDriverTypes = sizeof(driverTypes) / sizeof(driverTypes[0]); D3D_FEATURE_LEVEL featureLevelsToTry[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0 }; D3D_FEATURE_LEVEL initiatedFeatureLevel; int selectedDriverType = -1; for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ) { D3D_DRIVER_TYPE driverType; driverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDeviceAndSwapChain( NULL, driverType, NULL, createDeviceFlags, featureLevelsToTry, ARRAYSIZE(featureLevelsToTry), D3D11_SDK_VERSION, &m_swapChainDesc, &m_swapChain, &m_device, &initiatedFeatureLevel, &m_deviceContext); if (hr == S_OK) { selectedDriverType = driverTypeIndex; m_featureLevel = m_device->GetFeatureLevel(); SETDDEBUGNAME((m_device),("m_device")); break; } } if ( selectedDriverType > 0 ) throw GraphicsException("Couldn't create a D3D Hardware-device, software render enabled." ,__FILE__, __FUNCTION__, __LINE__); }
void Texture3D::LoadTexture(int width, int height, int depth, const char *data, Format format, int stride /*= -1*/) { GLint glFormat; GLint glInternalFormat; int elementSize = 0; switch (format) { case RGB: elementSize = 3; glFormat = GL_RGB; glInternalFormat = GL_RGB8; break; case RGBA: elementSize = 4; glFormat = GL_RGBA; glInternalFormat = GL_RGBA8; break; case Red: elementSize = 1; glFormat = GL_RED; glInternalFormat = GL_R8; break; case USHORT_5_5_5_1: elementSize = 2; glFormat = GL_UNSIGNED_SHORT_5_5_5_1; glInternalFormat = GL_RGBA8; break; case USHORT_1_5_5_5: elementSize = 2; glFormat = GL_UNSIGNED_SHORT_1_5_5_5_REV; glInternalFormat = GL_RGBA8; break; default: throw GraphicsException(GL_INVALID_ENUM, "Texture format not recognized"); break; } if (stride == -1) { stride = width * elementSize; } // Generate an texture GL_CHECKED(glGenTextures(1, &_id)); Bind(); GL_CHECKED(glPixelStorei(GL_UNPACK_ROW_LENGTH, stride)); //GL_CHECKED(glTexImage3D(_type, 0, glInternalFormat, width, height, depth, 0, glFormat, GL_UNSIGNED_BYTE, data)); GL_CHECKED(glTexStorage3D(_type, 1, glInternalFormat, width, height, depth)); if (data != nullptr) { GL_CHECKED(glTexSubImage3D(_type, 0, 0, 0, 0, width, height, depth, glFormat, GL_UNSIGNED_BYTE, data)); } GL_CHECKED(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)); UnBind(); }
void BufferD3D11::resize(uint32 numBytes) { if (mBuffer != nullptr) { if (numBytes < mBufferDesc.ByteWidth) { D3D11_BOX dstBox = { 0 }; dstBox.right = numBytes; dstBox.bottom = 1; dstBox.back = 1; mBufferDesc.ByteWidth = numBytes; ID3D11Buffer* tmp = nullptr; auto devptr = mDevice.lock(); Device::GxDeviceD3D11Ptr dev = std::static_pointer_cast<Device::GxDeviceD3D11>(devptr); auto res = dev->getDevice()->CreateBuffer(&mBufferDesc, nullptr, &tmp); if (FAILED(res)) { throw GraphicsException("Failed to create buffer"); } dev->getImmContext()->CopySubresourceRegion(tmp, 0, 0, 0, 0, mBuffer, 0, &dstBox); mBuffer = tmp; } else if (numBytes > mBufferDesc.ByteWidth) { mBufferDesc.ByteWidth = numBytes; ID3D11Buffer* tmp = nullptr; auto devptr = mDevice.lock(); Device::GxDeviceD3D11Ptr dev = std::static_pointer_cast<Device::GxDeviceD3D11>(devptr); auto res = dev->getDevice()->CreateBuffer(&mBufferDesc, nullptr, &tmp); if (FAILED(res)) { throw GraphicsException("Failed to create buffer"); } dev->getImmContext()->CopySubresourceRegion(tmp, 0, 0, 0, 0, mBuffer, 0, nullptr); mBuffer = tmp; } } else { initBuffer(nullptr, numBytes); } }
static GLenum GetUsage(BufferObject::Usage usage) { switch (usage) { case BufferObject::Usage::StreamDraw: return GL_STREAM_DRAW; case BufferObject::Usage::StreamRead: return GL_STREAM_READ; case BufferObject::Usage::StreamCopy: return GL_STREAM_COPY; case BufferObject::Usage::DynamicDraw: return GL_DYNAMIC_DRAW; case BufferObject::Usage::DynamicRead: return GL_DYNAMIC_READ; case BufferObject::Usage::DynamicCopy: return GL_DYNAMIC_COPY; case BufferObject::Usage::StaticDraw: return GL_STATIC_DRAW; case BufferObject::Usage::StaticRead: return GL_STATIC_READ; case BufferObject::Usage::StaticCopy: return GL_STATIC_COPY; default: throw GraphicsException(GL_INVALID_ENUM, "Invalid BufferObject usage"); } }
void BufferBase::init(void* p_initData ) { HRESULT hr = S_OK; if(p_initData){ D3D11_SUBRESOURCE_DATA data; data.pSysMem = p_initData; hr = m_device->CreateBuffer(m_config->getBufferDesc(), &data, &m_buffer); } else{ hr = m_device->CreateBuffer(m_config->getBufferDesc(), NULL, &m_buffer); } if(FAILED(hr)){ throw GraphicsException(hr,__FILE__,__FUNCTION__,__LINE__); } }
static GLenum GetBufferType(BufferObject::Type type) { switch (type) { case BufferObject::Type::PixelPack: return GL_PIXEL_PACK_BUFFER; case BufferObject::Type::PixelUnpack: return GL_PIXEL_UNPACK_BUFFER; case BufferObject::Type::Uniform: return GL_UNIFORM_BUFFER; case BufferObject::Type::Array: return GL_ARRAY_BUFFER; case BufferObject::Type::Texture: return GL_TEXTURE_BUFFER; case BufferObject::Type::DrawIndirect: return GL_DRAW_INDIRECT_BUFFER; case BufferObject::Type::DispatchIndirect: return GL_DISPATCH_INDIRECT_BUFFER; case BufferObject::Type::AtomicCounter: return GL_ATOMIC_COUNTER_BUFFER; case BufferObject::Type::ElementArray: return GL_ELEMENT_ARRAY_BUFFER; case BufferObject::Type::ShaderStorage: return GL_SHADER_STORAGE_BUFFER; case BufferObject::Type::TransfromFeedback: return GL_TRANSFORM_FEEDBACK_BUFFER; default: throw GraphicsException(GL_INVALID_ENUM, "Invalid BufferObject Type"); } }
void Texture3D::UpdateData(int x, int y, int z, int width, int height, int depth, const char *data, Format format, int stride /*= -1*/) { GLint glFormat; GLint glDataFormat; switch (format) { case RGB: glFormat = GL_RGB; glDataFormat = GL_UNSIGNED_BYTE; break; case RGBA: glFormat = GL_RGBA; glDataFormat = GL_UNSIGNED_BYTE; break; case Red: glFormat = GL_RED; glDataFormat = GL_UNSIGNED_BYTE; break; case USHORT_5_5_5_1: glFormat = GL_RGBA; glDataFormat = GL_UNSIGNED_SHORT_5_5_5_1; break; case USHORT_1_5_5_5: glFormat = GL_RGBA; glDataFormat = GL_UNSIGNED_SHORT_1_5_5_5_REV; break; default: throw GraphicsException(GL_INVALID_ENUM, "Texture format not recognized"); break; } if (stride == -1) { stride = width; } Bind(); GL_CHECKED(glPixelStorei(GL_UNPACK_ROW_LENGTH, stride)); GL_CHECKED(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); GL_CHECKED(glTexSubImage3D(_type, 0, x, y, z, width, height, depth, glFormat, glDataFormat, data)); GL_CHECKED(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)); UnBind(); }
void GraphicsDevice::updateResolution( int p_width, int p_height ) { m_width = p_width; m_height = p_height; setRenderTarget(RenderTargetSpec::RT_NONE); releaseBackBuffer(); releaseGBufferAndDepthStencil(); HRESULT hr; // Resize the swap chain // !HACK! !IMPORTANT! m_deviceContext->ClearState(); // MUST DO PROPER HANDLING OF BUFFER DEALLOCATION AND THEN REALLOCATION HERE!! *****TEDIOUS!!!***** // NOW WE GET THE D3D LIVE LEAKS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // http://msdn.microsoft.com/en-us/library/windows/desktop/bb174577(v=vs.85).aspx hr = m_swapChain->ResizeBuffers(0, p_width, p_height, DXGI_FORMAT_R8G8B8A8_UNORM, 0); if(FAILED(hr)) throw GraphicsException(hr,__FILE__,__FUNCTION__,__LINE__); initBackBuffer(); fitViewport(); initGBufferAndDepthStencil(); }
void SamplerStateD3D11::createDefault() { auto device = mDevice.lock(); auto dev11 = std::static_pointer_cast<Device::GxDeviceD3D11>(device); memset(&mDescription, 0, sizeof(mDescription)); mDescription.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; mDescription.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; mDescription.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; mDescription.BorderColor[0] = mDescription.BorderColor[1] = mDescription.BorderColor[2] = mDescription.BorderColor[3] = 0.0f; mDescription.ComparisonFunc = D3D11_COMPARISON_ALWAYS; mDescription.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; mDescription.MaxAnisotropy = 1; mDescription.MaxLOD = D3D11_FLOAT32_MAX; mDescription.MinLOD = 0; mDescription.MipLODBias = 0.0f; auto res = dev11->getDevice()->CreateSamplerState(&mDescription, mSamplerState); if (FAILED(res)) { throw GraphicsException("Failed to create sampler state"); } }
BufferConfig::BufferConfig(BUFFER_INIT_DESC& p_initDesc) { usage = p_initDesc.Usage; elementSize = p_initDesc.ElementSize; elementCount = p_initDesc.NumElements; arraySize = p_initDesc.arraySize; switch (p_initDesc.Slot) { case PERFRAME: case SLOT0: slot = 0; break; case PEROBJECT: case SLOT1: slot = 1; break; default: break; } type = p_initDesc.Type; switch(type) { case VERTEX_BUFFER: { m_bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; if(p_initDesc.Usage == BUFFER_STREAM_OUT_TARGET) m_bufferDesc.BindFlags |= D3D11_BIND_STREAM_OUTPUT; } break; case INDEX_BUFFER: { m_bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; } break; case CONSTANT_BUFFER_VS: case CONSTANT_BUFFER_GS: case CONSTANT_BUFFER_PS: case CONSTANT_BUFFER_VS_PS: case CONSTANT_BUFFER_VS_GS: case CONSTANT_BUFFER_VS_GS_PS: case CONSTANT_BUFFER_GS_PS: case CONSTANT_BUFFER_ALL: { m_bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; } break; default: throw GraphicsException("Unknown buffer type.",__FILE__,__FUNCTION__,__LINE__); break; }; m_bufferDesc.CPUAccessFlags = 0; m_bufferDesc.Usage = D3D11_USAGE_DEFAULT; if(usage == BUFFER_CPU_READ) { m_bufferDesc.Usage = D3D11_USAGE_DYNAMIC; m_bufferDesc.CPUAccessFlags |= D3D11_CPU_ACCESS_READ; } else if(usage == BUFFER_CPU_WRITE) { m_bufferDesc.Usage = D3D11_USAGE_DYNAMIC; m_bufferDesc.CPUAccessFlags |= D3D11_CPU_ACCESS_WRITE; } else if(usage == BUFFER_CPU_WRITE_DISCARD) { m_bufferDesc.Usage = D3D11_USAGE_DYNAMIC; m_bufferDesc.CPUAccessFlags |= D3D11_CPU_ACCESS_WRITE; } //Desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; m_bufferDesc.MiscFlags = 0; m_bufferDesc.ByteWidth = p_initDesc.NumElements * p_initDesc.ElementSize; //set at least 16 bytes if(m_bufferDesc.ByteWidth < 16) m_bufferDesc.ByteWidth = 16; }
int ObjectRoster::id_of_color(uint8_t r, uint8_t g, uint8_t b){ int id = (r << 16) + (g << 8) + b; if(id > max_id) throw GraphicsException("ObjectRoster::Id above max"); return id; }