1e9297d28Sopenharmony_ci/*
2e9297d28Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3e9297d28Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4e9297d28Sopenharmony_ci * you may not use this file except in compliance with the License.
5e9297d28Sopenharmony_ci * You may obtain a copy of the License at
6e9297d28Sopenharmony_ci *
7e9297d28Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8e9297d28Sopenharmony_ci *
9e9297d28Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10e9297d28Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11e9297d28Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12e9297d28Sopenharmony_ci * See the License for the specific language governing permissions and
13e9297d28Sopenharmony_ci * limitations under the License.
14e9297d28Sopenharmony_ci */
15e9297d28Sopenharmony_ci
16e9297d28Sopenharmony_ci#include "ec_log.h"
17e9297d28Sopenharmony_ci#include "program.h"
18e9297d28Sopenharmony_ci
19e9297d28Sopenharmony_cinamespace OHOS {
20e9297d28Sopenharmony_cinamespace Rosen {
21e9297d28Sopenharmony_civoid Program::Compile(const std::string& vertexShader, const std::string& fragmentShader)
22e9297d28Sopenharmony_ci{
23e9297d28Sopenharmony_ci    vertexID_ = CreateShader(GL_VERTEX_SHADER, vertexShader);
24e9297d28Sopenharmony_ci    fragmentID_ = CreateShader(GL_FRAGMENT_SHADER, fragmentShader);
25e9297d28Sopenharmony_ci    if (!initFlag_) {
26e9297d28Sopenharmony_ci        initFlag_ = true;
27e9297d28Sopenharmony_ci        programID_ = glCreateProgram();
28e9297d28Sopenharmony_ci    }
29e9297d28Sopenharmony_ci    glAttachShader(programID_, vertexID_);
30e9297d28Sopenharmony_ci    glAttachShader(programID_, fragmentID_);
31e9297d28Sopenharmony_ci    glLinkProgram(programID_);
32e9297d28Sopenharmony_ci    CheckProgramLinkErrors(programID_);
33e9297d28Sopenharmony_ci    glDeleteShader(vertexID_);
34e9297d28Sopenharmony_ci    glDeleteShader(fragmentID_);
35e9297d28Sopenharmony_ci}
36e9297d28Sopenharmony_ci
37e9297d28Sopenharmony_civoid Program::UseProgram() const
38e9297d28Sopenharmony_ci{
39e9297d28Sopenharmony_ci    glUseProgram(programID_);
40e9297d28Sopenharmony_ci}
41e9297d28Sopenharmony_ci
42e9297d28Sopenharmony_ciGLuint Program::CreateShader(GLuint type, const std::string& shaderCode)
43e9297d28Sopenharmony_ci{
44e9297d28Sopenharmony_ci    const GLchar* charShaderCode = static_cast<const GLchar*>(shaderCode.c_str());
45e9297d28Sopenharmony_ci    GLuint shader = glCreateShader(type);
46e9297d28Sopenharmony_ci    glShaderSource(shader, 1, &charShaderCode, nullptr);
47e9297d28Sopenharmony_ci    glCompileShader(shader);
48e9297d28Sopenharmony_ci    if (type == GL_VERTEX_SHADER) {
49e9297d28Sopenharmony_ci        CheckShaderCompileErrors(shader, "vertex");
50e9297d28Sopenharmony_ci    } else if (type == GL_FRAGMENT_SHADER) {
51e9297d28Sopenharmony_ci        CheckShaderCompileErrors(shader, "fragment");
52e9297d28Sopenharmony_ci    }
53e9297d28Sopenharmony_ci    return shader;
54e9297d28Sopenharmony_ci}
55e9297d28Sopenharmony_ci
56e9297d28Sopenharmony_civoid Program::CheckShaderCompileErrors(GLuint shader, const std::string& type)
57e9297d28Sopenharmony_ci{
58e9297d28Sopenharmony_ci    GLint complete = 0;
59e9297d28Sopenharmony_ci    GLchar infoLog[INFO_LOG_LENGTH];
60e9297d28Sopenharmony_ci    glGetShaderiv(shader, GL_COMPILE_STATUS, &complete);
61e9297d28Sopenharmony_ci    if (!complete) {
62e9297d28Sopenharmony_ci        glGetShaderInfoLog(shader, INFO_LOG_LENGTH, nullptr, infoLog);
63e9297d28Sopenharmony_ci        LOGE("Shader compile error of type: %{public}s, errorInfo: %{public}s", type.c_str(), infoLog);
64e9297d28Sopenharmony_ci    }
65e9297d28Sopenharmony_ci}
66e9297d28Sopenharmony_ci
67e9297d28Sopenharmony_civoid Program::CheckProgramLinkErrors(GLuint program)
68e9297d28Sopenharmony_ci{
69e9297d28Sopenharmony_ci    GLint complete = 0;
70e9297d28Sopenharmony_ci    GLchar infoLog[INFO_LOG_LENGTH];
71e9297d28Sopenharmony_ci    glGetProgramiv(program, GL_LINK_STATUS, &complete);
72e9297d28Sopenharmony_ci    if (!complete) {
73e9297d28Sopenharmony_ci        glGetProgramInfoLog(program, INFO_LOG_LENGTH, nullptr, infoLog);
74e9297d28Sopenharmony_ci        LOGE("Program linking error: %{public}s", infoLog);
75e9297d28Sopenharmony_ci    }
76e9297d28Sopenharmony_ci}
77e9297d28Sopenharmony_ci} // namespcae Rosen
78e9297d28Sopenharmony_ci} // namespace OHOS