int compileHLSLToD3D9(const char* from, const char* to, const std::map<std::string, int>& attributes) { LPD3DXBUFFER errors; LPD3DXBUFFER shader; LPD3DXCONSTANTTABLE table; HRESULT hr = D3DXCompileShaderFromFileA(from, nullptr, nullptr, "main", isVertexShader(from) ? "vs_2_0" : "ps_2_0", 0, &shader, &errors, &table); if (FAILED(hr)) hr = D3DXCompileShaderFromFileA(from, nullptr, nullptr, "main", isVertexShader(from) ? "vs_3_0" : "ps_3_0", 0, &shader, &errors, &table); if (errors != nullptr) std::cerr << (char*)errors->GetBufferPointer(); if (!FAILED(hr)) { std::ofstream file(to, std::ios_base::binary); file.put(attributes.size()); for (std::map<std::string, int>::const_iterator attribute = attributes.begin(); attribute != attributes.end(); ++attribute) { file << attribute->first.c_str(); file.put(0); file.put(attribute->second); } D3DXCONSTANTTABLE_DESC desc; table->GetDesc(&desc); file.put(desc.Constants); for (UINT i = 0; i < desc.Constants; ++i) { D3DXHANDLE handle = table->GetConstant(nullptr, i); D3DXCONSTANT_DESC descriptions[10]; UINT count = 10; table->GetConstantDesc(handle, descriptions, &count); if (count > 1) std::cerr << "Error: Number of descriptors for one constant is greater than one." << std::endl; for (UINT i2 = 0; i2 < count; ++i2) { char regtype; switch (descriptions[i2].RegisterSet) { case D3DXRS_BOOL: regtype = 'b'; break; case D3DXRS_INT4: regtype = 'i'; break; case D3DXRS_FLOAT4: regtype = 'f'; break; case D3DXRS_SAMPLER: regtype = 's'; break; } //std::cout << descriptions[i2].Name << " " << regtype << descriptions[i2].RegisterIndex << " " << descriptions[i2].RegisterCount << std::endl; file << descriptions[i2].Name; file.put(0); file.put(regtype); file.put(descriptions[i2].RegisterIndex); file.put(descriptions[i2].RegisterCount); } } DWORD* data = (DWORD*)shader->GetBufferPointer(); for (unsigned i = 0; i < shader->GetBufferSize() / 4; ++i) { if ((data[i] & 0xffff) == 0xfffe) { //comment token unsigned size = (data[i] >> 16) & 0xffff; i += size; } else file.write((char*)&data[i], 4);
int static l_graphics_newShader(lua_State* state) { char const* vertexSrc = l_tools_toStringOrError(state, 1); char const* fragmentSrc = NULL; char * loadedFile1 = NULL; char * loadedFile2 = NULL; if(lua_isstring(state, 2)) { fragmentSrc = lua_tostring(state, 2); if(!isVertexShader(vertexSrc)) { // TODO int loadedFile1Size = filesystem_read(vertexSrc, &loadedFile1); (void) loadedFile1Size; if(!loadedFile1 || !isVertexShader(loadedFile1)) { free(loadedFile1); lua_pushstring(state, "input 1 is not a valid vertex shader"); return lua_error(state); } vertexSrc = loadedFile1; } if(!isSingleFragmentShader(fragmentSrc)) { // TODO int loadedFile2Size = filesystem_read(fragmentSrc, &loadedFile2); (void)loadedFile2Size; if(!loadedFile2 || !isSingleFragmentShader(loadedFile2)) { free(loadedFile1); free(loadedFile2); lua_pushstring(state, "input 2 is not a valid fragment shader"); return lua_error(state); } fragmentSrc = loadedFile2; } } else { if(isVertexShader(vertexSrc)) { // nothing required } else if(isSingleFragmentShader(vertexSrc)) { fragmentSrc = vertexSrc; vertexSrc = NULL; } else { // TODO int loadedFile1Size = filesystem_read(vertexSrc, &loadedFile1); (void) loadedFile1Size; if(!loadedFile1) { lua_pushstring(state, "could not open file"); return lua_error(state); } if(isSingleFragmentShader(loadedFile1)) { fragmentSrc = loadedFile1; vertexSrc = NULL; } else if(isVertexShader(loadedFile1)) { vertexSrc = loadedFile1; fragmentSrc = NULL; } else { free(loadedFile1); lua_pushstring(state, "input is not a valid shader"); return lua_error(state); } } } l_graphics_Shader * shader = lua_newuserdata(state, sizeof(l_graphics_Shader)); graphics_ShaderCompileStatus status = graphics_Shader_new(&shader->shader, vertexSrc, fragmentSrc); if(status != graphics_ShaderCompileStatus_okay) { pushShaderInfoLog(state, &shader->shader); return lua_error(state); } lua_rawgeti(state, LUA_REGISTRYINDEX, moduleData.shaderMT); lua_setmetatable(state, -2); free(loadedFile1); free(loadedFile2); int const textureUnits = shader->shader.textureUnitCount; shader->referencedTextures = malloc(textureUnits * sizeof(int)); for(int i = 0; i < textureUnits; ++i) { shader->referencedTextures[i] = LUA_NOREF; } return 1; }