0

ティーポットを描いて照明を当てるC++プログラムを作成しました。それ自体は単純ですが、シェーダーも使用しています。シンプルGLSLは初めてです。シンプルなフラグメントシェーダーを試しましたが、画面出力がわかりません。

このファイルでは、initメソッドでglewを初期化し、頂点シェーダーとフラグメントシェーダーもコンパイルします。それらは「vertex_shader」ファイルと「fragment_shader」ファイルにあります。

あなたが認識できないかもしれないのは、光と物質です。これらは、ライトに関するすべての情報を含む構造体にすぎません。私はこれらの構造体をテストしたので、期待どおりに機能すると確信しています。Material = BlackPlasticを宣言するときは、defineディレクティブで定義されたデフォルト値に設定するだけです。問題があると思われる場合は、このコードを投稿することもできます。

#include <GL/glew.h>
#include <GL/glut.h>
#include <iostream>
#include <fstream>
#include <vector>
#include "utility.hpp"

#define MAX_DIM 1000

GLfloat width=600, height=800;
GLuint vertex_shader, fragment_shader;
GLuint program;
const char* vertex_shader_filename= "vertex_shader";
const char* fragment_shader_filename= "fragment_shader";
Light light;
Material material;

void init()
{    
    // Inizializzazione di GLEW
    glewInit();
    if(GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader)
    {
    cout << "Supporto GLSL" << endl;
    }

    // Lettura e compilazione del vertex shader
    GLchar* buffer= new GLchar[MAX_DIM];
    ifstream stream;
    streamsize count;
    stream.open(vertex_shader_filename);
    stream.read(buffer,MAX_DIM);
    count= stream.gcount();
    stream.close();
    vertex_shader= glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex_shader, 1, (const GLchar**)&buffer, &count);
    glCompileShader(vertex_shader);

    // Lettura, inizializzazione ed esecuzione del fragment shader
    stream.open(fragment_shader_filename);
    stream.read(buffer,MAX_DIM);
    count= stream.gcount();
    stream.close();
    fragment_shader= glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment_shader, 1, (const GLchar**)&buffer, &count);
    glCompileShader(fragment_shader);
    delete[] buffer;

    // Creazione del programma

    program= glCreateProgram();
    glAttachShader(program, vertex_shader);
    glAttachShader(program, fragment_shader);
    glLinkProgram(program);
    glUseProgram(program);

    // Inizializzazione materiale e luce
    material= BlackPlastic;
    light= {vector<GLfloat>{-2,2,2,1} ,vector<GLfloat>{1,1,1,1},vector<GLfloat>{1,1,1,1},vector<GLfloat>{1,1,1,1} };
}

void display()
{
    glEnable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45,width/height,1,1000);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0,0,-100,0,0,0,0,1,0);

    // Illuminazione
    glShadeModel(GL_SMOOTH);
    material.apply(); // This just causes glMaterialfv to be called for the ambient, diffuse, specular and shininess values.
    light.apply(); // This just causes glLightfv to be called for the ambient, diffuse and specular values
    glEnable(GL_LIGHT0);
    glEnable(GL_LIGHTING);

    // Rendering
    glClearColor(0.8,0.8,0.8,1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glutSolidTeapot(10);
    glutSwapBuffers();
}

void reshape(int w, int h)
{
    width=w;
    height=h;
    glutPostRedisplay();
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowPosition(100,100);
    glutInitWindowSize(500,500);
    glutCreateWindow("test");
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    init();
    glutMainLoop();
    return 0;
}

頂点シェーダーが問題を引き起こしているとは思いません。色を割り当てて位置を正しく計算するだけです。また、フラグメントシェーダーは明らかに正しいです。これは、実行される唯一の命令です。

gl_FragColor = gl_Color;

これを行うと、白いティーポットが表示されます。代わりに、この値を任意の色に変更した場合:

gl_FragColor = vec4{0,0,1,1};

私は正しい色のティーポットを手に入れました:黒いプラスチック。理由はわかりません。ここでは照明を適用していません。計算する必要があります。

シェーダーを適用せずに同じプログラムを実行したことを感謝し、ティーポットの色を適切に設定しました。

4

1 に答える 1

2

まず最初に、固定機能パイプラインを「新しいもの」と混合します。バックグラウンドで何が起こっているのか本当にわからないため、多くの問題が発生する可能性があるため、これは本当に悪い習慣です。

ディフューズシェーダーを使用した実際の照明が必要な場合は、自分でディフューズカラーを計算する必要があります。ずっと前に、前回ffpを使用したので、それを使用するシェーダーをいくつか検索しました。

頂点シェーダー

varying vec3 normal;
varying vec3 v;
varying vec3 lightvec;
void main(void)
{
    normal      = normalize(gl_NormalMatrix * gl_Normal);
    v           = vec3(gl_ModelViewMatrix * gl_Vertex);
    lightvec    = normalize(gl_LightSource[0].position.xyz - v);
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

フラグメントシェーダー

varying vec3 normal;
varying vec3 v;
varying vec3 lightvec;

void main(void)
{
   vec3 Eye          = normalize(-v);
   vec3 Reflected    = normalize( reflect( -lightvec, normal )); 
   vec4 IAmbient     = gl_LightSource[0].ambient * gl_FrontMaterial.ambient;
   vec4 IDiffuse     = gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * max(dot(normal, lightvec), 0.0);
   vec4 ISpecular    = gl_LightSource[0].specular * gl_FrontMaterial.specular * pow(max(dot(Reflected, Eye), 0.0), gl_FrontMaterial.shininess);
   gl_FragColor      = gl_FrontLightModelProduct.sceneColor + IAmbient + IDiffuse + ISpecular;
}
于 2013-01-28T23:44:51.080 に答える