私はこのプログラムを持っています。 (すべてのコードが表示されているわけではありません)、基本的に球体を描画しますが、問題は頂点シェーダに一様な変数を渡そうとしているときです。 私が持っているのは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で)これらの行にあります単一のファイル内の私のコード、アニメーションは正常に動作します。しかし、コードを別々のファイルに保存すると、頂点データへの「一貫変数の受け渡し」が機能しないように見えます。その結果、移動しない球が得られます。 私は間違った順序で何かをロードしていますか?
問題が何か言及するのを忘れました。 –
私は今質問を編集しました –
これは、他のユニフォーム(行列)が正しく渡されることを意味します(球の頂点が正しく投影されるようになります)が、 'd_pos'ではなくなりますか?単純に色を 'd_pos'にするシェーダをスタブすることはできますか(もちろん、範囲[0,1]に適切に変換されます)? –