2012-01-10 22 views
0

私はこのプログラムを持っています。 (すべてのコードが表示されているわけではありません)、基本的に球体を描画しますが、問題は頂点シェーダに一様な変数を渡そうとしているときです。 私が持っているのは3つのファイルです。 Sphere.cpp、Sphere.h、main.cpp、およびVertex/Fragment Shaders ofcが含まれます。私はすべての必要な計算を行うすべてのOpenGLで非常に奇妙な頂点シェーダの動作

まず頂点の配列にポイントを保存:

は、ここに私のコードはどのようになるのです。 は、それから私は(main.cppにして)これを呼び出す:

void SetupGemetry() { 

    //Allocate 5 VBOs 
    glGenBuffers(5, vbo); 

    } 

かなりストレートフォワードです。私は(main.cppにして)これを呼び出す

第二:

Sphere *planet_1 = new Sphere(sphere_start ,sphere_end); 

再びかなりストレートフォワードです。 すべての球コードは、(Sphere.cpp内の)別のファイルにあります。 ここにある:

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <stddef.h> 
#include <GL/glew.h> 
#include <GL/glfw.h> 
#include <glm/glm.hpp> 
#include <glm/gtc/matrix_transform.hpp> 
#include <glm/gtc/type_ptr.hpp> 
#include <stdlib.h> 
#include <vector> 
#include <iostream> 

#include "Sphere.h" 

int start_sphere, end_sphere; 

//these will contain the vertex and shader contents 
GLchar *sphere_vertexsource, *sphere_fragmentsource; 
//this will be used to access the shaders 
GLuint sphere_vertexshader, sphere_fragmentshader; 
//declaring a shader program 
GLuint sphere_shaderprogram; 

Sphere::Sphere (int a, int b) 
{ 
    start_sphere = a; 
    end_sphere = b; 
    SetupShaders_sphere(); 
} 

//reading hte files (shaders)! 
char* Sphere::filetobuf_sphere(char *file) 
{ 
    FILE *fptr; 
    long length; 
    char *buf; 

    fptr = fopen(file, "r"); /* Open file for reading */ 
     if (!fptr) /* Return NULL on failure */ 
     return NULL; 
    fseek(fptr, 0, SEEK_END); /* Seek to the end_sphere of the file */ 
    length = ftell(fptr); /* Find out how many bytes into the file we are */ 
    buf = (char*)malloc(length + 1); /* Allocate a buffer for the entire length of the file plus a null terminator */ 
    fseek(fptr, 0, SEEK_SET); /* Go back to the beginning of the file */ 
    fread(buf, length, 1, fptr); /* Read the contents of the file in to the buffer */ 
    fclose(fptr); /* Close the file */ 
    buf[length] = 0; /* Null terminator */ 
    return buf; /* Return the buffer */ 
} 

void Sphere::SetupShaders_sphere(void){ 

    // Read our shaders into the appropriate buffers 
    sphere_vertexsource = filetobuf_sphere("vertex_shader_sphere.vert"); 
    sphere_fragmentsource = filetobuf_sphere("fragment_shader_sphere.frag"); 

    //Assign our handles a "name" to new shader objects 
    sphere_vertexshader = glCreateShader(GL_VERTEX_SHADER); 
    sphere_fragmentshader = glCreateShader(GL_FRAGMENT_SHADER); 

    // Associate the source code buffers with each handle 
    glShaderSource(sphere_vertexshader, 1, (const GLchar**)&sphere_vertexsource, 0); 
    glShaderSource(sphere_fragmentshader, 1, (const GLchar**)&sphere_fragmentsource, 0); 

    //Setting them up by compiling, attaching and linking them! 
    glCompileShader(sphere_vertexshader); 
    glCompileShader(sphere_fragmentshader); 

    sphere_shaderprogram = glCreateProgram(); 
    glAttachShader(sphere_shaderprogram, sphere_vertexshader); 
    glAttachShader(sphere_shaderprogram, sphere_fragmentshader); 

    glBindAttribLocation(sphere_shaderprogram, 0, "in_Position"); 
    glBindAttribLocation(sphere_shaderprogram, 1, "in_Color"); 
    glBindAttribLocation(sphere_shaderprogram, 2, "in_vertexUV"); 

    glLinkProgram(sphere_shaderprogram); 
    glUseProgram(sphere_shaderprogram); 

    printf("Sphere Shaders Loaded!\n"); 

} 

