void CShader::Compile() { CompileShader(); CheckErrors(); }
bool glsl_recompile(GLSLProgram *program) { struct stat vs, fs; if (0 == stat(program->vshader_filename, &vs)) program->vshader_mtime = vs.st_mtime; else program->vshader_mtime = 0; if (0 == stat(program->fshader_filename, &fs)) program->fshader_mtime = fs.st_mtime; else program->fshader_mtime = 0; char *vsh_src = 0, *fsh_src = 0; if (!program->vshader_source) { size_t sz; vsh_src = (char *)VFSReadFile(program->vshader_filename, &sz); if (!vsh_src) { ELOG("File missing: %s", program->vshader_filename); return false; } } if (!program->fshader_source) { size_t sz; fsh_src = (char *)VFSReadFile(program->fshader_filename, &sz); if (!fsh_src) { ELOG("File missing: %s", program->fshader_filename); delete [] vsh_src; return false; } } GLuint vsh = glCreateShader(GL_VERTEX_SHADER); const GLchar *vsh_str = program->vshader_source ? program->vshader_source : (const GLchar *)(vsh_src); if (!CompileShader(vsh_str, vsh, program->vshader_filename)) { return false; } delete [] vsh_src; const GLchar *fsh_str = program->fshader_source ? program->fshader_source : (const GLchar *)(fsh_src); GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER); if (!CompileShader(fsh_str, fsh, program->fshader_filename)) { glDeleteShader(vsh); return false; } delete [] fsh_src; GLuint prog = glCreateProgram(); glAttachShader(prog, vsh); glAttachShader(prog, fsh); glLinkProgram(prog); GLint linkStatus; glGetProgramiv(prog, GL_LINK_STATUS, &linkStatus); if (linkStatus != GL_TRUE) { GLint bufLength = 0; glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &bufLength); if (bufLength) { char* buf = new char[bufLength]; glGetProgramInfoLog(prog, bufLength, NULL, buf); FLOG("Could not link program:\n %s", buf); delete [] buf; // we're dead! } else { FLOG("Could not link program."); } glDeleteShader(vsh); glDeleteShader(fsh); return false; } // Destroy the old program, if any. if (program->program_) { glDeleteProgram(program->program_); } program->program_ = prog; program->vsh_ = vsh; program->fsh_ = vsh; program->sampler0 = glGetUniformLocation(program->program_, "sampler0"); program->sampler1 = glGetUniformLocation(program->program_, "sampler1"); program->a_position = glGetAttribLocation(program->program_, "a_position"); program->a_color = glGetAttribLocation(program->program_, "a_color"); program->a_normal = glGetAttribLocation(program->program_, "a_normal"); program->a_texcoord0 = glGetAttribLocation(program->program_, "a_texcoord0"); program->a_texcoord1 = glGetAttribLocation(program->program_, "a_texcoord1"); program->u_worldviewproj = glGetUniformLocation(program->program_, "u_worldviewproj"); program->u_world = glGetUniformLocation(program->program_, "u_world"); program->u_viewproj = glGetUniformLocation(program->program_, "u_viewproj"); program->u_fog = glGetUniformLocation(program->program_, "u_fog"); program->u_sundir = glGetUniformLocation(program->program_, "u_sundir"); program->u_camerapos = glGetUniformLocation(program->program_, "u_camerapos"); //ILOG("Shader compilation success: %s %s", // program->vshader_filename, // program->fshader_filename); return true; }
bool ShapesDemo::LoadContent(){ ID3DBlob* vsBuffer = 0; bool compileResult = CompileShader(L"SolidColor.fx", "VS_Main", "vs_4_0", &vsBuffer); if(!compileResult){ MessageBox(0, L"Error loading vertex shader!", L"Compile Error", MB_OK); return false; } HRESULT result; result = mDevice->CreateVertexShader(vsBuffer->GetBufferPointer(), vsBuffer->GetBufferSize(), 0, &mSolidColorVS); if(FAILED(result)){ if(vsBuffer) vsBuffer->Release(); return false; } D3D11_INPUT_ELEMENT_DESC scLayout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 } }; unsigned int nLayoutElements = ARRAYSIZE(scLayout); result = mDevice->CreateInputLayout(scLayout, nLayoutElements, vsBuffer->GetBufferPointer(), vsBuffer->GetBufferSize(),&mInputLayout); vsBuffer->Release(); if(FAILED(result)){ return false; } ID3DBlob* psBuffer = 0; compileResult = CompileShader( L"SolidColor.fx", "PS_Main", "ps_4_0", &psBuffer ); if( compileResult == false ) { MessageBox( 0, L"Error loading pixel shader!", L"Compile Error", MB_OK ); return false; } result = mDevice->CreatePixelShader( psBuffer->GetBufferPointer( ), psBuffer->GetBufferSize( ), 0, &mSolidColorPS); psBuffer->Release( ); if(FAILED( result ) ) { return false; } VertexPos vertices[] = { XMFLOAT3( 0.5f, 0.5f, 0.5f ), XMFLOAT3( 0.5f, -0.5f, 0.5f ), XMFLOAT3( -0.5f, -0.5f, 0.5f ) }; D3D11_BUFFER_DESC vertexDesc; ZeroMemory(&vertexDesc, sizeof(vertexDesc)); vertexDesc.Usage = D3D11_USAGE_DEFAULT; vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; vertexDesc.ByteWidth = sizeof(VertexPos) * ARRAYSIZE(vertices); D3D11_SUBRESOURCE_DATA resourceData; ZeroMemory(&resourceData, sizeof(resourceData)); resourceData.pSysMem = vertices; result = mDevice->CreateBuffer(&vertexDesc, &resourceData, &mVertexBuffer); return true; }
bool ShaderProgram::Construct(const std::string& vertex_shader_path, const std::string& fragment_shader_path) { // LOGI("shader program construct vs: %s, fs: %s", vertex_shader_path.c_str(), fragment_shader_path.c_str()); GLuint vertex_shader; std::string shader_code; if (!GetFileContentString(std::string(GetResourcePath()) + "/" + vertex_shader_path, shader_code)) { LOGW("Failed to load vertex shader: %s", vertex_shader_path.c_str()); return false; } if (!CompileShader(&vertex_shader, GL_VERTEX_SHADER, shader_code.c_str())) { LOGW("Failed to compile vertex shader: %s", vertex_shader_path.c_str()); return false; } GLuint fragment_shader; if (!GetFileContentString(std::string(GetResourcePath()) + "/" + fragment_shader_path, shader_code)) { LOGW("Failed to load fragment shader: %s", fragment_shader_path.c_str()); return false; } if (!CompileShader(&fragment_shader, GL_FRAGMENT_SHADER, shader_code.c_str())) { LOGW("Failed to compile fragment shader: %s", fragment_shader_path.c_str()); glDeleteShader(vertex_shader); return false; } ASSERT(program_ == 0); // create shader program program_ = glCreateProgram(); // attach vertex shader to program glAttachShader(program_, vertex_shader); // attach fragment shader to program glAttachShader(program_, fragment_shader); // bind attribute locations // this needs to be done prior to linking glBindAttribLocation(program_, ATTRIB_VERTEX, "a_position"); glBindAttribLocation(program_, ATTRIB_NORMAL, "a_normal"); glBindAttribLocation(program_, ATTRIB_COLOR, "a_color"); glBindAttribLocation(program_, ATTRIB_TEXCOORD0, "a_texcoord0"); glBindAttribLocation(program_, ATTRIB_TEXCOORD1, "a_texcoord1"); // link program if (!LinkProgram(program_)) { LOGW("Failed to link program: %d", program_); glDeleteShader(vertex_shader); glDeleteShader(fragment_shader); glDeleteProgram(program_); program_ = 0; return false; } // get uniform locations uniforms_[UNIFORM_MODEL_VIEW_PROJ_MATRIX] = glGetUniformLocation(program_, "model_view_proj_matrix"); uniforms_[UNIFORM_MODEL_VIEW_MATRIX] = glGetUniformLocation(program_, "model_view_matrix"); uniforms_[UNIFORM_TEX_USE_COORD_INDEX] = glGetUniformLocation(program_, "tex_use_coord_idx"); uniforms_[UNIFORM_TEX0] = glGetUniformLocation(program_, "tex[0]"); uniforms_[UNIFORM_TEX1] = glGetUniformLocation(program_, "tex[1]"); uniforms_[UNIFORM_TEX_MATRIX_ENABLE] = glGetUniformLocation(program_, "tex_matrix_enable"); uniforms_[UNIFORM_TEX_MATRIX0] = glGetUniformLocation(program_, "tex_matrix[0]"); uniforms_[UNIFORM_TEX_MATRIX1] = glGetUniformLocation(program_, "tex_matrix[1]"); uniforms_[UNIFORM_FOG_ENABLE] = glGetUniformLocation(program_, "fog_enable"); uniforms_[UNIFORM_FOG_MODE] = glGetUniformLocation(program_, "fog_mode"); uniforms_[UNIFORM_FOG_START] = glGetUniformLocation(program_, "fog_start"); uniforms_[UNIFORM_FOG_END] = glGetUniformLocation(program_, "fog_end"); uniforms_[UNIFORM_FOG_DENSITY] = glGetUniformLocation(program_, "fog_density"); uniforms_[UNIFORM_FOG_COLOR] = glGetUniformLocation(program_, "fog_color"); // release vertex and fragment shaders if (vertex_shader) glDeleteShader(vertex_shader); if (fragment_shader) glDeleteShader(fragment_shader); // int n; // glGetProgramiv(program_, GL_ACTIVE_UNIFORMS, &n); // LOGI("GL_ACTIVE_UNIFORMS: %d", n); // glGetProgramiv(program_, GL_ACTIVE_ATTRIBUTES, &n); // LOGI("GL_ACTIVE_ATTRIBUTES: %d", n); return true; }
void Shader::CreateShaderFromFile(std::string const & fileName) { LoadShaderSource(fileName); m_shader = CreateShader(); CompileShader(); }
bool Initialize(VinoMemory* Mem) { // Init values { float OrthoMtx[4][4] = { { 2.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, -2.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, -1.0f, 0.0f }, { -1.0f, 1.0f, 0.0f, 1.0f }, }; memcpy(Mem->Window.ProjMtx, OrthoMtx, sizeof(OrthoMtx)); } #if 0 // Initialize mpg123 { if (Mem->Audio.Mpg_Init() != MPG123_OK) { // TODO: Log error return false; } int Error; Mem->Audio.MpgHandle = Mem->Audio.Mpg_New(0, &Error); if (Error) { // TODO: Log error return false; } Error = Mem->Audio.Mpg_Open(Mem->Audio.MpgHandle, "C:\\Users\\Apoorva\\Music\\foo.mp3"); if (Error) { return false; } Error = Mem->Audio.Mpg_GetFormat(Mem->Audio.MpgHandle, (long*)&Mem->Audio.Rate, &Mem->Audio.Channels, &Mem->Audio.Encoding); if (Error) { return false; } } // Initialize PortAudio { PaError Error = Pa_Initialize(); if (Error != paNoError) { // TODO: Log: Audio init failure return false; } PaStream* Stream; Error = Pa_OpenDefaultStream( &Stream, 0, Mem->Audio.Channels, paInt16, Mem->Audio.Rate, 0, AudioReadCallback, Mem); Error = Pa_SetStreamFinishedCallback(Stream, &AudioFinishedCallback); if (Error != paNoError) { return false; } Error = Pa_StartStream(Stream); if (Error != paNoError) { return false; } //Error = Pa_StopStream(Stream); //if (Error != paNoError) { return false; } //Error = Pa_CloseStream(Stream); //if (Error != paNoError) { return false; } //Pa_Terminate(); } #endif const char* Vert; // Vertex shader { Vert = " #version 330 \n" " uniform mat4 ProjMtx; \n" // Uniforms[0] " \n" " in vec2 Position; \n" // Attributes[0] " in vec2 UV; \n" // Attributes[1] " in vec4 Color; \n" // Attributes[2] " \n" " out vec2 Frag_UV; \n" " out vec4 Frag_Color; \n" " void main() \n" " { \n" " Frag_UV = UV; \n" " Frag_Color = Color; \n" " gl_Position = ProjMtx * vec4(Position.xy,0,1); \n" " } \n"; } // Default shader { const char* Frag = " #version 330 \n" " uniform sampler2D Texture; \n" // Uniforms[1] " \n" " in vec2 Frag_UV; \n" " in vec4 Frag_Color; \n" " \n" " out vec4 Out_Color; \n" " void main() \n" " { \n" " Out_Color = Frag_Color * texture( Texture, Frag_UV.st); \n" " } \n"; CompileShader(Mem->Shaders[VinoShader_Default], Vert, Frag, 3, 2, "Position", "UV", "Color", "ProjMtx", "Texture"); } // Setup for ImGui { glGenBuffers(1, &Mem->Meshes[VinoMesh_ImGui].VboHandle); glGenBuffers(1, &Mem->Meshes[VinoMesh_ImGui].ElementsHandle); glGenVertexArrays (1, &Mem->Meshes[VinoMesh_ImGui].VaoHandle); glBindVertexArray (Mem->Meshes[VinoMesh_ImGui].VaoHandle); glBindBuffer (GL_ARRAY_BUFFER, Mem->Meshes[VinoMesh_ImGui].VboHandle); glEnableVertexAttribArray(Mem->Shaders[VinoShader_Default].Attributes[0]); glEnableVertexAttribArray(Mem->Shaders[VinoShader_Default].Attributes[1]); glEnableVertexAttribArray(Mem->Shaders[VinoShader_Default].Attributes[2]); #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) glVertexAttribPointer(Mem->Shaders[VinoShader_Default].Attributes[0], 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); glVertexAttribPointer(Mem->Shaders[VinoShader_Default].Attributes[1], 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); glVertexAttribPointer(Mem->Shaders[VinoShader_Default].Attributes[2], 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); #undef OFFSETOF glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); // Create fonts texture ImGuiIO& io = ImGui::GetIO(); unsigned char* pixels; int width, height; //ImFont* my_font0 = io.Fonts->AddFontFromFileTTF("d:\\DroidSans.ttf", 15.0f); io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); glGenTextures (1, &Mem->Textures[VinoTex_Font]); glBindTexture (GL_TEXTURE_2D, Mem->Textures[VinoTex_Font]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); // Store our identifier io.Fonts->TexID = (void *)(intptr_t)Mem->Textures[VinoTex_Font]; // Cleanup io.Fonts->ClearInputData(); io.Fonts->ClearTexData(); } // Load interface textures and colors { // Texture IDs Mem->Textures[VinoTex_TitleBarButtons] = LoadAndBindImage("../../img/win32_titlebar_buttons.png"); Mem->Textures[VinoTex_TitleBarIcon] = LoadAndBindImage("../../img/win32_titlebar_icon.png"); Mem->Textures[VinoTex_InterfaceIcons] = LoadAndBindImage("../../img/interface_icons.png"); // Colors #if 1 Mem->Colors[VinoCol_Clear] = Color(45,45,48); // Dark grey #else Mem->Colors[VinoCol_Clear] = Color(114,144,154); // Light blue #endif Mem->Colors[VinoCol_Transparent] = Color(0,0,0,0); Mem->Colors[VinoCol_Button] = Color(92,92,94); Mem->Colors[VinoCol_ButtonHover] = Color(64,64,64); Mem->Colors[VinoCol_ButtonActive] = Color(0,122,204); } // ImGui Style Settings { ImGuiStyle& Style = ImGui::GetStyle(); Style.WindowFillAlphaDefault = 1.0f; // TODO: Move repeated stuff here by setting global style } return true; }
HRESULT S3UTVertexShader::CreateFromFile(ID3D10Device* pd3dDevice, LPCWSTR pSrcFile, CONST D3D10_SHADER_MACRO* pDefines, LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2) { HRESULT hr; S3UTVertexShader::CustomIncludeInterface includeInterface; // Inherited compile and reflect V(CompileShader(pd3dDevice,pSrcFile,pDefines,pFunctionName,pProfile,Flags1,Flags2)); V(pd3dDevice->CreateVertexShader(m_pShaderByteCode->GetBufferPointer(),m_pShaderByteCode->GetBufferSize(),&m_pVS)); D3D10_SHADER_DESC sdesc; m_pReflectedShader->GetDesc(&sdesc); // InputLayout // Count real elements, so we don't allocate space for a system value m_NumIEDElements = 0; for(int iInputParam=0;iInputParam<(int)sdesc.InputParameters;iInputParam++) { D3D10_SIGNATURE_PARAMETER_DESC pdesc; m_pReflectedShader->GetInputParameterDesc(iInputParam,&pdesc); if(pdesc.SystemValueType == D3D10_NAME_UNDEFINED && pdesc.ComponentType == D3D10_REGISTER_COMPONENT_FLOAT32) m_NumIEDElements++; } m_pIEDLayout = new D3D10_INPUT_ELEMENT_DESC[m_NumIEDElements]; // Parse Vertex Shader and generate the Input layout int ByteOffset = 0; int iLayoutSlot = 0; for(int iInputParam=0;iInputParam<(int)sdesc.InputParameters;iInputParam++) { D3D10_SIGNATURE_PARAMETER_DESC pdesc; m_pReflectedShader->GetInputParameterDesc(iInputParam,&pdesc); if(pdesc.SystemValueType == D3D10_NAME_UNDEFINED && pdesc.ComponentType == D3D10_REGISTER_COMPONENT_FLOAT32) { m_pIEDLayout[iLayoutSlot].SemanticName = pdesc.SemanticName; m_pIEDLayout[iLayoutSlot].SemanticIndex = pdesc.SemanticIndex; m_pIEDLayout[iLayoutSlot].AlignedByteOffset = ByteOffset; // $ Keep this before incrementing ByteOffset!!! const unsigned char parity_array[16] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; switch(parity_array[pdesc.Mask]) { default: case 0: assert(0); case 1: m_pIEDLayout[iLayoutSlot].Format = DXGI_FORMAT_R32_FLOAT; ByteOffset += 4; break; case 2: m_pIEDLayout[iLayoutSlot].Format = DXGI_FORMAT_R32G32_FLOAT; ByteOffset += 8; break; case 3: m_pIEDLayout[iLayoutSlot].Format = DXGI_FORMAT_R32G32B32_FLOAT; ByteOffset += 12; break; case 4: m_pIEDLayout[iLayoutSlot].Format = DXGI_FORMAT_R32G32B32A32_FLOAT; ByteOffset += 16; break; } m_pIEDLayout[iLayoutSlot].InputSlot = 0; m_pIEDLayout[iLayoutSlot].InstanceDataStepRate = 0; m_pIEDLayout[iLayoutSlot].InputSlotClass = D3D10_INPUT_PER_VERTEX_DATA; iLayoutSlot++; } } V(pd3dDevice->CreateInputLayout(m_pIEDLayout,m_NumIEDElements,m_pShaderByteCode->GetBufferPointer(),m_pShaderByteCode->GetBufferSize(),&m_pInputLayout)); m_VertexSize = ByteOffset; #ifndef _DEBUG // Not in DEBUG then release the Blobs SAFE_RELEASE(m_pCompileErrors); SAFE_RELEASE(m_pShaderByteCode); #endif return hr; }
/// This function loads a vertex and fragment shader file void GLSLShader::InitShaders() { // Make sure the user passed in at least a vertex and fragment shader file if(!GetVertexShaderFileName().length() || !GetFragmentShaderFileName().length()) { std::cerr << "GLSLShader requires setting a VertexShader and a FragmentShader" << std::endl; return; } // If any of our shader pointers are set, let's free them first. if(!m_hShaders.empty() || m_hProgramObject) Release(); bool ready = true; // Now we load and compile the shaders from their respective files for (std::map<GLint,std::string>::const_iterator it = m_hFileNames.begin(), itend = m_hFileNames.end(); it != itend; ++it) { ready &= CompileShader( it->first, it->second, header ); } if (!ready) { std::cerr << "SHADER compilation failed.\n"; return; } // Next we create a program object to represent our shaders m_hProgramObject = glCreateProgramObjectARB(); // We attach each shader we just loaded to our program object for (std::map<GLint,GLhandleARB>::const_iterator it = m_hShaders.begin(), itend = m_hShaders.end(); it != itend; ++it) { glAttachObjectARB(m_hProgramObject, it->second); } #if defined(GL_EXT_geometry_shader4) && defined(SOFA_HAVE_GLEW) if (GetGeometryShaderID()) { if (geometry_input_type != -1) glProgramParameteriEXT(m_hProgramObject, GL_GEOMETRY_INPUT_TYPE_EXT, geometry_input_type ); if (geometry_output_type != -1) glProgramParameteriEXT(m_hProgramObject, GL_GEOMETRY_OUTPUT_TYPE_EXT, geometry_output_type ); if (geometry_vertices_out != -1) glProgramParameteriEXT(m_hProgramObject, GL_GEOMETRY_VERTICES_OUT_EXT, geometry_vertices_out ); } #endif // Our last init function is to link our program object with OpenGL glLinkProgramARB(m_hProgramObject); GLint linked = 0, length = 0, laux = 0; glGetObjectParameterivARB(m_hProgramObject, GL_OBJECT_LINK_STATUS_ARB, &linked); if (!linked) std::cerr << "ERROR: Link of program shader failed:\n"<<std::endl; // else std::cout << "Link of program shader OK" << std::endl; glGetObjectParameterivARB(m_hProgramObject, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length); if (length > 1) { GLcharARB *logString = (GLcharARB *)malloc((length+1) * sizeof(GLcharARB)); glGetInfoLogARB(m_hProgramObject, length, &laux, logString); std::cerr << logString << std::endl; free(logString); for (std::map<GLint,std::string>::const_iterator it = m_hFileNames.begin(), itend = m_hFileNames.end(); it != itend; ++it) std::cerr << GetShaderStageName(it->first) << " shader file: " << it->second << std::endl; } // Now, let's turn off the shader initially. glUseProgramObjectARB(0); }
void GrGLProgram::genProgram(GrGLProgram::CachedData* programData, const GrDrawTarget* target) const { ShaderCodeSegments segments; const uint32_t& layout = fProgramDesc.fVertexLayout; memset(&programData->fUniLocations, 0, sizeof(UniLocations)); bool haveColor = !(ProgramDesc::kVertexColorAllOnes_OptFlagBit & fProgramDesc.fOptFlags); #if ATTRIBUTE_MATRIX segments.fVSAttrs = "attribute mat3 " VIEW_MATRIX_NAME ";\n"; #else segments.fVSUnis = "uniform mat3 " VIEW_MATRIX_NAME ";\n"; segments.fVSAttrs = ""; #endif segments.fVSAttrs += "attribute vec2 " POS_ATTR_NAME ";\n"; if (haveColor) { segments.fVSAttrs += "attribute vec4 " COL_ATTR_NAME ";\n"; segments.fVaryings = "varying vec4 vColor;\n"; } else { segments.fVaryings = ""; } segments.fVSCode = "void main() {\n" "\tvec3 pos3 = " VIEW_MATRIX_NAME " * vec3(" POS_ATTR_NAME ", 1);\n" "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n"; if (haveColor) { segments.fVSCode += "\tvColor = " COL_ATTR_NAME ";\n"; } if (!(fProgramDesc.fOptFlags & ProgramDesc::kNotPoints_OptFlagBit)) { segments.fVSCode += "\tgl_PointSize = 1.0;\n"; } segments.fFSCode = "void main() {\n"; // add texture coordinates that are used to the list of vertex attr decls GrTokenString texCoordAttrs[GrDrawTarget::kMaxTexCoords]; for (int t = 0; t < GrDrawTarget::kMaxTexCoords; ++t) { if (target->VertexUsesTexCoordIdx(t, layout)) { tex_attr_name(t, texCoordAttrs + t); segments.fVSAttrs += "attribute vec2 "; segments.fVSAttrs += texCoordAttrs[t]; segments.fVSAttrs += ";\n"; } } // for each enabled stage figure out what the input coordinates are // and count the number of stages in use. const char* stageInCoords[GrDrawTarget::kNumStages]; int numActiveStages = 0; for (int s = 0; s < GrDrawTarget::kNumStages; ++s) { if (fProgramDesc.fStages[s].fEnabled) { if (GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s) & layout) { stageInCoords[s] = POS_ATTR_NAME; } else { int tcIdx = GrDrawTarget::VertexTexCoordsForStage(s, layout); // we better have input tex coordinates if stage is enabled. GrAssert(tcIdx >= 0); GrAssert(texCoordAttrs[tcIdx].length()); stageInCoords[s] = texCoordAttrs[tcIdx].cstr(); } ++numActiveStages; } } GrTokenString inColor = "vColor"; // if we have active stages string them together, feeding the output color // of each to the next and generating code for each stage. if (numActiveStages) { int currActiveStage = 0; for (int s = 0; s < GrDrawTarget::kNumStages; ++s) { if (fProgramDesc.fStages[s].fEnabled) { GrTokenString outColor; if (currActiveStage < (numActiveStages - 1)) { outColor = "color"; outColor.appendInt(currActiveStage); segments.fFSCode += "\tvec4 "; segments.fFSCode += outColor; segments.fFSCode += ";\n"; } else { outColor = "gl_FragColor"; } genStageCode(s, fProgramDesc.fStages[s], haveColor ? inColor.cstr() : NULL, outColor.cstr(), stageInCoords[s], &segments, &programData->fUniLocations.fStages[s]); ++currActiveStage; inColor = outColor; haveColor = true; } } } else { segments.fFSCode += "\tgl_FragColor = "; if (haveColor) { segments.fFSCode += inColor; } else { segments.fFSCode += "vec4(1,1,1,1)"; } segments.fFSCode += ";\n"; } segments.fFSCode += "}\n"; segments.fVSCode += "}\n"; const char* strings[4]; int lengths[4]; int stringCnt = 0; if (segments.fVSUnis.length()) { strings[stringCnt] = segments.fVSUnis.cstr(); lengths[stringCnt] = segments.fVSUnis.length(); ++stringCnt; } if (segments.fVSAttrs.length()) { strings[stringCnt] = segments.fVSAttrs.cstr(); lengths[stringCnt] = segments.fVSAttrs.length(); ++stringCnt; } if (segments.fVaryings.length()) { strings[stringCnt] = segments.fVaryings.cstr(); lengths[stringCnt] = segments.fVaryings.length(); ++stringCnt; } GrAssert(segments.fVSCode.length()); strings[stringCnt] = segments.fVSCode.cstr(); lengths[stringCnt] = segments.fVSCode.length(); ++stringCnt; #if PRINT_SHADERS GrPrintf("%s%s%s%s\n", segments.fVSUnis.cstr(), segments.fVSAttrs.cstr(), segments.fVaryings.cstr(), segments.fVSCode.cstr()); #endif programData->fVShaderID = CompileShader(GR_GL_VERTEX_SHADER, stringCnt, strings, lengths); stringCnt = 0; if (strlen(GrShaderPrecision()) > 1) { strings[stringCnt] = GrShaderPrecision(); lengths[stringCnt] = strlen(GrShaderPrecision()); ++stringCnt; } if (segments.fFSUnis.length()) { strings[stringCnt] = segments.fFSUnis.cstr(); lengths[stringCnt] = segments.fFSUnis.length(); ++stringCnt; } if (segments.fVaryings.length()) { strings[stringCnt] = segments.fVaryings.cstr(); lengths[stringCnt] = segments.fVaryings.length(); ++stringCnt; } GrAssert(segments.fFSCode.length()); strings[stringCnt] = segments.fFSCode.cstr(); lengths[stringCnt] = segments.fFSCode.length(); ++stringCnt; #if PRINT_SHADERS GrPrintf("%s%s%s%s\n", GR_SHADER_PRECISION, segments.fFSUnis.cstr(), segments.fVaryings.cstr(), segments.fFSCode.cstr()); #endif programData->fFShaderID = CompileShader(GR_GL_FRAGMENT_SHADER, stringCnt, strings, lengths); programData->fProgramID = GR_GL(CreateProgram()); const GrGLint& progID = programData->fProgramID; GR_GL(AttachShader(progID, programData->fVShaderID)); GR_GL(AttachShader(progID, programData->fFShaderID)); // Bind the attrib locations to same values for all shaders GR_GL(BindAttribLocation(progID, POS_ATTR_LOCATION, POS_ATTR_NAME)); for (int t = 0; t < GrDrawTarget::kMaxTexCoords; ++t) { if (texCoordAttrs[t].length()) { GR_GL(BindAttribLocation(progID, TEX_ATTR_LOCATION(t), texCoordAttrs[t].cstr())); } } #if ATTRIBUTE_MATRIX // set unis to a bogus value so that checks against -1 before // flushing will pass. GR_GL(BindAttribLocation(progID, VIEWMAT_ATTR_LOCATION, VIEW_MATRIX_NAME)); program->fUniLocations.fViewMatrixUni = BOGUS_MATRIX_UNI_LOCATION; for (int s = 0; s < kNumStages; ++s) { if (fProgramDesc.fStages[s].fEnabled) { GrStringBuilder matName; tex_matrix_name(s, &matName); GR_GL(BindAttribLocation(progID, TEXMAT_ATTR_LOCATION(s), matName.cstr())); program->fUniLocations.fStages[s].fTextureMatrixUni = BOGUS_MATRIX_UNI_LOCATION; } } #endif GR_GL(BindAttribLocation(progID, COL_ATTR_LOCATION, COL_ATTR_NAME)); GR_GL(LinkProgram(progID)); GrGLint linked = GR_GL_INIT_ZERO; GR_GL(GetProgramiv(progID, GR_GL_LINK_STATUS, &linked)); if (!linked) { GrGLint infoLen = GR_GL_INIT_ZERO; GR_GL(GetProgramiv(progID, GR_GL_INFO_LOG_LENGTH, &infoLen)); GrAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger if (infoLen > 0) { GR_GL(GetProgramInfoLog(progID, infoLen+1, NULL, (char*)log.get())); GrPrintf((char*)log.get()); } GrAssert(!"Error linking program"); GR_GL(DeleteProgram(progID)); programData->fProgramID = 0; return; } // Get uniform locations #if !ATTRIBUTE_MATRIX programData->fUniLocations.fViewMatrixUni = GR_GL(GetUniformLocation(progID, VIEW_MATRIX_NAME)); GrAssert(-1 != programData->fUniLocations.fViewMatrixUni); #endif for (int s = 0; s < GrDrawTarget::kNumStages; ++s) { StageUniLocations& locations = programData->fUniLocations.fStages[s]; if (fProgramDesc.fStages[s].fEnabled) { #if !ATTRIBUTE_MATRIX if (locations.fTextureMatrixUni) { GrTokenString texMName; tex_matrix_name(s, &texMName); locations.fTextureMatrixUni = GR_GL(GetUniformLocation( progID, texMName.cstr())); GrAssert(-1 != locations.fTextureMatrixUni); } else { locations.fTextureMatrixUni = -1; } #endif if (locations.fSamplerUni) { GrTokenString samplerName; sampler_name(s, &samplerName); locations.fSamplerUni = GR_GL(GetUniformLocation( progID, samplerName.cstr())); GrAssert(-1 != locations.fSamplerUni); } else { locations.fSamplerUni = -1; } if (locations.fRadial2Uni) { GrTokenString radial2ParamName; radial2_param_name(s, &radial2ParamName); locations.fRadial2Uni = GR_GL(GetUniformLocation( progID, radial2ParamName.cstr())); GrAssert(-1 != locations.fRadial2Uni); } else { locations.fRadial2Uni = -1; } } else { locations.fSamplerUni = -1; locations.fRadial2Uni = -1; locations.fTextureMatrixUni = -1; } } GR_GL(UseProgram(progID)); // init sampler unis and set bogus values for state tracking for (int s = 0; s < GrDrawTarget::kNumStages; ++s) { if (-1 != programData->fUniLocations.fStages[s].fSamplerUni) { GR_GL(Uniform1i(programData->fUniLocations.fStages[s].fSamplerUni, s)); } programData->fTextureMatrices[s] = GrMatrix::InvalidMatrix(); programData->fRadial2CenterX1[s] = GR_ScalarMax; programData->fRadial2Radius0[s] = -GR_ScalarMax; } programData->fViewMatrix = GrMatrix::InvalidMatrix(); }
bool glsl_recompile(GLSLProgram *program, std::string *error_message) { struct stat vs, fs; AutoCharArrayBuf vsh_src, fsh_src; if (strlen(program->vshader_filename) > 0 && 0 == stat(program->vshader_filename, &vs)) { program->vshader_mtime = vs.st_mtime; if (!program->vshader_source) { size_t sz; vsh_src.reset((char *)ReadLocalFile(program->vshader_filename, &sz)); } } else { program->vshader_mtime = 0; } if (strlen(program->fshader_filename) > 0 && 0 == stat(program->fshader_filename, &fs)) { program->fshader_mtime = fs.st_mtime; if (!program->fshader_source) { size_t sz; fsh_src.reset((char *)ReadLocalFile(program->fshader_filename, &sz)); } } else { program->fshader_mtime = 0; } if (!program->vshader_source && !vsh_src) { size_t sz; vsh_src.reset((char *)VFSReadFile(program->vshader_filename, &sz)); } if (!program->vshader_source && !vsh_src) { ELOG("File missing: %s", program->vshader_filename); if (error_message) { *error_message = std::string("File missing: ") + program->vshader_filename; } return false; } if (!program->fshader_source && !fsh_src) { size_t sz; fsh_src.reset((char *)VFSReadFile(program->fshader_filename, &sz)); } if (!program->fshader_source && !fsh_src) { ELOG("File missing: %s", program->fshader_filename); if (error_message) { *error_message = std::string("File missing: ") + program->fshader_filename; } return false; } GLuint vsh = glCreateShader(GL_VERTEX_SHADER); const GLchar *vsh_str = program->vshader_source ? program->vshader_source : (const GLchar *)(vsh_src); if (!CompileShader(vsh_str, vsh, program->vshader_filename, error_message)) { return false; } const GLchar *fsh_str = program->fshader_source ? program->fshader_source : (const GLchar *)(fsh_src); GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER); if (!CompileShader(fsh_str, fsh, program->fshader_filename, error_message)) { glDeleteShader(vsh); return false; } GLuint prog = glCreateProgram(); glAttachShader(prog, vsh); glAttachShader(prog, fsh); glLinkProgram(prog); GLint linkStatus; glGetProgramiv(prog, GL_LINK_STATUS, &linkStatus); if (linkStatus == GL_FALSE) { GLint bufLength = 0; glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &bufLength); if (bufLength) { char* buf = new char[bufLength + 1]; // safety glGetProgramInfoLog(prog, bufLength, NULL, buf); ILOG("vsh: %i fsh: %i", vsh, fsh); ELOG("Could not link shader program (linkstatus=%i):\n %s \n", linkStatus, buf); if (error_message) { *error_message = buf; } delete [] buf; } else { ILOG("vsh: %i fsh: %i", vsh, fsh); ELOG("Could not link shader program (linkstatus=%i). No OpenGL error log was available.", linkStatus); if (error_message) { *error_message = "(no error message available)"; } } glDeleteShader(vsh); glDeleteShader(fsh); return false; } // Destroy the old program, if any. if (program->program_) { glDeleteProgram(program->program_); } program->program_ = prog; program->vsh_ = vsh; program->fsh_ = fsh; program->sampler0 = glGetUniformLocation(program->program_, "sampler0"); program->sampler1 = glGetUniformLocation(program->program_, "sampler1"); program->a_position = glGetAttribLocation(program->program_, "a_position"); program->a_color = glGetAttribLocation(program->program_, "a_color"); program->a_normal = glGetAttribLocation(program->program_, "a_normal"); program->a_texcoord0 = glGetAttribLocation(program->program_, "a_texcoord0"); program->a_texcoord1 = glGetAttribLocation(program->program_, "a_texcoord1"); program->u_worldviewproj = glGetUniformLocation(program->program_, "u_worldviewproj"); program->u_world = glGetUniformLocation(program->program_, "u_world"); program->u_viewproj = glGetUniformLocation(program->program_, "u_viewproj"); program->u_fog = glGetUniformLocation(program->program_, "u_fog"); program->u_sundir = glGetUniformLocation(program->program_, "u_sundir"); program->u_camerapos = glGetUniformLocation(program->program_, "u_camerapos"); //ILOG("Shader compilation success: %s %s", // program->vshader_filename, // program->fshader_filename); return true; }
int main( /* int argc, char* args[] */ ) { /* The window */ SDL_Window* window = NULL; /* The window surface */ SDL_Surface* screen = NULL; /* The event structure */ SDL_Event event; /* The game loop flag */ _Bool running = true; if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) { printf( "SDL2 could not initialize! SDL2_Error: %s\n", SDL_GetError() ); SDL_Quit(); return 1; } SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); window = SDL_CreateWindow( WINDOW_TITLE, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL); if (window == NULL) { printf("unable to create window\n"); SDL_Quit(); return 1; } SDL_GLContext maincontext; /* Our opengl context handle */ maincontext = SDL_GL_CreateContext(window); SDL_GL_SetSwapInterval(1); GLint texAllPixels[] = { 0xFF0000FF, 0xFF0000FF, 0xFF0000FF, 0xFF0000FF, 0xFF00FF00, 0xFF00FF00, 0xFF00FF00, 0xFF00FF00, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000 }; GLuint texture = 0; glGenTextures(1, &texture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D_ARRAY, texture); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 2, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texAllPixels); glGenerateMipmap(GL_TEXTURE_2D_ARRAY); static const GLfloat quadVerts[] = { -0.8f, 0.8f, 0.0f, 1.0f, 0.8f, 0.8f, 0.0f, 1.0f, -0.8f, -0.8f, 0.0f, 1.0f, 0.8f, -0.8f, 0.0f, 1.0f, }; GLuint vao = 0; glGenVertexArrays(1, &vao); glBindVertexArray(vao); GLuint quadVB = 0; glGenBuffers(1, &quadVB); glBindBuffer(GL_ARRAY_BUFFER, quadVB); glBufferData(GL_ARRAY_BUFFER, sizeof(quadVerts), quadVerts, GL_STATIC_DRAW); const GLchar* vshadercode = "#version 330 core\n"\ "layout(location = 0) in vec4 a_position\n;"\ "layout(location = 1) in vec2 a_texcoord\n;"\ "out vec2 v_texcoord\n;"\ "void main(void)\n"\ "{\n"\ " gl_Position = a_position;\n"\ " v_texcoord = a_texcoord;\n"\ "}"; const GLchar* fshadercode = "#version 330 core\n"\ "in vec2 v_texcoord;\n"\ "uniform sampler2DArray sTexture;\n"\ "out vec4 o_color;\n"\ "void main(){\n"\ " float x = v_texcoord.x*0.5 + 0.5;\n"\ " float y = v_texcoord.y*0.5 + 0.5;\n"\ " float layer = (x*5)-1;\n"\ " o_color = texture( sTexture, vec3(x, y, layer));\n"\ "}"; GLuint vshader = glCreateShader(GL_VERTEX_SHADER); GLuint fshader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(vshader, 1, &vshadercode, NULL); glShaderSource(fshader, 1, &fshadercode, NULL); CompileShader(vshader, "Vertex"); CompileShader(fshader, "Fragment"); GLuint program = glCreateProgram(); glAttachShader(program, vshader); glAttachShader(program, fshader); LinkProgram(program, ""); glUseProgram(program); GLuint texLoc = glGetUniformLocation(program, "sTexture"); GLuint matViewProjLoc = glGetUniformLocation(program, "u_matViewProjection"); GLuint posLoc = 0; GLuint texcoordLoc = 1; glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 16, 0); glEnableVertexAttribArray(1); while( running ) { while( SDL_PollEvent( &event ) != 0 ) { if( event.type == SDL_QUIT ) { running = false; } } glClearColor ( 0.5, 0.5, 0.5, 1.0 ); glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); SDL_GL_SwapWindow(window); } glDeleteProgram(program); glDeleteShader(vshader); glDeleteShader(fshader); glDeleteTextures(1, &texture); glDeleteBuffers(1, &quadVB); glDeleteVertexArrays(1, &vao); SDL_GL_DeleteContext(maincontext); SDL_DestroyWindow( window ); SDL_Quit(); return 0; }
uniform vec2 scale;\ attribute vec2 uv;\ attribute vec3 position;\ varying vec2 texCoord;\ void main() {\ texCoord = uv * scale;\ gl_Position = mvp * vec4(position, 1.0);\ }"; const char* f_shader = "#version 120 \n\ varying vec2 texCoord;\ uniform sampler2D texture;\ void main() {\ gl_FragColor = texture2D(texture, texCoord);\ }\0"; GLuint vertexShader = CompileShader(v_shader, GL_VERTEX_SHADER); GLuint fragmentShader = CompileShader(f_shader, GL_FRAGMENT_SHADER); assert(vertexShader != -1 && fragmentShader != -1); // Make actual shader program GLint result; m_nBlitShader = glCreateProgram(); glAttachShader(m_nBlitShader, vertexShader); glAttachShader(m_nBlitShader, fragmentShader); glLinkProgram(m_nBlitShader); glGetProgramiv(m_nBlitShader, GL_LINK_STATUS, &result); if (result == GL_FALSE) { std::cout << "Could not link shader program!\n"; glGetProgramiv(m_nBlitShader, GL_INFO_LOG_LENGTH, &result); if (result > 0) { char* log = new char[result];
bool GSDevice10::Create(HWND hWnd, bool vsync) { if(!__super::Create(hWnd, vsync)) { return false; } HRESULT hr; DXGI_SWAP_CHAIN_DESC scd; D3D10_BUFFER_DESC bd; D3D10_SAMPLER_DESC sd; D3D10_DEPTH_STENCIL_DESC dsd; D3D10_RASTERIZER_DESC rd; D3D10_BLEND_DESC bsd; memset(&scd, 0, sizeof(scd)); scd.BufferCount = 2; scd.BufferDesc.Width = 1; scd.BufferDesc.Height = 1; scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; //scd.BufferDesc.RefreshRate.Numerator = 60; //scd.BufferDesc.RefreshRate.Denominator = 1; scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; scd.OutputWindow = hWnd; scd.SampleDesc.Count = 1; scd.SampleDesc.Quality = 0; scd.Windowed = TRUE; UINT flags = 0; #ifdef DEBUG flags |= D3D10_CREATE_DEVICE_DEBUG; #endif hr = D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, flags, D3D10_SDK_VERSION, &scd, &m_swapchain, &m_dev); if(FAILED(hr)) return false; // font /* // TODO: the driver crashes on alt-enter when using a font... D3DX10_FONT_DESC fd; memset(&fd, 0, sizeof(fd)); _tcscpy(fd.FaceName, _T("Arial")); fd.Height = 20; D3DX10CreateFontIndirect(m_dev, &fd, &m_font); */ // convert D3D10_INPUT_ELEMENT_DESC il_convert[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D10_INPUT_PER_VERTEX_DATA, 0}, }; hr = CompileShader(IDR_CONVERT10_FX, "vs_main", NULL, &m_convert.vs, il_convert, countof(il_convert), &m_convert.il); for(int i = 0; i < countof(m_convert.ps); i++) { CStringA main; main.Format("ps_main%d", i); hr = CompileShader(IDR_CONVERT10_FX, main, NULL, &m_convert.ps[i]); } memset(&bd, 0, sizeof(bd)); bd.Usage = D3D10_USAGE_DEFAULT; bd.BindFlags = D3D10_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = 0; bd.MiscFlags = 0; bd.ByteWidth = 4 * sizeof(GSVertexPT1); hr = m_dev->CreateBuffer(&bd, NULL, &m_convert.vb); memset(&dsd, 0, sizeof(dsd)); dsd.DepthEnable = false; dsd.StencilEnable = false; hr = m_dev->CreateDepthStencilState(&dsd, &m_convert.dss); memset(&bsd, 0, sizeof(bsd)); bsd.BlendEnable[0] = false; bsd.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL; hr = m_dev->CreateBlendState(&bsd, &m_convert.bs); // merge memset(&bd, 0, sizeof(bd)); bd.ByteWidth = sizeof(MergeConstantBuffer); bd.Usage = D3D10_USAGE_DEFAULT; bd.BindFlags = D3D10_BIND_CONSTANT_BUFFER; bd.CPUAccessFlags = 0; bd.MiscFlags = 0; hr = m_dev->CreateBuffer(&bd, NULL, &m_merge.cb); for(int i = 0; i < countof(m_merge.ps); i++) { CStringA main; main.Format("ps_main%d", i); hr = CompileShader(IDR_MERGE10_FX, main, NULL, &m_merge.ps[i]); } memset(&bsd, 0, sizeof(bsd)); bsd.BlendEnable[0] = true; bsd.BlendOp = D3D10_BLEND_OP_ADD; bsd.SrcBlend = D3D10_BLEND_SRC_ALPHA; bsd.DestBlend = D3D10_BLEND_INV_SRC_ALPHA; bsd.BlendOpAlpha = D3D10_BLEND_OP_ADD; bsd.SrcBlendAlpha = D3D10_BLEND_ONE; bsd.DestBlendAlpha = D3D10_BLEND_ZERO; bsd.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL; hr = m_dev->CreateBlendState(&bsd, &m_merge.bs); // interlace memset(&bd, 0, sizeof(bd)); bd.ByteWidth = sizeof(InterlaceConstantBuffer); bd.Usage = D3D10_USAGE_DEFAULT; bd.BindFlags = D3D10_BIND_CONSTANT_BUFFER; bd.CPUAccessFlags = 0; bd.MiscFlags = 0; hr = m_dev->CreateBuffer(&bd, NULL, &m_interlace.cb); for(int i = 0; i < countof(m_interlace.ps); i++) { CStringA main; main.Format("ps_main%d", i); hr = CompileShader(IDR_INTERLACE10_FX, main, NULL, &m_interlace.ps[i]); } // memset(&rd, 0, sizeof(rd)); rd.FillMode = D3D10_FILL_SOLID; rd.CullMode = D3D10_CULL_NONE; rd.FrontCounterClockwise = false; rd.DepthBias = false; rd.DepthBiasClamp = 0; rd.SlopeScaledDepthBias = 0; rd.DepthClipEnable = false; // ??? rd.ScissorEnable = true; rd.MultisampleEnable = false; rd.AntialiasedLineEnable = false; hr = m_dev->CreateRasterizerState(&rd, &m_rs); m_dev->RSSetState(m_rs); // memset(&sd, 0, sizeof(sd)); sd.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR; sd.AddressU = D3D10_TEXTURE_ADDRESS_CLAMP; sd.AddressV = D3D10_TEXTURE_ADDRESS_CLAMP; sd.AddressW = D3D10_TEXTURE_ADDRESS_CLAMP; sd.MaxLOD = FLT_MAX; sd.MaxAnisotropy = 16; sd.ComparisonFunc = D3D10_COMPARISON_NEVER; hr = m_dev->CreateSamplerState(&sd, &m_convert.ln); sd.Filter = D3D10_FILTER_MIN_MAG_MIP_POINT; hr = m_dev->CreateSamplerState(&sd, &m_convert.pt); // Reset(1, 1, true); // /* if(!m_mergefx.Create(this)) { return false; } */ // return true; }
bool GSDevice11::Create(GSWnd* wnd) { if(!__super::Create(wnd)) { return false; } HRESULT hr = E_FAIL; DXGI_SWAP_CHAIN_DESC scd; D3D11_BUFFER_DESC bd; D3D11_SAMPLER_DESC sd; D3D11_DEPTH_STENCIL_DESC dsd; D3D11_RASTERIZER_DESC rd; D3D11_BLEND_DESC bsd; memset(&scd, 0, sizeof(scd)); scd.BufferCount = 2; scd.BufferDesc.Width = 1; scd.BufferDesc.Height = 1; scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; //scd.BufferDesc.RefreshRate.Numerator = 60; //scd.BufferDesc.RefreshRate.Denominator = 1; scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; scd.OutputWindow = (HWND)m_wnd->GetHandle(); scd.SampleDesc.Count = 1; scd.SampleDesc.Quality = 0; // Always start in Windowed mode. According to MS, DXGI just "prefers" this, and it's more or less // required if we want to add support for dual displays later on. The fullscreen/exclusive flip // will be issued after all other initializations are complete. scd.Windowed = TRUE; // NOTE : D3D11_CREATE_DEVICE_SINGLETHREADED // This flag is safe as long as the DXGI's internal message pump is disabled or is on the // same thread as the GS window (which the emulator makes sure of, if it utilizes a // multithreaded GS). Setting the flag is a nice and easy 5% speedup on GS-intensive scenes. uint32 flags = D3D11_CREATE_DEVICE_SINGLETHREADED; #ifdef DEBUG flags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL level; hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, levels, countof(levels), D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &level, &m_ctx); // hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, flags, NULL, 0, D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &level, &m_ctx); //return false; if(FAILED(hr)) return false; if(!SetFeatureLevel(level, true)) { return false; } D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS options; hr = m_dev->CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &options, sizeof(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS)); // msaa for(uint32 i = 2; i <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++) { uint32 quality[2] = {0, 0}; if(SUCCEEDED(m_dev->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, i, &quality[0])) && quality[0] > 0 && SUCCEEDED(m_dev->CheckMultisampleQualityLevels(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, i, &quality[1])) && quality[1] > 0) { m_msaa_desc.Count = i; m_msaa_desc.Quality = std::min<uint32>(quality[0] - 1, quality[1] - 1); if(i >= m_msaa) break; } } // convert D3D11_INPUT_ELEMENT_DESC il_convert[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0}, }; hr = CompileShader(IDR_CONVERT_FX, "vs_main", NULL, &m_convert.vs, il_convert, countof(il_convert), &m_convert.il); for(int i = 0; i < countof(m_convert.ps); i++) { hr = CompileShader(IDR_CONVERT_FX, format("ps_main%d", i), NULL, &m_convert.ps[i]); } memset(&dsd, 0, sizeof(dsd)); dsd.DepthEnable = false; dsd.StencilEnable = false; hr = m_dev->CreateDepthStencilState(&dsd, &m_convert.dss); memset(&bsd, 0, sizeof(bsd)); bsd.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; hr = m_dev->CreateBlendState(&bsd, &m_convert.bs); // merge memset(&bd, 0, sizeof(bd)); bd.ByteWidth = sizeof(MergeConstantBuffer); bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; hr = m_dev->CreateBuffer(&bd, NULL, &m_merge.cb); for(int i = 0; i < countof(m_merge.ps); i++) { hr = CompileShader(IDR_MERGE_FX, format("ps_main%d", i), NULL, &m_merge.ps[i]); } memset(&bsd, 0, sizeof(bsd)); bsd.RenderTarget[0].BlendEnable = true; bsd.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; bsd.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; bsd.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; bsd.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; bsd.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; bsd.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; bsd.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; hr = m_dev->CreateBlendState(&bsd, &m_merge.bs); // interlace memset(&bd, 0, sizeof(bd)); bd.ByteWidth = sizeof(InterlaceConstantBuffer); bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; hr = m_dev->CreateBuffer(&bd, NULL, &m_interlace.cb); for(int i = 0; i < countof(m_interlace.ps); i++) { hr = CompileShader(IDR_INTERLACE_FX, format("ps_main%d", i), NULL, &m_interlace.ps[i]); } // memset(&rd, 0, sizeof(rd)); rd.FillMode = D3D11_FILL_SOLID; rd.CullMode = D3D11_CULL_NONE; rd.FrontCounterClockwise = false; rd.DepthBias = false; rd.DepthBiasClamp = 0; rd.SlopeScaledDepthBias = 0; rd.DepthClipEnable = false; // ??? rd.ScissorEnable = true; rd.MultisampleEnable = true; rd.AntialiasedLineEnable = false; hr = m_dev->CreateRasterizerState(&rd, &m_rs); m_ctx->RSSetState(m_rs); // memset(&sd, 0, sizeof(sd)); sd.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; sd.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; sd.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; sd.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; sd.MaxLOD = FLT_MAX; sd.MaxAnisotropy = 16; sd.ComparisonFunc = D3D11_COMPARISON_NEVER; hr = m_dev->CreateSamplerState(&sd, &m_convert.ln); sd.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; hr = m_dev->CreateSamplerState(&sd, &m_convert.pt); // Reset(1, 1); // CreateTextureFX(); // memset(&dsd, 0, sizeof(dsd)); dsd.DepthEnable = false; dsd.StencilEnable = true; dsd.StencilReadMask = 1; dsd.StencilWriteMask = 1; dsd.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; dsd.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE; dsd.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; dsd.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; dsd.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; dsd.BackFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE; dsd.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; dsd.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; m_dev->CreateDepthStencilState(&dsd, &m_date.dss); D3D11_BLEND_DESC blend; memset(&blend, 0, sizeof(blend)); m_dev->CreateBlendState(&blend, &m_date.bs); // Exclusive/Fullscreen flip, issued for legacy (managed) windows only. GSopen2 style // emulators will issue the flip themselves later on. if(m_wnd->IsManaged()) { SetExclusive( !theApp.GetConfig("windowed", 1) ); } return true; }
ParticleTest::ParticleTest( const vec3 &o_pos ) : CObject( o_pos, vec3(), vec3(), CVec < SMaterial, void >() ) { D3D11_RASTERIZER_DESC rsDesc; rsDesc.AntialiasedLineEnable = false; rsDesc.CullMode = D3D11_CULL_NONE; rsDesc.DepthBias = 0; rsDesc.DepthBiasClamp = 0.f; rsDesc.DepthClipEnable = true; rsDesc.FillMode = D3D11_FILL_SOLID; rsDesc.FrontCounterClockwise = false; rsDesc.MultisampleEnable = false; rsDesc.ScissorEnable = false; rsDesc.SlopeScaledDepthBias = 0.f; _rs = RasterizerStatesManager::GetState( &rsDesc ); D3D11_BLEND_DESC blendDesc = {}; blendDesc.AlphaToCoverageEnable = false; blendDesc.IndependentBlendEnable = false; blendDesc.RenderTarget[ 0 ].BlendEnable = true; blendDesc.RenderTarget[ 0 ].SrcBlend = D3D11_BLEND_ONE; blendDesc.RenderTarget[ 0 ].DestBlend = D3D11_BLEND_ONE; blendDesc.RenderTarget[ 0 ].BlendOp = D3D11_BLEND_OP_ADD; blendDesc.RenderTarget[ 0 ].SrcBlendAlpha = D3D11_BLEND_ZERO; blendDesc.RenderTarget[ 0 ].DestBlendAlpha = D3D11_BLEND_ZERO; blendDesc.RenderTarget[ 0 ].BlendOpAlpha = D3D11_BLEND_OP_ADD; blendDesc.RenderTarget[ 0 ].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; _bs = BlendStatesManager::GetState( &blendDesc ); D3D11_SAMPLER_DESC sampDesc; sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; sampDesc.BorderColor[ 0 ] = 1.f; sampDesc.BorderColor[ 1 ] = 1.f; sampDesc.BorderColor[ 2 ] = 1.f; sampDesc.BorderColor[ 3 ] = 1.f; sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; sampDesc.MaxAnisotropy = 1; sampDesc.MaxLOD = FLT_MAX; sampDesc.MinLOD = -FLT_MAX; sampDesc.MipLODBias = 0.f; _ss = SamplersManager::GetState( &sampDesc ); _particlesDrawShader = ShadersManager::AcquireByName( "particleTest" ); _meshesDrawShader = ShadersManager::AcquireByName( "meshesTest" ); ASSUME( sizeof(SParticle) == 48 ); static const D3D11_BUFFER_DESC vbufDesc = { ParticlesReserveSize * sizeof(SParticle), D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS, 0, D3D11_RESOURCE_MISC_BUFFER_STRUCTURED, sizeof(SParticle) }; DXHRCHECK( RendererGlobals::i_Device->CreateBuffer( &vbufDesc, 0, _particlesVB.AddrModifiable() ) ); DXHRCHECK( RendererGlobals::i_Device->CreateUnorderedAccessView( _particlesVB, 0, _particlesVBUAV.AddrModifiableRelease() ) ); DXHRCHECK( RendererGlobals::i_Device->CreateShaderResourceView( _particlesVB, 0, _particlesVBSRV.AddrModifiableRelease() ) ); static const D3D11_BUFFER_DESC vbufMeshDesc = { ParticlesReserveSize * sizeof(SParticle), D3D11_USAGE_DEFAULT, D3D11_BIND_VERTEX_BUFFER, 0, 0, sizeof(SParticle) }; DXHRCHECK( RendererGlobals::i_Device->CreateBuffer( &vbufMeshDesc, 0, _meshesVB.AddrModifiable() ) ); ASSUME( sizeof(ParticleFrame) == 80 ); static const D3D11_BUFFER_DESC vbufFrameDataDesc = { ParticlesReserveSize * sizeof(ParticleFrame), D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS, 0, D3D11_RESOURCE_MISC_BUFFER_STRUCTURED, sizeof(ParticleFrame) }; DXHRCHECK( RendererGlobals::i_Device->CreateBuffer( &vbufFrameDataDesc, 0, _particlesFrameDataVB.AddrModifiable() ) ); DXHRCHECK( RendererGlobals::i_Device->CreateUnorderedAccessView( _particlesFrameDataVB, 0, _frameDataUAV.AddrModifiableRelease() ) ); DXHRCHECK( RendererGlobals::i_Device->CreateShaderResourceView( _particlesFrameDataVB, 0, _frameDataSRV.AddrModifiableRelease() ) ); _textureView = TextureLoader::Load( "Textures/ball.dds" ); _circleTextureView = TextureLoader::Load( "Textures/circle.dds" ); if( CompileShader( L"Shaders/eraseFrameData_cs.hlsl", &_eraseFrameDataCS ) ) { SENDLOG( CLogger::Tag::important, "compiled erase frame data cs\n" ); } D3D11_BUFFER_DESC uniBufDesc; uniBufDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; uniBufDesc.ByteWidth = 256; uniBufDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; uniBufDesc.MiscFlags = 0; uniBufDesc.StructureByteStride = 0; uniBufDesc.Usage = D3D11_USAGE_DYNAMIC; DXHRCHECK( RendererGlobals::i_Device->CreateBuffer( &uniBufDesc, 0, _uniBuffer.AddrModifiable() ) ); static const VertexBufferFieldDesc MeshBufferDesc[] = { { "POSITION", DXGI_FORMAT_R32G32B32_FLOAT, 0, 0 }, { "COLOR", DXGI_FORMAT_R32G32B32A32_FLOAT, 16, 0 }, { "TEXCOORD", DXGI_FORMAT_R32G32_FLOAT, 32, 0 } }; LayoutsManager::BufferDesc_t compiledMeshBufferDesc = RendererGlobals::DefLayoutsManager.CompileBufferDesc( MakeRefVec( MeshBufferDesc ) ); bln meshBlendResult = ShadersManager::TryToBlend( compiledMeshBufferDesc, _meshesDrawShader, &_meshInputLayout ); ASSUME( meshBlendResult ); //LoadPSystems(); LoadMeshes(); }
void GSDevice11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel) { hash_map<uint64, CComPtr<ID3D11PixelShader> >::const_iterator i = m_ps.find(sel); if(i == m_ps.end()) { string str[21]; str[0] = format("%d", sel.fst); str[1] = format("%d", sel.wms); str[2] = format("%d", sel.wmt); str[3] = format("%d", sel.fmt); str[4] = format("%d", sel.aem); str[5] = format("%d", sel.tfx); str[6] = format("%d", sel.tcc); str[7] = format("%d", sel.atst); str[8] = format("%d", sel.fog); str[9] = format("%d", sel.clr1); str[10] = format("%d", sel.fba); str[11] = format("%d", sel.aout); str[12] = format("%d", sel.ltf); str[13] = format("%d", sel.colclip); str[14] = format("%d", sel.date); str[15] = format("%d", sel.spritehack); str[16] = format("%d", sel.tcoffsethack); str[17] = format("%d", sel.point_sampler); str[18] = format("%d", sel.shuffle); str[19] = format("%d", sel.read_ba); str[20] = format("%d", sel.fmt >> 2); D3D_SHADER_MACRO macro[] = { {"PS_FST", str[0].c_str()}, {"PS_WMS", str[1].c_str()}, {"PS_WMT", str[2].c_str()}, {"PS_FMT", str[3].c_str()}, {"PS_AEM", str[4].c_str()}, {"PS_TFX", str[5].c_str()}, {"PS_TCC", str[6].c_str()}, {"PS_ATST", str[7].c_str()}, {"PS_FOG", str[8].c_str()}, {"PS_CLR1", str[9].c_str()}, {"PS_FBA", str[10].c_str()}, {"PS_AOUT", str[11].c_str()}, {"PS_LTF", str[12].c_str()}, {"PS_COLCLIP", str[13].c_str()}, {"PS_DATE", str[14].c_str()}, {"PS_SPRITEHACK", str[15].c_str()}, {"PS_TCOFFSETHACK", str[16].c_str()}, {"PS_POINT_SAMPLER", str[17].c_str()}, {"PS_SHUFFLE", str[18].c_str() }, {"PS_READ_BA", str[19].c_str() }, {"PS_PAL_FMT", str[20].c_str() }, {NULL, NULL}, }; CComPtr<ID3D11PixelShader> ps; vector<unsigned char> shader; theApp.LoadResource(IDR_TFX_FX, shader); CompileShader((const char *)shader.data(), shader.size(), "tfx.fx", nullptr, "ps_main", macro, &ps); m_ps[sel] = ps; i = m_ps.find(sel); }
bool GSDevice11::Create(const std::shared_ptr<GSWnd> &wnd) { if(!__super::Create(wnd)) { return false; } HRESULT hr = E_FAIL; DXGI_SWAP_CHAIN_DESC scd; D3D11_BUFFER_DESC bd; D3D11_SAMPLER_DESC sd; D3D11_DEPTH_STENCIL_DESC dsd; D3D11_RASTERIZER_DESC rd; D3D11_BLEND_DESC bsd; CComPtr<IDXGIAdapter1> adapter; D3D_DRIVER_TYPE driver_type = D3D_DRIVER_TYPE_HARDWARE; std::string adapter_id = theApp.GetConfigS("Adapter"); if (adapter_id == "default") ; else if (adapter_id == "ref") { driver_type = D3D_DRIVER_TYPE_REFERENCE; } else { CComPtr<IDXGIFactory1> dxgi_factory; CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&dxgi_factory); if (dxgi_factory) for (int i = 0;; i++) { CComPtr<IDXGIAdapter1> enum_adapter; if (S_OK != dxgi_factory->EnumAdapters1(i, &enum_adapter)) break; DXGI_ADAPTER_DESC1 desc; hr = enum_adapter->GetDesc1(&desc); if (S_OK == hr && GSAdapter(desc) == adapter_id) { adapter = enum_adapter; driver_type = D3D_DRIVER_TYPE_UNKNOWN; break; } } } memset(&scd, 0, sizeof(scd)); scd.BufferCount = 2; scd.BufferDesc.Width = 1; scd.BufferDesc.Height = 1; scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; //scd.BufferDesc.RefreshRate.Numerator = 60; //scd.BufferDesc.RefreshRate.Denominator = 1; scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; scd.OutputWindow = (HWND)m_wnd->GetHandle(); scd.SampleDesc.Count = 1; scd.SampleDesc.Quality = 0; // Always start in Windowed mode. According to MS, DXGI just "prefers" this, and it's more or less // required if we want to add support for dual displays later on. The fullscreen/exclusive flip // will be issued after all other initializations are complete. scd.Windowed = TRUE; spritehack = theApp.GetConfigB("UserHacks") ? theApp.GetConfigI("UserHacks_SpriteHack") : 0; isNative = theApp.GetConfigI("upscale_multiplier") == 1; // NOTE : D3D11_CREATE_DEVICE_SINGLETHREADED // This flag is safe as long as the DXGI's internal message pump is disabled or is on the // same thread as the GS window (which the emulator makes sure of, if it utilizes a // multithreaded GS). Setting the flag is a nice and easy 5% speedup on GS-intensive scenes. uint32 flags = D3D11_CREATE_DEVICE_SINGLETHREADED; #ifdef DEBUG flags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL level; const D3D_FEATURE_LEVEL levels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; hr = D3D11CreateDeviceAndSwapChain(adapter, driver_type, NULL, flags, levels, countof(levels), D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &level, &m_ctx); if(FAILED(hr)) return false; if(!SetFeatureLevel(level, true)) { return false; } D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS options; hr = m_dev->CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &options, sizeof(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS)); // msaa for(uint32 i = 2; i <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++) { uint32 quality[2] = {0, 0}; if(SUCCEEDED(m_dev->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, i, &quality[0])) && quality[0] > 0 && SUCCEEDED(m_dev->CheckMultisampleQualityLevels(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, i, &quality[1])) && quality[1] > 0) { m_msaa_desc.Count = i; m_msaa_desc.Quality = std::min<uint32>(quality[0] - 1, quality[1] - 1); if(i >= m_msaa) break; } } if(m_msaa_desc.Count == 1) { m_msaa = 0; } // convert D3D11_INPUT_ELEMENT_DESC il_convert[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0}, }; std::vector<char> shader; theApp.LoadResource(IDR_CONVERT_FX, shader); CompileShader(shader.data(), shader.size(), "convert.fx", nullptr, "vs_main", nullptr, &m_convert.vs, il_convert, countof(il_convert), &m_convert.il); for(size_t i = 0; i < countof(m_convert.ps); i++) { CompileShader(shader.data(), shader.size(), "convert.fx", nullptr, format("ps_main%d", i).c_str(), nullptr, &m_convert.ps[i]); } memset(&dsd, 0, sizeof(dsd)); dsd.DepthEnable = false; dsd.StencilEnable = false; hr = m_dev->CreateDepthStencilState(&dsd, &m_convert.dss); memset(&bsd, 0, sizeof(bsd)); bsd.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; hr = m_dev->CreateBlendState(&bsd, &m_convert.bs); // merge memset(&bd, 0, sizeof(bd)); bd.ByteWidth = sizeof(MergeConstantBuffer); bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; hr = m_dev->CreateBuffer(&bd, NULL, &m_merge.cb); theApp.LoadResource(IDR_MERGE_FX, shader); for(size_t i = 0; i < countof(m_merge.ps); i++) { CompileShader(shader.data(), shader.size(), "merge.fx", nullptr, format("ps_main%d", i).c_str(), nullptr, &m_merge.ps[i]); } memset(&bsd, 0, sizeof(bsd)); bsd.RenderTarget[0].BlendEnable = true; bsd.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; bsd.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; bsd.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; bsd.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; bsd.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; bsd.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; bsd.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; hr = m_dev->CreateBlendState(&bsd, &m_merge.bs); // interlace memset(&bd, 0, sizeof(bd)); bd.ByteWidth = sizeof(InterlaceConstantBuffer); bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; hr = m_dev->CreateBuffer(&bd, NULL, &m_interlace.cb); theApp.LoadResource(IDR_INTERLACE_FX, shader); for(size_t i = 0; i < countof(m_interlace.ps); i++) { CompileShader(shader.data(), shader.size(), "interlace.fx", nullptr, format("ps_main%d", i).c_str(), nullptr, &m_interlace.ps[i]); } // Shade Boos int ShadeBoost_Contrast = theApp.GetConfigI("ShadeBoost_Contrast"); int ShadeBoost_Brightness = theApp.GetConfigI("ShadeBoost_Brightness"); int ShadeBoost_Saturation = theApp.GetConfigI("ShadeBoost_Saturation"); string str[3]; str[0] = format("%d", ShadeBoost_Saturation); str[1] = format("%d", ShadeBoost_Brightness); str[2] = format("%d", ShadeBoost_Contrast); D3D_SHADER_MACRO macro[] = { {"SB_SATURATION", str[0].c_str()}, {"SB_BRIGHTNESS", str[1].c_str()}, {"SB_CONTRAST", str[2].c_str()}, {NULL, NULL}, }; memset(&bd, 0, sizeof(bd)); bd.ByteWidth = sizeof(ShadeBoostConstantBuffer); bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; hr = m_dev->CreateBuffer(&bd, NULL, &m_shadeboost.cb); theApp.LoadResource(IDR_SHADEBOOST_FX, shader); CompileShader(shader.data(), shader.size(), "shadeboost.fx", nullptr, "ps_main", macro, &m_shadeboost.ps); // External fx shader memset(&bd, 0, sizeof(bd)); bd.ByteWidth = sizeof(ExternalFXConstantBuffer); bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; hr = m_dev->CreateBuffer(&bd, NULL, &m_shaderfx.cb); // Fxaa memset(&bd, 0, sizeof(bd)); bd.ByteWidth = sizeof(FXAAConstantBuffer); bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; hr = m_dev->CreateBuffer(&bd, NULL, &m_fxaa.cb); // memset(&rd, 0, sizeof(rd)); rd.FillMode = D3D11_FILL_SOLID; rd.CullMode = D3D11_CULL_NONE; rd.FrontCounterClockwise = false; rd.DepthBias = false; rd.DepthBiasClamp = 0; rd.SlopeScaledDepthBias = 0; rd.DepthClipEnable = false; // ??? rd.ScissorEnable = true; rd.MultisampleEnable = true; rd.AntialiasedLineEnable = false; hr = m_dev->CreateRasterizerState(&rd, &m_rs); m_ctx->RSSetState(m_rs); // memset(&sd, 0, sizeof(sd)); sd.Filter = theApp.GetConfigI("MaxAnisotropy") && !theApp.GetConfigB("paltex") ? D3D11_FILTER_ANISOTROPIC : D3D11_FILTER_MIN_MAG_MIP_LINEAR; sd.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; sd.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; sd.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; sd.MinLOD = -FLT_MAX; sd.MaxLOD = FLT_MAX; sd.MaxAnisotropy = theApp.GetConfigI("MaxAnisotropy"); sd.ComparisonFunc = D3D11_COMPARISON_NEVER; hr = m_dev->CreateSamplerState(&sd, &m_convert.ln); sd.Filter = theApp.GetConfigI("MaxAnisotropy") && !theApp.GetConfigB("paltex") ? D3D11_FILTER_ANISOTROPIC : D3D11_FILTER_MIN_MAG_MIP_POINT; hr = m_dev->CreateSamplerState(&sd, &m_convert.pt); // Reset(1, 1); // CreateTextureFX(); // memset(&dsd, 0, sizeof(dsd)); dsd.DepthEnable = false; dsd.StencilEnable = true; dsd.StencilReadMask = 1; dsd.StencilWriteMask = 1; dsd.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; dsd.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE; dsd.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; dsd.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; dsd.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; dsd.BackFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE; dsd.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; dsd.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; m_dev->CreateDepthStencilState(&dsd, &m_date.dss); D3D11_BLEND_DESC blend; memset(&blend, 0, sizeof(blend)); m_dev->CreateBlendState(&blend, &m_date.bs); // Exclusive/Fullscreen flip, issued for legacy (managed) windows only. GSopen2 style // emulators will issue the flip themselves later on. if(m_wnd->IsManaged()) { SetExclusive(!theApp.GetConfigB("windowed")); } return true; }
GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader) { CONTEXT_EXEC(CompileShader(shader)); }
//-------------------------------------------------------------------------------- // Constructors/Destructors //-------------------------------------------------------------------------------- ShaderData::ShaderData(const std::string& fileName) { std::string actualFileName = fileName; #if PROFILING_DISABLE_SHADING != 0 actualFileName = "nullShader"; #endif m_program = glCreateProgram(); if (m_program == 0) { fprintf(stderr, "Error creating shader program\n"); exit(1); } if(s_supportedOpenGLLevel == 0) { int majorVersion; int minorVersion; glGetIntegerv(GL_MAJOR_VERSION, &majorVersion); glGetIntegerv(GL_MINOR_VERSION, &minorVersion); s_supportedOpenGLLevel = majorVersion * 100 + minorVersion * 10; if(s_supportedOpenGLLevel >= 330) { std::ostringstream convert; convert << s_supportedOpenGLLevel; s_glslVersion = convert.str(); } else if(s_supportedOpenGLLevel >= 320) { s_glslVersion = "150"; } else if(s_supportedOpenGLLevel >= 310) { s_glslVersion = "140"; } else if(s_supportedOpenGLLevel >= 300) { s_glslVersion = "130"; } else if(s_supportedOpenGLLevel >= 210) { s_glslVersion = "120"; } else if(s_supportedOpenGLLevel >= 200) { s_glslVersion = "110"; } else { fprintf(stderr, "Error: OpenGL Version %d.%d does not support shaders.\n", majorVersion, minorVersion); exit(1); } } std::string shaderText = LoadShader(actualFileName + ".glsl"); std::string vertexShaderText = "#version " + s_glslVersion + "\n#define VS_BUILD\n#define GLSL_VERSION " + s_glslVersion + "\n" + shaderText; std::string fragmentShaderText = "#version " + s_glslVersion + "\n#define FS_BUILD\n#define GLSL_VERSION " + s_glslVersion + "\n" + shaderText; AddVertexShader(vertexShaderText); AddFragmentShader(fragmentShaderText); std::string attributeKeyword = "attribute"; AddAllAttributes(vertexShaderText, attributeKeyword); CompileShader(); AddShaderUniforms(shaderText); }
bool Shader::LoadShader(string vertexName, string fragmentName) { GLuint vertShader, fragShader; // Create shader program. _program = glCreateProgram(); // Create and compile vertex shader. if (!CompileShader(&vertShader, GL_VERTEX_SHADER, vertexName)) { cout << "Failed to compile vertex shader "<<vertexName<<endl; return false; } // Create and compile fragment shader. if (!CompileShader(&fragShader, GL_FRAGMENT_SHADER, fragmentName)) { cout << "Failed to compile fragment shader " << fragmentName << endl; return false; } // Attach vertex shader to program. glAttachShader(_program, vertShader); // Attach fragment shader to program. glAttachShader(_program, fragShader); // Bind attribute locations. // This needs to be done prior to linking. glBindAttribLocation(_program, ATTRIB_VERTEX, "position"); glBindAttribLocation(_program, ATTRIB_NORMAL, "normal"); glBindAttribLocation(_program, ATTRIB_TCOORD, "tcoord"); glBindAttribLocation(_program, ATTRIB_INDICES, "indices"); glBindAttribLocation(_program, ATTRIB_COEFFICIENTS, "coefficients"); // Link program. if (!LinkProgram(_program)) { cout << "Failed to link program: " << _program << endl; if (vertShader) { glDeleteShader(vertShader); vertShader = 0; } if (fragShader) { glDeleteShader(fragShader); fragShader = 0; } if (_program) { glDeleteProgram(_program); _program = 0; } return false; } // Release vertex and fragment shaders. if (vertShader) { glDetachShader(_program, vertShader); glDeleteShader(vertShader); } if (fragShader) { glDetachShader(_program, fragShader); glDeleteShader(fragShader); } return true; }
bool Shader::Load(const File &vshFile, const File &fshFile, std::function<void(GLuint)> bindAttribCompletion, std::function<void(GLuint)> bindUniformCompletion) { GLuint vertShader, fragShader; // Create shader program. program_ = glCreateProgram(); // Create and compile vertex shader. bool status = CompileShader(&vertShader, GL_VERTEX_SHADER, vshFile); if (!status) { std::cout << "Failed to compile vertex shader" << std::endl; return false; } // Create and compile fragment shader. status = CompileShader(&fragShader, GL_FRAGMENT_SHADER, fshFile); if (!status) { std::cout << "Failed to compile fragment shader" << std::endl; return false; } // Attach vertex shader to program. glAttachShader(program_, vertShader); // Attach fragment shader to program. glAttachShader(program_, fragShader); // Bind attribute locations. // This needs to be done prior to linking. bindAttribCompletion(program_); // Link program. status = LinkProgram(program_); if (!status) { std::cout << "Failed to link program: " << program_ << std::endl; if (vertShader) { glDeleteShader(vertShader); vertShader = 0; } if (fragShader) { glDeleteShader(fragShader); fragShader = 0; } if (program_) { glDeleteProgram(program_); program_ = 0; } return false; } bindUniformCompletion(program_); // Release vertex and fragment shaders. if (vertShader) { glDetachShader(program_, vertShader); glDeleteShader(vertShader); } if (fragShader) { glDetachShader(program_, fragShader); glDeleteShader(fragShader); } return true; }
/* function:CreateProgram This function is to compile and link a full program from 3 filenames Parameters: vertFileName: a pointer to the filename of the vertex shader(can be null) geoFileName:a pointer to the filename of the geometry shader(can be null) fragFileName: a pointer to the filename of the fragment shader(can be null) Return Value: The identifier of the linked and compiled program */ GLint MakeShaderProgram(const char* vertFileName, const char* geoFileName, const char* fragFileName, int debugOption) { GLint programID = glCreateProgram(); //compile each of the shaders that isn't null if (vertFileName != '\0') { GLuint vertShader = CompileShader(GL_VERTEX_SHADER, vertFileName, debugOption); if (vertShader == 0) return 0; glAttachShader(programID, vertShader); } if (geoFileName != '\0') { GLuint geoShader = CompileShader(GL_GEOMETRY_SHADER, geoFileName, debugOption); if (geoShader == 0) return 0; glAttachShader(programID, geoShader); } if (fragFileName != '\0') { GLuint fragShader = CompileShader(GL_FRAGMENT_SHADER, fragFileName, debugOption); if (fragShader == 0) return 0; glAttachShader(programID, fragShader); } if (debugOption) printf("\tLinking Program\n"); glLinkProgram(programID); //get the linking status GLint status; glGetProgramiv(programID, GL_LINK_STATUS, &status); //if linking failed, output the error message if (status == GL_FALSE) { //we have to get the log length first GLint infoLogLength; glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &infoLogLength); //get the program log GLchar* infoLog = (GLchar*)malloc((sizeof(GLchar))*(infoLogLength + 1)); (*infoLog) = '\0'; glGetProgramInfoLog(programID, infoLogLength, NULL, infoLog); printf("\t%s\n", infoLog); free(infoLog); } //print an success message else if (debugOption) { printf("\tLinked Successfully\n"); } //now set up the uniform locations /*matrixUniformLocation = glGetUniformLocation(programID, "finalMatrix"); if (hasLighting) { wcLightLocationUniformLocation = glGetUniformLocation(programID, "wcLightLocation"); normalTransformMatrixUniformLocation = glGetUniformLocation(programID, "normalTransformMatrix"); } else { wcLightLocationUniformLocation = 0; normalTransformMatrixUniformLocation = 0; }*/ //I'm not sure if this has any value, but I'll keep it here for a bit to find out return programID; }
RenderDevice::RenderDevice(const RendererParams& p, HWND window) { RECT rc; GetClientRect(window, &rc); UINT width = rc.right - rc.left; UINT height = rc.bottom - rc.top; WindowWidth = width; WindowHeight = height; Window = window; Params = p; memset(UniformBuffers, 0, sizeof(UniformBuffers)); memset(CommonUniforms, 0, sizeof(CommonUniforms)); QuadVertexBuffer = NULL; HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&DXGIFactory.GetRawRef())); if (FAILED(hr)) return; // Find the adapter & output (monitor) to use for fullscreen, based on the reported name of the HMD's monitor. if (Params.MonitorName.GetLength() > 0) { for(UINT AdapterIndex = 0; ; AdapterIndex++) { HRESULT hr = DXGIFactory->EnumAdapters(AdapterIndex, &Adapter.GetRawRef()); if (hr == DXGI_ERROR_NOT_FOUND) break; DXGI_ADAPTER_DESC Desc; Adapter->GetDesc(&Desc); UpdateMonitorOutputs(); if (FullscreenOutput) break; } if (!FullscreenOutput) Adapter = NULL; } if (!Adapter) { DXGIFactory->EnumAdapters(0, &Adapter.GetRawRef()); } int flags = 0; hr = D3D10CreateDevice(Adapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, flags, D3D1x_(SDK_VERSION), &Device.GetRawRef()); Context = Device; Context->AddRef(); if (FAILED(hr)) return; if (!RecreateSwapChain()) return; if (Params.Fullscreen) SwapChain->SetFullscreenState(1, FullscreenOutput); CurRenderTarget = NULL; for(int i = 0; i < Shader_Count; i++) { UniformBuffers[i] = CreateBuffer(); MaxTextureSet[i] = 0; } ID3D10Blob* vsData = CompileShader("vs_4_0", DirectVertexShaderSrc); VertexShaders[VShader_MV] = *new VertexShader(this, vsData); for(int i = 1; i < VShader_Count; i++) { VertexShaders[i] = *new VertexShader(this, CompileShader("vs_4_0", VShaderSrcs[i])); } for(int i = 0; i < FShader_Count; i++) { PixelShaders[i] = *new PixelShader(this, CompileShader("ps_4_0", FShaderSrcs[i])); } SPInt bufferSize = vsData->GetBufferSize(); const void* buffer = vsData->GetBufferPointer(); ID3D1xInputLayout** objRef = &ModelVertexIL.GetRawRef(); HRESULT validate = Device->CreateInputLayout(ModelVertexDesc, sizeof(ModelVertexDesc)/sizeof(D3D1x_(INPUT_ELEMENT_DESC)), buffer, bufferSize, objRef); OVR_UNUSED(validate); Ptr<ShaderSet> gouraudShaders = *new ShaderSet(); gouraudShaders->SetShader(VertexShaders[VShader_MVP]); gouraudShaders->SetShader(PixelShaders[FShader_Gouraud]); DefaultFill = *new ShaderFill(gouraudShaders); D3D1x_(BLEND_DESC) bm; memset(&bm, 0, sizeof(bm)); bm.BlendEnable[0] = true; bm.BlendOp = bm.BlendOpAlpha = D3D1x_(BLEND_OP_ADD); bm.SrcBlend = bm.SrcBlendAlpha = D3D1x_(BLEND_SRC_ALPHA); bm.DestBlend = bm.DestBlendAlpha = D3D1x_(BLEND_INV_SRC_ALPHA); bm.RenderTargetWriteMask[0] = D3D1x_(COLOR_WRITE_ENABLE_ALL); Device->CreateBlendState(&bm, &BlendState.GetRawRef()); D3D1x_(RASTERIZER_DESC) rs; memset(&rs, 0, sizeof(rs)); rs.AntialiasedLineEnable = true; rs.CullMode = D3D1x_(CULL_BACK); rs.DepthClipEnable = true; rs.FillMode = D3D1x_(FILL_SOLID); Device->CreateRasterizerState(&rs, &Rasterizer.GetRawRef()); QuadVertexBuffer = CreateBuffer(); const RenderTiny::Vertex QuadVertices[] = { Vertex(Vector3f(0, 1, 0)), Vertex(Vector3f(1, 1, 0)), Vertex(Vector3f(0, 0, 0)), Vertex(Vector3f(1, 0, 0)) }; QuadVertexBuffer->Data(Buffer_Vertex, QuadVertices, sizeof(QuadVertices)); SetDepthMode(0, 0); }
bool ParticleManager::BuildShaders(ID3D11Device* pDevice) { #pragma region COMPILE_RENDER_SHADER if (!CompileShader(&m_vBlob, "Data/particles.fx", "VS_MAIN", "vs_5_0")) { return false; } ID3DBlob* pBlob = 0; if (!CompileShader(&pBlob, "Data/particles.fx", "PS_MAIN", "ps_5_0")) { if (pBlob) { pBlob->Release(); } return false; } #pragma endregion #pragma region COMPILE_UPDATE_SHADER ID3DBlob* vBlob = 0; if (!CompileShader(&vBlob, "Data/particles.fx", "VS_MAIN_SO", "vs_5_0")) { if (vBlob) { vBlob->Release(); } return false; } ID3DBlob* gBlob = 0; if (!CompileShader(&gBlob, "Data/particles.fx", "GS_MAIN_SO", "gs_5_0")) { if (gBlob) { gBlob->Release(); } return false; } #pragma endregion #pragma region CREATE_RENDER_SHADER HRESULT hr = 0; hr = pDevice->CreateVertexShader(m_vBlob->GetBufferPointer(), m_vBlob->GetBufferSize(), NULL, &m_vShader); if (FAILED(hr)) { return false; } hr = pDevice->CreatePixelShader(pBlob->GetBufferPointer(), pBlob->GetBufferSize(), NULL, &m_pShader); if (FAILED(hr)) { pBlob->Release(); return false; } pBlob->Release(); #pragma endregion hr = pDevice->CreateVertexShader(vBlob->GetBufferPointer(), vBlob->GetBufferSize(), NULL, &m_vUpdate); if (FAILED(hr)) { vBlob->Release(); return false; } //Stream out decl D3D11_SO_DECLARATION_ENTRY dso[] = { { 0, "SV_POSITION", 0, 0, 3, 0 }, { 0, "VELOCITY", 0, 0, 3, 0 }, { 0, "COLOR", 0, 0, 4, 0 } }; UINT stride = sizeof(Particle); UINT elems = sizeof(dso) / sizeof(D3D11_SO_DECLARATION_ENTRY); hr = pDevice->CreateGeometryShaderWithStreamOutput( gBlob->GetBufferPointer(), gBlob->GetBufferSize(), dso, elems, &stride, 1, 0, NULL, &m_gUpdate); if (FAILED(hr)) { gBlob->Release(); return false; } vBlob->Release(); gBlob->Release(); return true; }
int setup(void) { GLuint major, minor; GLint success; GLuint model_id; srand( (unsigned)time( NULL ) ); // Make sure required functionality is available! if (!getGLversion( &major, &minor)) return -1; if (major < 2) { printf("<!> OpenGL 2.0 or higher is required\n"); return -1; } windowpos = IsExtSupported("GL_ARB_window_pos"); // Make sure required functionality is available! if (!(IsExtSupported("GL_ARB_vertex_program"))) { printf("<!> ARB vertex program extension not supported\n"); return -1; } if (!(IsExtSupported("GL_ARB_fragment_program"))) { printf("<!> ARB fragment program extension not supported\n"); return -1; } if (!(IsExtSupported("GL_ARB_vertex_shader"))) { printf("<!> ARB vertex shader extension not supported\n"); return -1; } if (!(IsExtSupported("GL_ARB_fragment_shader"))) { printf("<!> ARB fragment shader extension not supported\n"); return -1; } if (!(IsExtSupported("GL_EXT_framebuffer_object"))) { printf("<!> Framebuffer object extension not supported\n"); return -1; } //Define extension prointers glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)glXGetProcAddressARB("glGenFramebuffersEXT"); glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)glXGetProcAddressARB("glBindFramebufferEXT"); glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)glXGetProcAddressARB("glFramebufferTexture2DEXT"); glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)glXGetProcAddressARB("glGenRenderbuffersEXT"); glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)glXGetProcAddressARB("glBindRenderbufferEXT"); glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)glXGetProcAddressARB("glRenderbufferStorageEXT"); glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)glXGetProcAddressARB("glFramebufferRenderbufferEXT"); glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)glXGetProcAddressARB("glDeleteFramebuffersEXT"); glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)glXGetProcAddressARB("glDeleteRenderbuffersEXT"); glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)glXGetProcAddressARB("glCheckFramebufferStatusEXT"); if ( !glGenFramebuffersEXT || !glBindFramebufferEXT || !glFramebufferTexture2DEXT || !glGenRenderbuffersEXT || !glBindRenderbufferEXT || !glRenderbufferStorageEXT || !glFramebufferRenderbufferEXT || !glDeleteFramebuffersEXT || !glDeleteRenderbuffersEXT || !glCheckFramebufferStatusEXT ) { printf("<!> Required extension not supported\n"); return -1; } //Enable smooth shading glShadeModel(GL_SMOOTH); //Enable depth testing glEnable(GL_DEPTH_TEST); glPolygonOffset( scalePoly, biasPoly ); //Enable backface culling glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glFrontFace( GL_CW ); //Background color (Ligth blue) glClearColor(0.0f, 0.4f, 0.8f, 1.0f); //Generate texture objects texture_id = (GLuint *)malloc( NUM_TEXTURES * sizeof(GLuint) ); glGenTextures( NUM_TEXTURES, texture_id ); // Enable Anisotropic filtering (for 2D textures only) if( enable_anisotropic ) { glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &MaxAnisoLevel); if( AnisoLevel > MaxAnisoLevel) AnisoLevel = MaxAnisoLevel; if( print_info ) printf("<-> %.0fX anisotropic filtering enabled\n", AnisoLevel); } else AnisoLevel = 0.0f; // Enable FSAA if (enable_fsaa) glEnable(GL_MULTISAMPLE); //Load MD2 models and textures for (model_id = 0; model_id < NUM_MODELS; ++model_id) { // Load the .md2 model if ( (md2_model[model_id] = (MD2_MODEL_PTR)malloc(sizeof(MD2_MODEL))) == NULL) { printf("<!> Unable to allocate memory for MD2 model in %s\n", filename[3*model_id]); return -1; } if ( !LoadMD2(md2_model[model_id], filename[3*model_id]) ) { printf("<!> Unable to load MD2 model from %s\n", filename[3*model_id]); return -1; } if( print_info ) printf("<-> Loaded MD2 model from \"%s\" for model #%d\n", filename[3*model_id], model_id); // Load texture from disk if ( !LoadImageFromDisk(md2_model[model_id]->skin, filename[3*model_id+1]) ) { printf("<!> Unable to load texture from %s \n", filename[3*model_id+1]); return -1; } if( print_info ) printf("<-> Loaded texture from \"%s\" for model #%d\n", filename[3*model_id+1], model_id); //Set up model texture parameters glBindTexture(GL_TEXTURE_2D, texture_id[2*model_id]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 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, md2_model[model_id]->skin->components, md2_model[model_id]->skin->width, md2_model[model_id]->skin->height, 0, md2_model[model_id]->skin->format, GL_UNSIGNED_BYTE, md2_model[model_id]->skin->data); // Load normal from disk if ( !LoadImageFromDisk(md2_model[model_id]->normal, filename[3*model_id+2]) ) { printf("<!> Unable to load texture from %s \n", filename[3*model_id+2]); return -1; } if( print_info ) printf("<-> Loaded texture from \"%s\" for model #%d\n", filename[3*model_id+2], model_id); //Set up model texture parameters glBindTexture(GL_TEXTURE_2D, texture_id[2*model_id+1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 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, md2_model[model_id]->normal->components, md2_model[model_id]->normal->width, md2_model[model_id]->normal->height, 0, md2_model[model_id]->normal->format, GL_UNSIGNED_BYTE, md2_model[model_id]->normal->data); } // Load floor texture from disk floor_texture = (IMAGE_PTR)malloc(sizeof(IMAGE)); floor_texture->data = NULL; if ( !LoadImageFromDisk(floor_texture, filename[3*NUM_MODELS]) ) { printf("<!> Unable to load texture from %s\n", filename[3*NUM_MODELS]); return -1; } if( print_info ) printf("<-> Loaded texture from \"%s\"\n", filename[3*NUM_MODELS]); //Set up floor texture parameters glBindTexture(GL_TEXTURE_2D, texture_id[NUM_TEXTURES-2]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (enable_anisotropic) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, AnisoLevel); glTexImage2D( GL_TEXTURE_2D, 0, floor_texture->components, floor_texture->width, floor_texture->height, 0, floor_texture->format, GL_UNSIGNED_BYTE, floor_texture->data); if (floor_texture->data) { free(floor_texture->data); floor_texture->data = NULL; } // Load floor normal map from disk floor_texture = (IMAGE_PTR)malloc(sizeof(IMAGE)); floor_texture->data = NULL; if ( !LoadImageFromDisk(floor_texture, filename[3*NUM_MODELS+1]) ) { printf("<!> Unable to load texture from %s\n", filename[3*NUM_MODELS+1]); return -1; } if( print_info ) printf("<-> Loaded texture from \"%s\"\n", filename[3*NUM_MODELS+1]); //Set up floor texture parameters glBindTexture(GL_TEXTURE_2D, texture_id[NUM_TEXTURES-1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (enable_anisotropic) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, AnisoLevel); glTexImage2D( GL_TEXTURE_2D, 0, floor_texture->components, floor_texture->width, floor_texture->height, 0, floor_texture->format, GL_UNSIGNED_BYTE, floor_texture->data); if (floor_texture->data) { free(floor_texture->data); floor_texture->data = NULL; } // Load and compile low-level shaders glGenProgramsARB(NUM_SHADERS, ids); if (!CompileShader(GL_VERTEX_PROGRAM_ARB, ids[0], DATA_DIR "data/shaders/light.vp")) return -1; if (!CompileShader(GL_FRAGMENT_PROGRAM_ARB, ids[1], DATA_DIR "data/shaders/lightMasked.fp")) return -1; // Create program object and compile GLSL shaders progObj = glCreateProgramObjectARB(); if (!CompileGLSLshaders(&progObj, DATA_DIR "data/shaders/bumpTBN_SH_VP.glsl", DATA_DIR "data/shaders/bumpTBN_SH_FP.glsl", GL_FALSE)) return -1; // Retrieve uniform and attributes locations glUseProgramObjectARB(progObj); colorMap = glGetUniformLocationARB(progObj, "colorMap"); bumpMap = glGetUniformLocationARB(progObj, "bumpMap"); shadowMap = glGetUniformLocationARB(progObj, "shadowMap"); tangent = glGetAttribLocation(progObj, "tangent"); binormal = glGetAttribLocation(progObj, "binormal"); for (model_id = 0; model_id < NUM_MODELS; ++model_id) { md2_model[model_id]->tangent = tangent; md2_model[model_id]->binormal = binormal; } // Set texture units glUniform1i( colorMap, 0 ); glUniform1i( bumpMap, 1 ); glUniform1i( shadowMap, 2 ); //Validate shaders glValidateProgramARB(progObj); glGetObjectParameterivARB(progObj, GL_OBJECT_VALIDATE_STATUS_ARB, &success); if (!success) { GLbyte infoLog[MAX_INFO_LOG_SIZE]; glGetInfoLogARB(progObj, MAX_INFO_LOG_SIZE, NULL, (char *)infoLog); printf("<!> Error in program validation\n"); printf("Info log: %s\n", infoLog); return -1; } //Disable GLSL and enable low-level shaders glUseProgramObjectARB(0); glEnable(GL_VERTEX_PROGRAM_ARB); glEnable(GL_FRAGMENT_PROGRAM_ARB); glBindProgramARB(GL_VERTEX_PROGRAM_ARB, ids[0]); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, ids[1]); // Create FrameBuffer if (!CreateFB( shadow_sz, &FBO, &shadow_tx )) return -1; //Prebuild the display lists FList = glGenLists(1); glNewList(FList, GL_COMPILE); DrawGround(); glEndList(); //Init animations and kinematic state md2_model[0]->anim_state = ANIMATION_RUN; md2_model[0]->anim_command = ANIMATION_START; md2_model[0]->delta_rate = 30.f; md2_model[0]->position.x = 85.f; md2_model[0]->position.z = 0.f; md2_model[0]->rotation = 90.f; md2_model[1]->anim_state = ANIMATION_RUN; md2_model[1]->anim_command = ANIMATION_START; md2_model[1]->delta_rate = 30.f; md2_model[1]->position.x = 85.f; md2_model[1]->position.z = 0.f; md2_model[1]->rotation = 90.f; md2_model[2]->anim_state = ANIMATION_STANDING_IDLE; md2_model[2]->anim_command = ANIMATION_START; // Set initial camera position and orientation xCam = 0.0f; yCam = 70.0f; zCam = 200.0f; eCam = -0.35f; aCam = 0.0f; lCam = 0.0f; vCam = 0.0f; dCam = 0.0f; //Set initial light aLit = 0.0f; eLit = 0.75f; // Initialise timer gettimeofday(&tv, NULL); t0 = (double)tv.tv_sec + tv.tv_usec / 1000000.0f; t1 = t0; t2 = t0; return 0; }
SHADER* ProgramShaderCache::SetShader ( DSTALPHA_MODE dstAlphaMode, u32 components ) { SHADERUID uid; GetShaderId(&uid, dstAlphaMode, components); // Check if the shader is already set if (last_entry) { if (uid == last_uid) { GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); last_entry->shader.Bind(); return &last_entry->shader; } } last_uid = uid; // Check if shader is already in cache PCache::iterator iter = pshaders.find(uid); if (iter != pshaders.end()) { PCacheEntry *entry = &iter->second; last_entry = entry; GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); last_entry->shader.Bind(); return &last_entry->shader; } // Make an entry in the table PCacheEntry& newentry = pshaders[uid]; last_entry = &newentry; newentry.in_cache = 0; VertexShaderCode vcode; PixelShaderCode pcode; GenerateVertexShaderCode(vcode, components, API_OPENGL); GeneratePixelShaderCode(pcode, dstAlphaMode, API_OPENGL, components); if (g_ActiveConfig.bEnableShaderDebugging) { newentry.shader.strvprog = vcode.GetBuffer(); newentry.shader.strpprog = pcode.GetBuffer(); } #if defined(_DEBUG) || defined(DEBUGFAST) if (g_ActiveConfig.iLog & CONF_SAVESHADERS) { static int counter = 0; char szTemp[MAX_PATH]; sprintf(szTemp, "%svs_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), counter++); SaveData(szTemp, vcode.GetBuffer()); sprintf(szTemp, "%sps_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), counter++); SaveData(szTemp, pcode.GetBuffer()); } #endif if (!CompileShader(newentry.shader, vcode.GetBuffer(), pcode.GetBuffer())) { GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); return NULL; } INCSTAT(stats.numPixelShadersCreated); SETSTAT(stats.numPixelShadersAlive, pshaders.size()); GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); last_entry->shader.Bind(); return &last_entry->shader; }
// Constructor helper void RenderDevice::initShadersAndStates() { CurRenderTarget = NULL; for(int i = 0; i < Shader_Count; i++) { UniformBuffers[i] = *CreateBuffer(); MaxTextureSet[i] = 0; } ID3D10Blob* vsData = CompileShader("vs_4_0", DirectVertexShaderSrc); VertexShaders[VShader_MV] = *new VertexShader(this, vsData); for(int i = 1; i < VShader_Count; i++) { VertexShaders[i] = *new VertexShader(this, CompileShader("vs_4_0", VShaderSrcs[i])); } for(int i = 0; i < FShader_Count; i++) { PixelShaders[i] = *new PixelShader(this, CompileShader("ps_4_0", FShaderSrcs[i])); } intptr_t bufferSize = vsData->GetBufferSize(); const void* buffer = vsData->GetBufferPointer(); ModelVertexIL = NULL; ID3D11InputLayout** objRef = &ModelVertexIL.GetRawRef(); HRESULT validate = Device->CreateInputLayout(ModelVertexDesc, sizeof(ModelVertexDesc)/sizeof(D3D11_INPUT_ELEMENT_DESC), buffer, bufferSize, objRef); OVR_UNUSED(validate); Ptr<ShaderSet> gouraudShaders = *new ShaderSet(); gouraudShaders->SetShader(VertexShaders[VShader_MVP]); gouraudShaders->SetShader(PixelShaders[FShader_Gouraud]); DefaultFill = *new ShaderFill(gouraudShaders); D3D11_BLEND_DESC bm; memset(&bm, 0, sizeof(bm)); bm.RenderTarget[0].BlendEnable = true; bm.RenderTarget[0].BlendOp = bm.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; bm.RenderTarget[0].SrcBlend = bm.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; bm.RenderTarget[0].DestBlend = bm.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; bm.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; BlendState = NULL; Device->CreateBlendState(&bm, &BlendState.GetRawRef()); D3D11_RASTERIZER_DESC rs; memset(&rs, 0, sizeof(rs)); rs.AntialiasedLineEnable = true; rs.CullMode = D3D11_CULL_BACK; rs.DepthClipEnable = true; rs.FillMode = D3D11_FILL_SOLID; Rasterizer = NULL; Device->CreateRasterizerState(&rs, &Rasterizer.GetRawRef()); QuadVertexBuffer = *CreateBuffer(); const Vertex QuadVertices[] = { Vertex(Vector3f(0, 1, 0)), Vertex(Vector3f(1, 1, 0)), Vertex(Vector3f(0, 0, 0)), Vertex(Vector3f(1, 0, 0)) }; QuadVertexBuffer->Data(Buffer_Vertex, QuadVertices, sizeof(QuadVertices)); SetDepthMode(0, 0); }
void GSDevice11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel) { hash_map<uint32, CComPtr<ID3D11PixelShader> >::const_iterator i = m_ps.find(sel); if(i == m_ps.end()) { string str[21]; str[0] = format("%d", sel.fst); str[1] = format("%d", sel.wms); str[2] = format("%d", sel.wmt); str[3] = format("%d", sel.fmt); str[4] = format("%d", sel.aem); str[5] = format("%d", sel.tfx); str[6] = format("%d", sel.tcc); str[7] = format("%d", sel.atst); str[8] = format("%d", sel.fog); str[9] = format("%d", sel.clr1); str[10] = format("%d", sel.fba); str[11] = format("%d", sel.aout); str[12] = format("%d", sel.ltf); str[13] = format("%d", sel.colclip); str[14] = format("%d", sel.date); str[15] = format("%d", sel.spritehack); str[16] = format("%d", sel.tcoffsethack); str[17] = format("%d", sel.point_sampler); str[18] = format("%d", sel.shuffle); str[19] = format("%d", sel.read_ba); str[20] = format("%d", sel.p4_ultrahack); D3D11_SHADER_MACRO macro[] = { {"PS_FST", str[0].c_str()}, {"PS_WMS", str[1].c_str()}, {"PS_WMT", str[2].c_str()}, {"PS_FMT", str[3].c_str()}, {"PS_AEM", str[4].c_str()}, {"PS_TFX", str[5].c_str()}, {"PS_TCC", str[6].c_str()}, {"PS_ATST", str[7].c_str()}, {"PS_FOG", str[8].c_str()}, {"PS_CLR1", str[9].c_str()}, {"PS_FBA", str[10].c_str()}, {"PS_AOUT", str[11].c_str()}, {"PS_LTF", str[12].c_str()}, {"PS_COLCLIP", str[13].c_str()}, {"PS_DATE", str[14].c_str()}, {"PS_SPRITEHACK", str[15].c_str()}, {"PS_TCOFFSETHACK", str[16].c_str()}, {"PS_POINT_SAMPLER", str[17].c_str()}, {"PS_SHUFFLE", str[18].c_str()}, {"PS_READ_BA", str[19].c_str()}, {"PS_P4_ULTRAHACK", str[20].c_str()}, {NULL, NULL}, }; CComPtr<ID3D11PixelShader> ps; CompileShader(IDR_TFX_FX, "ps_main", macro, &ps); m_ps[sel] = ps; i = m_ps.find(sel); } if(m_ps_cb_cache.Update(cb)) { ID3D11DeviceContext* ctx = m_ctx; ctx->UpdateSubresource(m_ps_cb, 0, NULL, cb, 0, 0); } CComPtr<ID3D11SamplerState> ss0, ss1; if(sel.tfx != 4) { if(!(sel.fmt < 3 && sel.wms < 3 && sel.wmt < 3)) { ssel.ltf = 0; } hash_map<uint32, CComPtr<ID3D11SamplerState> >::const_iterator i = m_ps_ss.find(ssel); if(i != m_ps_ss.end()) { ss0 = i->second; } else { D3D11_SAMPLER_DESC sd, af; memset(&sd, 0, sizeof(sd)); af.Filter = theApp.GetConfig("MaxAnisotropy", 0) && !theApp.GetConfig("paltex", 0) ? D3D11_FILTER_ANISOTROPIC : D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT; sd.Filter = ssel.ltf ? af.Filter : D3D11_FILTER_MIN_MAG_MIP_POINT; sd.AddressU = ssel.tau ? D3D11_TEXTURE_ADDRESS_WRAP : D3D11_TEXTURE_ADDRESS_CLAMP; sd.AddressV = ssel.tav ? D3D11_TEXTURE_ADDRESS_WRAP : D3D11_TEXTURE_ADDRESS_CLAMP; sd.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; sd.MinLOD = -FLT_MAX; sd.MaxLOD = FLT_MAX; sd.MaxAnisotropy = theApp.GetConfig("MaxAnisotropy", 0); sd.ComparisonFunc = D3D11_COMPARISON_NEVER; m_dev->CreateSamplerState(&sd, &ss0); m_ps_ss[ssel] = ss0; } if(sel.fmt >= 3) { ss1 = m_palette_ss; } } PSSetSamplerState(ss0, ss1, sel.date ? m_rt_ss : NULL); PSSetShader(i->second, m_ps_cb); }
int main( int argc , char* args[] ) { /* The window */ SDL_Window* window = NULL; /* The window surface */ SDL_Surface* screen = NULL; /* The event structure */ SDL_Event event; /* The game loop flag */ _Bool running = true; if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) { printf( "SDL2 could not initialize! SDL2_Error: %s\n", SDL_GetError() ); SDL_Quit(); return 1; } SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); window = SDL_CreateWindow( WINDOW_TITLE, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL); if (window == NULL) { printf("unable to create window: %s\n", SDL_GetError()); SDL_Quit(); return 1; } SDL_GLContext maincontext; /* Our opengl context handle */ maincontext = SDL_GL_CreateContext(window); SDL_GL_SetSwapInterval(1); GLint level5Pixels[] = { 0xFF00FFFF, 0xFF00FF00, 0xFFFF0000, 0xFF000000 }; GLint level6Pixels[] = { 0xFFFFFFFF }; GLuint texture = 0; glGenTextures(1, &texture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 5); glTexImage2D(GL_TEXTURE_2D, 5, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, level5Pixels); glTexImage2D(GL_TEXTURE_2D, 6, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, level6Pixels); const GLchar* vshadercode = "#version 330 core\n"\ "layout(location = 0) in vec4 a_position\n;"\ "layout(location = 1) in vec2 a_texcoord\n;"\ "out vec2 v_texcoord\n;"\ "void main(void)\n"\ "{\n"\ " gl_Position = a_position;\n"\ " v_texcoord = a_texcoord;\n"\ "}"; const GLchar* fshadercode = "#version 330 core\n"\ "in vec2 v_texcoord;\n"\ "uniform sampler2D sTexture;\n"\ "out vec4 o_color;\n"\ "void main(){\n"\ " vec2 tc = v_texcoord.xy*0.5 + 0.5;\n"\ " o_color = texture( sTexture, tc );\n"\ "}"; GLuint vshader = glCreateShader(GL_VERTEX_SHADER); GLuint fshader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(vshader, 1, &vshadercode, NULL); glShaderSource(fshader, 1, &fshadercode, NULL); CompileShader(vshader, "Vertex"); CompileShader(fshader, "Fragment"); GLuint program = glCreateProgram(); glAttachShader(program, vshader); glAttachShader(program, fshader); LinkProgram(program, ""); glUseProgram(program); GLuint texLoc = glGetUniformLocation(program, "sTexture"); GLuint matViewProjLoc = glGetUniformLocation(program, "u_matViewProjection"); GLuint posLoc = 0; GLuint texcoordLoc = 1; glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); GLuint vao = 0; glGenVertexArrays(1, &vao); glBindVertexArray(vao); GLuint quadVB = 0; glGenBuffers(1, &quadVB); glBindBuffer(GL_ARRAY_BUFFER, quadVB); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 16, 0); glEnableVertexAttribArray(1); glBindVertexArray(vao); glDepthMask(GL_TRUE); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_ALWAYS); GLuint renderbuffers[2]; glGenRenderbuffers(2, renderbuffers); int num_samples = 1; if (argc > 1) num_samples = atoi(args[1]); printf("Using %u multisample(s)\n", num_samples); if (num_samples > 1) { glBindRenderbuffer(GL_RENDERBUFFER, renderbuffers[0]); glRenderbufferStorageMultisample(GL_RENDERBUFFER, num_samples, GL_RGBA, WINDOW_WIDTH, WINDOW_HEIGHT); glBindRenderbuffer(GL_RENDERBUFFER, renderbuffers[1]); glRenderbufferStorageMultisample(GL_RENDERBUFFER, num_samples, GL_DEPTH_STENCIL, WINDOW_WIDTH, WINDOW_HEIGHT); } else { glBindRenderbuffer(GL_RENDERBUFFER, renderbuffers[0]); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, WINDOW_WIDTH, WINDOW_HEIGHT); glBindRenderbuffer(GL_RENDERBUFFER, renderbuffers[1]); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, WINDOW_WIDTH, WINDOW_HEIGHT); } GLuint fbo; glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffers[0]); glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuffers[1]); GLenum bufs[1]; glDrawBuffers(1, bufs); GLenum status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { fprintf(stderr, "Failed creating FBO!\n"); exit(EXIT_FAILURE); } float f = 0.0f; uint s = 0; while( running ) { while( SDL_PollEvent( &event ) != 0 ) { if( event.type == SDL_QUIT ) { running = false; } } glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); glReadBuffer(GL_BACK); glClearColor( 1.0, 0.0, 0.0, 1.0 ); glClearDepth(f); glClearStencil(s & 0xFF); f += .125f; if (f > 1.0f) f = 0; s += 1; glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); glEnable(GL_STENCIL_TEST); glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); uint i; for (i = 0; i < 512; i++) { glStencilFunc(GL_ALWAYS, i & 0xFF, 0xFF); float nx = ((float)(i) / WINDOW_WIDTH) * 2.0f - 1.0f; float px = ((float)(i + 1) / WINDOW_WIDTH) * 2.0f - 1.0f; const GLfloat quadVerts[] = { nx, 0.8f, 0.33f, 1.0f, px, 0.8f, 0.33f, 1.0f, nx, -0.8f, 0.33f, 1.0f, px, -0.8f, 0.33f, 1.0f, }; glBufferData(GL_ARRAY_BUFFER, sizeof(quadVerts), quadVerts, GL_STATIC_DRAW); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); glReadBuffer(GL_COLOR_ATTACHMENT0); glBlitFramebuffer(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, GL_COLOR_BUFFER_BIT, GL_LINEAR); SDL_GL_SwapWindow(window); } glDeleteRenderbuffers(2, renderbuffers); glDeleteProgram(program); glDeleteShader(vshader); glDeleteShader(fshader); glDeleteTextures(1, &texture); glDeleteBuffers(1, &quadVB); glDeleteVertexArrays(1, &vao); SDL_GL_DeleteContext(maincontext); SDL_DestroyWindow( window ); SDL_Quit(); return 0; }
GLuint LoadShaderProgram(char *filenameVertex, char *filenameFragment) { GLuint program = 0; char *buffer1; char *buffer2; const GLchar *pSource = 0; long length = 0; GLuint vertShader = 0; GLuint fragShader = 0; FILE* file; if (filenameVertex != NULL) { file = fopen(filenameVertex, "r"); if(!file) { fprintf(stderr, "failed to open vert shader file %s\n", filenameVertex); exit(1); } fseek (file , 0 , SEEK_END); length = ftell (file); rewind (file); buffer1= (char*) malloc(sizeof(char)*length); fread(buffer1,1,length,file); fclose (file); pSource = (const GLchar *)(buffer1); vertShader = CompileShader(GL_VERTEX_SHADER, pSource, length); } if (filenameFragment != NULL) { file = fopen(filenameFragment, "r"); if(!file) { fprintf(stderr, "failed to open frag shader file %s\n", filenameFragment); exit(1); } fseek (file , 0 , SEEK_END); length = ftell(file); rewind(file); buffer2= (char*) malloc(sizeof(char)*length); fread(buffer2,1,length,file); fclose (file); pSource = (const GLchar *)(buffer2); fragShader = CompileShader(GL_FRAGMENT_SHADER, pSource, length); } program = linkShaders(vertShader, fragShader); return program; }