我意识到我没有使用Glu,也没有设置透视图,但我使用的是与McKeeson使用http://www.arcsynthesis.org/gltut/相同的标准化设备坐标,所以我应该看到他获得的相同三角形,只有红色。我得到一个黑屏并且没有警告(我希望他们留下glDraw功能进行调试; GL3就像飞行盲目,直到你走出烟雾!)。图纸的代码是:
module ShaderHub;
import std.stdio;
import std.string;
import derelict.opengl3.gl3;
class ShaderHub{
private bool ok=true;
private GLuint shad=0, vshad=0, fshad=0;
private int voff=0;
private GLuint vbo=0, vao=0;
const float[] v = [ 0.75f, 0.75f, 0.0f, 1.0f,
0.75f, -0.75f, 0.0f, 1.0f,
-0.75f, -0.75f, 0.0f, 1.0f];
public this(){
immutable string vshader = `
#version 330
layout(location = 1) in vec4 pos;
void main(void)
{
gl_Position = pos;
}
`;
immutable string fshader = `
#version 330
void main(void)
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`;
shad=glCreateProgram();
if(shad==0){
writeln("Error: GL did not assigh main shader program id");
ok=false;
}
vshad=glCreateShader(GL_VERTEX_SHADER);
const char *vptr=toStringz(vshader);
glShaderSource(vshad, 1, &vptr, null);
glCompileShader(vshad);
int status, len;
glGetShaderiv(vshad, GL_COMPILE_STATUS, &status);
if(status==GL_FALSE){
glGetShaderiv(vshad, GL_INFO_LOG_LENGTH, &len);
char[] error=new char[len];
glGetShaderInfoLog(vshad, len, null, cast(char*)error);
writeln(error);
ok=false;
}
fshad=glCreateShader(GL_FRAGMENT_SHADER);
const char *fptr=toStringz(fshader);
glShaderSource(fshad, 1, &fptr, null);
glCompileShader(fshad);
glGetShaderiv(vshad, GL_COMPILE_STATUS, &status);
if(status==GL_FALSE){
glGetShaderiv(fshad, GL_INFO_LOG_LENGTH, &len);
char[] error=new char[len];
glGetShaderInfoLog(fshad, len, null, cast(char*)error);
writeln(error);
ok=false;
}
glAttachShader(shad, vshad);
glAttachShader(shad, fshad);
glLinkProgram(shad);
glGetShaderiv(shad, GL_LINK_STATUS, &status);
if(status==GL_FALSE){
glGetShaderiv(shad, GL_INFO_LOG_LENGTH, &len);
char[] error=new char[len];
glGetShaderInfoLog(shad, len, null, cast(char*)error);
writeln(error);
ok=false;
}
glGenVertexArrays(1, &vao);
if(vao<1){
writeln("Error: GL failed to assign vao id");
ok=false;
}
glBindVertexArray(vao);
glGenBuffers(1, &vbo);
if(vbo<1){
writeln("Error: GL failed to assign vbo id");
ok=false;
}
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, v.length * GL_FLOAT.sizeof, &v[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, cast(void*)voff);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
public void draw(){
glUseProgram(shad);
writeln(glGetAttribLocation(shad, "pos"));//prints 1
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
glUseProgram(0);
}
}
请注意,调试写入pos'绑定位置正确打印1.设置SDL和GL的代码为:
import std.stdio;
import derelict.sdl2.sdl;
import derelict.opengl3.gl3;
import EventHub;
import ExposeApp;
pragma(lib, "DerelictUtil.lib");
pragma(lib, "DerelictSDL2.lib");
pragma(lib, "DerelictGL3.lib");
class App{
private ExposeApp funcPtrs;
private EventHub ehub;
private SDL_Window *win;
private SDL_GLContext context;
private int w=600, h=480, fov=55;
private bool running=true;
public this(){
if(!initSDL()){
writeln("Error initializing SDL");
SDL_Quit();
}
initGL();
funcPtrs=new ExposeApp();
funcPtrs.stop=&stopLoop;
funcPtrs.grabMouse=&grabMouse;
funcPtrs.releaseMouse=&releaseMouse;
ehub=new EventHub(funcPtrs);
while(running){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
ehub.tick();
SDL_GL_SwapWindow(win);
}
SDL_GL_DeleteContext(context);
SDL_DestroyWindow(win);
SDL_Quit();
}
private void stopLoop(){
running=false;
}
private void grabMouse(){
SDL_ShowCursor(SDL_DISABLE);
SDL_SetWindowGrab(win, SDL_TRUE);
}
private void releaseMouse(){
SDL_ShowCursor(SDL_ENABLE);
SDL_SetWindowGrab(win, SDL_FALSE);
}
private bool initSDL(){
if(SDL_Init(SDL_INIT_VIDEO)< 0){
writefln("Error initializing SDL");
SDL_Quit();
return false;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
win=SDL_CreateWindow("3Doodle", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, w, h, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
if(!win){
writefln("Error creating SDL window");
SDL_Quit();
return false;
}
context=SDL_GL_CreateContext(win);
SDL_GL_SetSwapInterval(1);
DerelictGL3.reload();
return true;
}
private void initGL(){
resize(w, h);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glDepthFunc(GL_LEQUAL);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClearDepth(1.0);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
}
private void resize(int w, int h){
//this will contain the makings of the projection matrix, which we go into next tut
glViewport(0, 0, w, h);
}
}
void main(){
try{
DerelictSDL2.load();
}catch(Exception e){
writeln("Error loading SDL2 lib");
}
try{
DerelictGL3.load();
}catch(Exception e){
writeln("Error loading GL3 lib");
}
App a=new App();
}
如果有人有一些Derelict3 openGL3代码实际上在屏幕上显示某些内容并愿意分享,因为我上下搜索并找不到任何内容。
对大卫的评论:
正如我所说的那样,直到我能在屏幕上看到某些东西,我才会飞得很黑,那么扩展黑暗以涵盖模型加载的重点是什么?我在这里的“BASIC”模板之后;我已经有了一个用于C#工作的模型加载器。您链接的代码是Derelict 1,并且不需要openGL3,从我读到的内容,要求vao(因此包含它们的原因)。但即使没有这个原因,能够在初始化时将vbo绑定到顶点着色器中的属性位置,而不是为每个绘制的vbo使glEnableVertexAttribArray加上glVertexAttribPointer调用是一个函数保存。剔除不是我检查的问题。所以我想我还在等待一个考虑好的答案!
PS。好的,我很抱歉没有点击接听按钮,我没有意识到有这样的事情。我已经回过头来修改过去了。但是你对Dav1d这个问题的回答错过了标记。
答案 0 :(得分:3)
很抱歉,但这段代码让我哭了。
我想这是教程的第一个例子(根据着色器),my D solution with Derelict2(也不是最好的代码)。顺便说一句,你应该禁用调整大小,这在大多数情况下都不起作用,使事情变得更难,特别是初学者。
我建议您不要使用VAO,首先,它们几乎不会带来任何性能提升,使您的应用程序难以维护,并且与DSA approach冲突。
此外,我还建议您使用某种类型的OpenGL API包装器,至少用于加载网格物体(教程使用自己的帮助器,如果你想重新实现它,你需要做很多工作!)。您可以使用我编写的库gljm,这对于.obj格式的网格(它能够加载sponza场景)非常有用,也适用于层格式的非复杂网格。
稍后你还需要一个vector / matrix / quaternion数学库,教程使用glm(你不能真正移植到D,因为它是一个C ++模板库)。 gl3n可能是另一种选择(也是我写的)。
PS:当你提出问题时,请接受答案,不仅仅是因为我是一个声誉妓女,而且也是为了让人们能够立即看到最好的答案(你也应该用旧的问题来解决)。
PS²:也许你的问题只是由启用面部剔除引起的。
答案 1 :(得分:1)
感谢David在DMD网站上的回答。 glBufferData中的&amp; v(GL_ARRAY_BUFFER,v.length * GL_FLOAT.sizeof,&amp; v,GL_STATIC_DRAW);需要更改为&amp; v [0]。
答案 2 :(得分:0)
对于初学者,我不相信你曾经称过你的绘画功能(除非通过ehub.tick()
完成。