void Sphere::render_sphere(int i, glm::vec3 center) 
{ 

    int position_factor; 
    GLfloat angle; 
    const double PI = 3.1415926535897; 
    GLfloat time, theta_angle, r, x_cord, z_cord, radius; 
    GLfloat period = 600; 

    angle = (GLfloat) (i/40 % 360); 
    time = (GLfloat) (i%600); 
    r= 1.5; 
    theta_angle = (2*PI*time)/period; 

    //PROJECTION 
    glm::mat4 Projection = glm::perspective(45.0f, 1.0f, 0.1f, 100.0f); 

    //VIEW 
    glm::mat4 View = glm::mat4(1.); 

    View = glm::translate(View, center); // x, y, z position ? 

    //View = glm::rotate(View, angle * -1.0f, glm::vec3(1.f, 0.f, 0.f)); 
    View = glm::rotate(View, angle * 0.5f, glm::vec3(0.f, 1.f, 0.f)); 
    //View = glm::rotate(View, angle * 0.5f, glm::vec3(0.f, 0.f, 1.f)); 

    //MODEL 
    // for scaling down to 0.5 >> glm::scale(glm::mat4(1.0f),glm::vec3(0.5f)); 
    // original >> glm::mat4(1.0); 
    glm::mat4 Model = glm::scale(glm::mat4(1.0f),glm::vec3(0.3f)); 

    //Rotation Calculations 
    if(theta_angle <= 2*PI || theta_angle >= 0) 
    { 
     x_cord = radius*cos(theta_angle); 
     z_cord = radius*sin(theta_angle); 

    } 

    glm::vec3 Position_test = glm::vec3(x_cord, 0.f, z_cord); 

    glUniform3fv(glGetUniformLocation(sphere_shaderprogram, "d_pos"), 1, glm::value_ptr(Position_test)); 

    glm::mat4 MVP = Projection * View * Model; 
    glUniformMatrix4fv(glGetUniformLocation(sphere_shaderprogram, "MVP_matrix"), 1, GL_FALSE, glm::value_ptr(MVP)); 

    //Transfer additional information to the vertex shader 
    //glm::mat4 MV = Model * View; 
    //glUniformMatrix4fv(glGetUniformLocation(sphere_shaderprogram, "MV_matrix"), 1, GL_FALSE, glm::value_ptr(MV)); 

    glClearColor(0.0, 0.0, 0.0, 1.0); 

    glDrawArrays(GL_LINE_STRIP, start_sphere, end_sphere); 

} 

第三に、私は私が(main.cppにして)を呼び出し、 "しばらく" のループがあります。

while(running) 
    { 

      //glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

       setBuffer(0,no_sphere_vertices, sphere_vertices); 
       planet_1->render_sphere(k, planet_1_center); 

      k++; 
      glfwSwapBuffers(); 
      running = !(glfwGetKey(GLFW_KEY_ESC) | glfwGetKey('Q') | glfwGetKey('q')) && glfwGetWindowParam(GLFW_OPENED); 
    } 

それです!

#version 330 
precision highp float; 

//setting the in coming variables! 
layout(location = 0) in vec3 in_Position; //declare position 
layout(location = 1) in vec3 in_Color; 
layout(location = 2) in vec3 in_vertexUV; 

//Variables 
uniform mat4 MVP_matrix; //Model View Projection Matrix 
uniform vec3 d_pos; // the position difference 

vec3 const_color; //a blue constant color declared below 

out vec3 ex_Color; 


void main(void) { 


     gl_Position = MVP_matrix * vec4(in_Position+d_pos, 1.0); 
     const_color = in_Color; 
     ex_Color = const_color ; 


} 

もう一つの奇妙な部分は、その移動した場合はALLです:

glm::vec3 Position_test = glm::vec3(x_cord, 0.f, z_cord); 

    glUniform3fv(glGetUniformLocation(sphere_shaderprogram, "d_pos"), 1, glm::value_ptr(Position_test)); 

そしてところで、私のバーテックスシェーダは、この簡単なものである:

は、今の問題は、(Sphere.cppで)これらの行にあります単一のファイル内の私のコード、アニメーションは正常に動作します。しかし、コードを別々のファイルに保存すると、頂点データへの「一貫変数の受け渡し」が機能しないように見えます。その結果、移動しない球が得られます。 私は間違った順序で何かをロードしていますか?

+0

問題が何か言及するのを忘れました。 –

+0

私は今質問を編集しました –

+0

これは、他のユニフォーム(行列)が正しく渡されることを意味します(球の頂点が正しく投影されるようになります)が、 'd_pos'ではなくなりますか?単純に色を 'd_pos'にするシェーダをスタブすることはできますか(もちろん、範囲[0,1]に適切に変換されます)? –

答えて

0

A - 特定の問題にかかわらず、私はあなたがモデルマトリックスに基づいてオブジェクトを移動させない理由と、d_posユニフォームに基づいてそれを行うのだろうと思います。計算が「頂点ごとに」評価される必要があるため、無駄な「頂点ごとの」演算になります。

vec4(in_Position + d_pos、1.0);

代わりにモデル行列を使用して移動操作を実行すると、計算はモデル行列変更レベルで1回だけ実行されます。

B-私はあなたがglGetUniformLocation(sphere_shaderprogram、「d_pos」)

はすべてがうまくいったかどうかを確認するためにglLinkProgramの出力を確認C-この操作の出力をチェックし、出力に

をチェックお勧めしますコンパイルフェーズで

関連する問題