Reputation: 1035
I realize that I am not using Glu, nor setting the perspective, but I am using the same normalized device coordinates as McKeeson uses http://www.arcsynthesis.org/gltut/, so I should see the same triangle he gets, only red. I get a black screen and no warnings (I wish they left glDraw functionality for debugging; GL3 is like flying blind until you get out of the smoke!). The code for the drawing is:
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);
}
}
Note that the debug writing pos' binding location correctly prints 1. The code setting up SDL and GL is:
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();
}
If anyone has some Derelict3 openGL3 code that actually displays something on screen and were willing to share, because I have googled up and down and can't find any.
Comment to David:
As I said, until I can get something on screen I am flying dark, so what's the point in extending that darkness to cover model loading? I am after the "BASIC" template here; I already have a model loader for the work in C#. The code you linked to is Derelict 1 and doesn't require openGL3, which from what I read, demands vao (hence the reason for their inclusion). But even without that reason, to be able to bind vbo to attribute locations in the vertex shader at initialization, rather than make the glEnableVertexAttribArray plus the glVertexAttribPointer call for every loop for every vbo drawn is a function saving. Culling isn't the problem I checked. So I guess I am still waiting a considered answer!
PS. OK, I am sorry about not clicking the answered button, I didn't realize there was such a thing. I have gone back through old posts and corrected. But your answer to this question Dav1d misses the mark.
Upvotes: 1
Views: 780
Reputation: 1035
Found the answer thanks to David at DMD site. The &v in glBufferData(GL_ARRAY_BUFFER, v.length * GL_FLOAT.sizeof, &v, GL_STATIC_DRAW); needs to be changed to a &v[0].
Upvotes: 1
Reputation: 6055
Sorry, but this code makes me cry.
I guess this is the first example of the tutorial (according to the shader), my D solution with Derelict2 (also not the best code). Btw, you should disable resizing, this doesn't work most of the time and makes things just harder, especially for a beginner.
I recommend you not to use VAOs, first of all, they bring you nearly no performance boost, make your application harder to maintain and it conflicts with the DSA approach.
Furthermore I also recommend you use some kind of wrapper for the OpenGL API, at least for loading meshes (the Tutorial uses its own helper, if you wanna reimplement it, you have lots of work!). You could use gljm, a library that I wrote, this works pretty well for meshes in the .obj format (it's able to load the sponza scene), also for non-complex meshes in the ply format.
Later on you also need a vector/matrix/quaternion math library, the tutorial uses glm (which you can't really port to D, since it's a C++ template library). gl3n could be an alternative (also written by me).
PS: Please accept answers when you ask questions, not just because I am a reputation-whore, but also so that people can see the best answer immediately (you should also do this with your older questions).
PS²: Maybe your problem is just caused by enabling face-culling.
Upvotes: 3
Reputation: 2077
For starters, I don't believe you ever call your draw function (unless that's done via ehub.tick()
.
Upvotes: 0