簡體   English   中英

OpenGL中非常奇怪的頂點着色器行為

[英]Very Strange Vertex Shader Behavior in OpenGL

好的,我有這個程序。 (未顯示所有代碼),基本上可以繪制出一個球形,但是當我嘗試將統一變量傳遞給頂點着色器時,問題就來了。 我只有3個文件。 Sphere.cpp,Sphere.h,main.cpp和“頂點/片段着色器” ofc。

我的代碼如下:

首先,我進行所有必要的計算,並將點存儲到頂點數組中。 然后我將其稱為(在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 );

}

第三,我調用了一個“ while”循環(在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 );
    }

而已!

現在問題出在以下幾行中(在Sphere.cpp中):

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

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

而且我的頂點着色器就是這個簡單的着色器:

#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 ; 


}

另一個奇怪的部分是,如果將我的所有代碼移動到單個文件中,動畫效果會很好。 但是,當我將代碼保存在單獨的文件中時,似乎無法向頂點數據“傳遞統一變量”,因此,我得到的球體沒有移動。 我以錯誤的順序加載了東西嗎?

答:不管具體問題如何,我都想知道為什么您不基於模型矩陣移動對象,而是基於d_pos統一對象來移動對象。 這似乎是無用的“每個頂點”操作,因為計算需要“每個頂點”進行評估:

vec4(in_Position + d_pos,1.0);

如果要改為使用模型矩陣執行移動操作,則計算將僅執行一次(在模型矩陣更改級別)。

B-我建議您檢查此操作的輸出並檢查輸出

glGetUniformLocation(sphere_shaderprogram,“ d_pos”)

C-檢查glLinkProgram的輸出以查看在編譯階段是否一切順利

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM