2013-12-06 3 views
0

Я хотел бы выполнить операцию на пиксель для каждого экземпляра сетки. Я нашел переменную gl_FragCoord, но кажется, что это координаты SCREEN. Я хотел бы иметь доступ к ЛОКАЛЬНЫМ координатам, чтобы я мог вносить изменения, которые влияли бы на каждую сетку независимо. Я хотел бы иметь координаты, где, например, координаты (0.0, 0.0) являются верхним левым углом фрагмента и (1.0, 1.0) являются нижними правыми.Координаты в вершинных/фрагментарных шейдерах

+0

Каноническая матрица проекции в OpenGL будет производить (0.0, 0.0) в нижнем левом углу. Если вы хотите, чтобы это было левым верхним, вам нужно перевернуть ось Y, но имейте в виду, что это изменит вашу направленность вашей проекции, и вам нужно будет делать другие вещи, например, компенсировать заказы на намотку и т. Д. –

ответ

1

Вы можете передать в иллюминатор как форма и разделить фраг Корд X на видовых экранах W и Y осколочного коорда по видовому экрану H

+0

Я попробовал но это не сработало, как я ожидал. –

+0

Помните, что координаты OpenGL расположены снизу вверх. Итак, (0.0, 0.0) - нижний левый угол. –

0

Используйте barycentric coordinates и дополнительный атрибут вершины построить треугольник локальной системы координат :

#include <GL/glew.h> 
#include <GL/freeglut.h> 
#include <iostream> 
#include <vector> 
using namespace std; 

#include <glm/glm.hpp> 
#include <glm/gtc/type_ptr.hpp> 
#include <glm/gtx/transform.hpp> 
using namespace glm; 

void CheckStatus(GLuint obj) 
{ 
    GLint status = GL_FALSE; 
    if(glIsShader(obj)) glGetShaderiv(obj, GL_COMPILE_STATUS, &status); 
    if(glIsProgram(obj)) glGetProgramiv(obj, GL_LINK_STATUS, &status); 
    if(status == GL_TRUE) return; 
    GLchar log[ 1 << 16 ] = { 0 }; 
    if(glIsShader(obj)) glGetShaderInfoLog(obj, sizeof(log), NULL, log); 
    if(glIsProgram(obj)) glGetProgramInfoLog(obj, sizeof(log), NULL, log); 
    std::cerr << log << std::endl; 
    exit(-1); 
} 

void AttachShader(GLuint program, GLenum type, const char* src) 
{ 
    GLuint shader = glCreateShader(type); 
    glShaderSource(shader, 1, &src, NULL); 
    glCompileShader(shader); 
    CheckStatus(shader); 
    glAttachShader(program, shader); 
    glDeleteShader(shader); 
} 

GLuint LoadProgram(const char* vert, const char* geom, const char* frag) 
{ 
    GLuint prog = glCreateProgram(); 
    if(vert) AttachShader(prog, GL_VERTEX_SHADER, vert); 
    if(geom) AttachShader(prog, GL_GEOMETRY_SHADER, geom); 
    if(frag) AttachShader(prog, GL_FRAGMENT_SHADER, frag); 
    glLinkProgram(prog); 
    CheckStatus(prog); 
    return prog; 
} 

#define GLSL(version, shader) "#version " #version "\n" #shader 

const char* vert = GLSL 
(
    120, 
    uniform mat4 u_projection; 
    uniform mat4 u_modelview; 

    attribute vec3 a_pos; 
    attribute vec3 a_bc; 

    varying vec3 v_bc; 

    void main() 
    { 
     v_bc = a_bc; 
     gl_Position = u_projection * u_modelview * vec4(a_pos, 1.0); 
    } 
); 

const char* frag = GLSL 
(
    120, 
    varying vec3 v_bc; 
    void main() 
    { 
     gl_FragColor = vec4(v_bc, 1.0); 
    } 
); 

