고정 기능 OpenGL에서 원하는 기능을 수행 할 수 없습니다.
당신이 할 수있는 베스트 색상 속성 정보를 귀하의 운동 학적 상태를 분할 중복입니다 :
class Vertex {
public:
CD_FLOAT3 pos;
CD_FLOAT3 color;
};
class State {
public:
CD_FLOAT3 direction;
CD_FLOAT velocity;
};
const unsigned int NumTris = ...;
std::vector<State> states(NumTris);
std::vector<Vertex> verts(NumTris * 3);
PopulateAndBindVBO();
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), 0);
glColorPointer(3, GL_FLOAT, sizeof(Vertex), sizeof(CD_FLOAT3));
glDrawArrays(GL_TRIANGLES, 0, NumTris);
당신 하지만 삼각형에 당신의 Triangle
구조체의 배열을 분할하는 지오메트리 쉐이더를 사용할 수 있습니다
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <iostream>
#include <vector>
#include <cstddef>
using namespace std;
#include <glm/glm.hpp>
using namespace glm;
struct Program
{
static GLuint Load(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;
}
private:
static 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 << 15 ] = { 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);
}
static 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);
}
};
#define GLSL(version, shader) "#version " #version "\n" #shader
struct Triangle
{
glm::vec3 a;
glm::vec3 b;
glm::vec3 c;
glm::vec3 color;
glm::vec3 direction;
GLfloat velocity;
};
const char* vert = GLSL
(
330 core,
layout (location = 0) in vec3 A;
layout (location = 1) in vec3 B;
layout (location = 2) in vec3 C;
layout (location = 3) in vec3 Color;
out VertToGeom
{
vec3 A;
vec3 B;
vec3 C;
vec3 Color;
} outData;
void main()
{
outData.A = A;
outData.B = B;
outData.C = C;
outData.Color = Color;
}
);
const char* geom = GLSL
(
330 core,
in VertToGeom
{
vec3 A;
vec3 B;
vec3 C;
vec3 Color;
} inData[];
out GeomToFrag
{
vec3 Color;
} outData;
layout (points) in;
layout (triangle_strip, max_vertices = 3) out;
void main()
{
gl_Position.xyz = inData[ 0 ].A;
outData.Color = inData[ 0 ].Color;
EmitVertex();
gl_Position.xyz = inData[ 0 ].B;
outData.Color = inData[ 0 ].Color;
EmitVertex();
gl_Position.xyz = inData[ 0 ].C;
outData.Color = inData[ 0 ].Color;
EmitVertex();
EndPrimitive();
}
);
const char* frag = GLSL
(
330 core,
in GeomToFrag
{
vec3 Color;
} inData;
void main()
{
gl_FragColor = vec4(inData.Color, 1.0);
}
);
GLuint vbo = 0;
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
static GLuint prog = Program::Load(vert, geom, frag);
glUseProgram(prog);
vector<Triangle> tris(2);
tris[0].a = glm::vec3(0, 0, 0);
tris[0].b = glm::vec3(1, 0, 0);
tris[0].c = glm::vec3(1, 1, 0);
tris[0].color = glm::vec3(1, 0, 0);
tris[1].a = glm::vec3(0, 0, 0);
tris[1].b = glm::vec3(-1, 0, 0);
tris[1].c = glm::vec3(-1, -1, 0);
tris[1].color = glm::vec3(0, 1, 0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(Triangle) * tris.size(), &tris[0], GL_STREAM_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Triangle), (void*)(sizeof(glm::vec3) * 0));
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Triangle), (void*)(sizeof(glm::vec3) * 1));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Triangle), (void*)(sizeof(glm::vec3) * 2));
glEnableVertexAttribArray(2);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Triangle), (void*)(sizeof(glm::vec3) * 3));
glEnableVertexAttribArray(3);
glDrawArrays(GL_POINTS, 0, tris.size());
glutSwapBuffers();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
glutInitContextVersion(3, 3);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(600, 600);
glutCreateWindow("GLUT");
glewExperimental = GL_TRUE;
glewInit();
GLuint vao = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &vbo);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
가 왜 데이터가 당신이 클럽의 다른 데이터 쉐이더에 공급합니까? GPU에 불필요한 데이터를 업로드 한 다음 건너 뛸 것을 요청하면 작동하도록 만들 수 있지만 실제로는 권장되지 않습니다. 당신이 절대적으로 필요로하는 것을 업로드하십시오. 내가 당신을 올바르게 이해한다면 렌더링 된 삼각형마다 '삼각형'전체를 올리겠습니까? – legends2k
왜'glVertexPointer() '를 세 번 호출하고 있니? 'glDrawArrays()'의 마지막 호출 만 효과가 있습니다. – genpfault
@ legends2k 쉐이더에 데이터를 보내는 것이 유용하지는 않지만 지금은 걱정하지 않는다는 것을 알고 있습니다. 어떻게 내가 afterhother 세 번 전화를 지정할 수 있습니다, 또 다른 그램 전화가 무엇입니까? – Darwly