struct Vertex 
{ 
    Vertex(const vec3& pos, const vec3& bc) 
     : pos(pos) 
     , bc(bc) 
    {} 
    vec3 pos; 
    vec3 bc; 
}; 

void AddTriangle(const vec3& p1, const vec3& p2, const vec3& p3, vector<Vertex>& verts) 
{ 
    verts.push_back(Vertex(p1, vec3(1, 0, 0))); 
    verts.push_back(Vertex(p2, vec3(0, 1, 0))); 
    verts.push_back(Vertex(p3, vec3(0, 0, 1))); 
} 

void display() 
{ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    double w = glutGet(GLUT_WINDOW_WIDTH); 
    double h = glutGet(GLUT_WINDOW_HEIGHT); 
    double ar = w/h; 
    mat4 projection = glm::ortho<float>(-2 * ar, 2 * ar, -2.0, 2.0, -1.0, 1.0); 

    mat4 modelview = mat4(1.0); 

    // prepare to render 
    static GLuint prog = LoadProgram(vert, NULL, frag); 
    glUseProgram(prog); 

    GLint proj = glGetUniformLocation(prog, "u_projection"); 
    glUniformMatrix4fv(proj, 1, GL_FALSE, glm::value_ptr(projection)); 

    GLint model = glGetUniformLocation(prog, "u_modelview"); 
    glUniformMatrix4fv(model, 1, GL_FALSE, glm::value_ptr(modelview)); 

    vector<Vertex> verts; 
    AddTriangle 
     (
     vec3(0, 0, 0), 
     vec3(1, 0, 0), 
     vec3(1, 1, 0), 
     verts 
     ); 

    GLint pos = glGetAttribLocation(prog, "a_pos"); 
    glVertexAttribPointer(pos, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), &verts[0].pos); 
    glEnableVertexAttribArray(pos); 

    GLint bc = glGetAttribLocation(prog, "a_bc"); 
    glVertexAttribPointer(bc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), &verts[0].bc); 
    glEnableVertexAttribArray(bc); 

    glDrawArrays(GL_TRIANGLES, 0, verts.size()); 

    glutSwapBuffers(); 
} 

int main(int argc, char **argv) 
{ 
    glutInit(&argc, argv); 
    glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS); 
    glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); 
    glutInitWindowSize(600, 600); 
    glutCreateWindow("GLUT"); 
    glewInit(); 

    glutDisplayFunc(display); 
    glutMainLoop(); 
    return 0; 
} 

Если v_bc == (1,0,0) тогда ваш фрагмент находится на первой вершине.

Если v_bc == (0,1,0), то ваш фрагмент находится на второй вершине.

Если v_bc == (0,0,1), то ваш фрагмент находится на третьей вершине.

0

Спасибо за вашу поддержку и идеи, мне было нужно передать ЛОКАЛЬНОЕ положение вершины через вершинный шейдер в шейдер фрагмента. Мы можем сделать это без каких-либо дополнительных вычислений, поскольку это значение, которое известно вершинному шейдеру. У меня все еще нет того, что я хотел вначале, но теперь я знаю больше о том, как я могу использовать шейдер фрагмента для выполнения необходимых эффектов :).

+0

Чтобы быть понятным, по позиции 'LOCAL', вы имеете в виду объектное пространство? Это координатное пространство, в котором вершины находятся перед любым преобразованием. Обычно роль вершинного шейдера заключается в преобразовании из пространства-объекта в пространство-клип ... сразу же после этого происходит другой набор преобразований, переводящих эти координаты в нормализованное пространство устройства и, наконец, оконное пространство. ЛОКАЛЬНАЯ позиция вовсе не описательна, когда вы понимаете, как работают преобразования координат в конвейере рендеринга. –

+0

Да, в ЛОКАЛЬНОМ положении я имел в виду объект-пространство. То, что я действительно хотел, было иметь доступ к каждому пикселю текстуры/текселя объекта. –

Смежные вопросы